Динамическое приведение C++ против хранения типа объекта в статическом перечислении?


Я разрабатываю большую иерархию классов для фреймворка, которая потребует довольно много приведения типов, когда это будет сделано.

Мой вопрос в том, насколько глупа идея поместить статический элемент, который использует перечисление для хранения всех типов объектов в иерархии. Наличие статического члена для каждого класса не приведет к увеличению размеров экземпляра объекта и даст (потенциально) более быстрый способ определения типа объекта во время выполнения, чем dynamic_cast.

По крайней мере это основная идея. Насколько адекватным был бы такой подход, и есть ли какие-либо потенциальные недостатки?

2 2

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_cast или typeid.

Вот несколько лучший и отличный ответ. Я не хотел менять ответ Тимо, поэтому представил новый. Логическое обоснование этого-избегать магических чисел. Иногда для добавления новых функциональных возможностей требуется типизация и манипулирование объектами, когда цель не заключается в изменении исходных классов. Но это не должно позволить кому-то использовать магические числа.

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;
     }
}