2012-04-18 2 views
2

Я разрабатываю большую иерархию классов для фреймворка, которая потребует довольно много типоразмеров, когда это будет сделано.C++ dynamic_cast vs сохранение типа объекта в статическом enum?

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

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

+0

Существует один потенциальный недостаток. Эта идея не может работать. Попробуйте его с иерархией из 2 классов и посмотрите. –

+0

Да, недостаток в том, что для получения правильного статического члена вы должны сначала знать тип объекта. –

+0

Если вы не планируете получать доступ к статическому члену с помощью виртуальной функции, то есть. Если вы это сделаете, то это станет просто еще одной самодельной, неэффективной, неидиоматичной, недостижимой, избыточной реализацией RTTI. Получите тот, который дает вам компилятор, он уже существует, и он фактически (каламбур) свободен. –

ответ

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.

+0

Это точно отвечает на вопрос, но все же оставляет вопрос о том, что пытается сделать OP ... – Chad

0

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

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; 
    } 
} 
Смежные вопросы