【问题标题】:Comparing types in C++比较 C++ 中的类型
【发布时间】:2023-03-26 13:22:01
【问题描述】:

我正在开发一个自定义引擎,其中有 2 个不同的变换类,一个用于 2D,一个用于 3D。我正在使用#define 来选择要使用的转换类,并在逻辑应该相同的地方使用该定义而不是类名。我现在正处于一个我希望他们有不同逻辑的部分,并想做一个比较以为此分支。 我需要做什么才能让它工作?

class Transform2D;
class Transform3D;

#define TransformClass Transform2D

if(TransformClass == Transform2D)
{
  //like this
}
else    
{
  //like that
}

类型 id 可以做到这一点。你是怎么处理的?

if ( typeid(TransformClass) == typeid(Transform2D) )
{
    ittransform->SetRotation(0);
    ittransform->SetScale(Vector2D(defaultScale, defaultScale));
}
else
{
    ittransform->SetRotation(Vector3f());
    ittransform->SetScale(Vector3f(defaultScale, defaultScale, defaultScale));
}

【问题讨论】:

  • 这种类型检查通常表明架构/类设计不佳。要么使用重载函数,比如 Sean 建议的,要么定义一个由 transform2D 或 transform3D 实现的顶级接口类
  • 而不是 #define 只是让你的函数成为一个模板,使用 Sean 建议的通用接口对 Transform2D/3D 类进行操作。

标签: c++ architecture component-based


【解决方案1】:

使用函数分解(将您的逻辑分解为子函数),然后使用重载。

void do_something(Transform2D const& t) {
  ...
}

void do_something(Transform3D const& t) {
  ...
}

void test() {
  TransformClass tc = ...
  do_something(tc); // invokes the desired overload
}

另外,使用 typedef 或类型别名代替定义,例如

#if defined(USE_3D)
using TransformClass = Transform3D;
#else
using TransformClass = Transform2D;
#endif

您还可以通过 std::conditional 定义别名,并且更加功能化-y 和 C++-y。

【讨论】:

  • using TransformClass = Transform2D; 是否与#define 做同样的事情,还是有更多/不同的行为。`
  • @ColinAvrech:它有稍微不同的行为。也就是说,如果你命名一个变量TransformClass,它实际上是TransformClass,而不是Transform3D。其他一些差异。
  • 该用途的行话/术语是什么?
  • 它是一个“类型别名”,类似于 typedef,但使用语法更易于阅读且功能更强大(它允许使用参数化别名,即别名模板)。基本上,只需在您之前使用过 typedef 的地方使用它(我认为它是一个完整的替代品,但也许有一个我不知道的极端情况)。
【解决方案2】:

在这种情况下不要使用 if()。

由于您正在使用预处理器进行编码,请坚持使用它:

# if USING_3D
    3d code
# else
    2d code
# endif

如果您努力使大多数方法和辅助类看起来大致相同,您可能会设法避免过多使用#if

旧的 C 代码中充斥着这些东西,这被认为是好的。然而,如今,它已经非常老式了。在继续这条路之前,请三思而后行。

【讨论】:

    【解决方案3】:

    我认为最简单的选择是创建一个额外的定义,如下所示:

    #define USING_CLASS_2D 1
    
    #if USING_CLASS_2D
    #define TransformClass Transform2D
    #else
    #define TransformClass Transform3D
    #endif
    
    if (USING_CLASS_2D)
    {
    }
    else
    {
    }
    

    【讨论】:

    • 如果采用这种方式,那为什么还要使用if()逻辑呢?在这种情况下,正确的应该是预处理器#if#ifdef
    • 为什么要在typedef上这样做?
    • 我使用了#defineif,因为这就是问题中使用的内容。您可以改用 typedef。
    猜你喜欢
    • 2012-09-14
    • 1970-01-01
    • 1970-01-01
    • 2015-02-10
    • 2020-01-06
    • 2014-08-19
    • 1970-01-01
    • 1970-01-01
    • 2019-09-28
    相关资源
    最近更新 更多