Динамическое приведение C++ против хранения типа объекта в статическом перечислении?
Я разрабатываю большую иерархию классов для фреймворка, которая потребует довольно много приведения типов, когда это будет сделано.
Мой вопрос в том, насколько глупа идея поместить статический элемент, который использует перечисление для хранения всех типов объектов в иерархии. Наличие статического члена для каждого класса не приведет к увеличению размеров экземпляра объекта и даст (потенциально) более быстрый способ определения типа объекта во время выполнения, чем dynamic_cast.
По крайней мере это основная идея. Насколько адекватным был бы такой подход, и есть ли какие-либо потенциальные недостатки?
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; } }