【问题标题】:C++ dynamic_cast vs storing object type in a static enum?C++ dynamic_cast 与将对象类型存储在静态枚举中?
【发布时间】:2012-04-30 06:40:38
【问题描述】:

我正在为一个框架开发一个很大的类层次结构,当它完成时需要大量的类型转换。

我的问题是,放入一个使用枚举来存储层次结构中所有对象类型的静态成员是多么愚蠢的想法。为每个类设置成员 static 不会增加实例化对象的大小,并且会提供一种(可能)比 dynamic_cast 在运行时更快地确定对象类型的方法。

至少这是基本的想法。这种方法有多合适,是否存在任何潜在缺陷?

【问题讨论】:

  • 存在一个潜在缺陷。这个想法不可能奏效。尝试使用 2 个类的层次结构并查看。
  • 是的,缺陷是要获得正确的静态成员,您必须首先知道对象的类型。
  • 如果你不打算用虚函数访问静态成员,那就是。如果你这样做了,那么这将成为 RTTI 的另一种本土的、低效的、不习惯的、不可维护的、冗余的实现。获取编译器为您提供的一个,它已经存在并且几乎(双关语)是免费的。
  • 需要大量转换的类层次结构是有缺陷的。也许您可以使用双重调度或函数对象来修复您的设计。
  • 为什么需要大量的选角?如果你必须强制转换为一个类型来获得一些功能,那么它不是polymorphic,如果它不是polymorphic,那你为什么要这样建模呢?

标签: c++ object types casting dynamic-cast


【解决方案1】:

这是一个稍微好一点的不同答案。我不想更改 Timo 的答案,所以提交了一个新答案。这背后的基本原理是避免幻数。当目标不是修改原始类时,有时需要对对象进行类型转换和摆弄以添加新功能。但这不应该允许某人使用幻数。

enum mytypeid {
    DERIVED1,
    DERIVED2,
};

struct Base
{
   virtual mytypeid type() = 0;
};

struct Derived1 : public Base
{
   static const mytypeid mytype = DERIVED1;

   virtual mytypeid type() { return mytype ; }
};

struct Derived2 : public Base
{
   static const mytypeid mytype = DERIVED2;

   virtual mytypeid type() { return mytype ; }
};

//...

void fn(Base &a) {
     if(a.type() == Derived1::mytype) {
        std::cout<<"1"<<std::endl;
     }
}

【讨论】:

    【解决方案2】:

    我不知道您将如何从对象之间共享的静态变量中确定每个对象的类型。除非您为每个类都覆盖了一些虚函数,但是您根本不需要静态变量,只需执行以下操作:

    struct Base
    {
       virtual int type() = 0;
    };
    
    struct Derived1 : public Base
    {
       virtual int type() { return 1; }
    };
    
    struct Derived2 : public Base
    {
       virtual int type() { return 2; }
    };
    

    不是最快的解决方案,但比 dynamic_casttypeid 快几个数量级。

    【讨论】:

    • 这完全回答了这个问题,但仍然留下了关于 OP 试图完成什么的问题......
    猜你喜欢
    • 2015-04-26
    • 1970-01-01
    • 1970-01-01
    • 2014-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多