Подтвердить что ты не робот

Проверка типов в С++

В С++ я хочу знать, является ли фактический тип объекта одним и тем же классом, а не тем же классом или производным. Это похоже на следующий код С#:

Class Base
{
}

Class Child:Base
{
}

Base childObject = new Child();

If (childObject.GetType() == typeof(Child))
{
 // do some code
}

Спасибо!

4b9b3361

Ответ 1

Есть два способа сделать это. Во-первых, вы можете использовать оператор typeid, который возвращает структуру type_info, содержащую информацию о типе объекта. Например:

Base* ptr = /* ... */
if (typeid(*ptr) == typeid(DerivedType)) {
    /* ... ptr points to a DerivedType ... */
}

Обратите внимание, что здесь вы должны использовать typeid(*ptr), а не typeid(ptr). Если вы используете typeid(ptr), вы вернете объект type_info для Base*, так как указатель имеет тип Base*, независимо от того, на что он указывает.

Важно отметить, что это будет проверять, что точка ptr находится точно так же, как DerivedType. Если ptr указывает на объект типа, полученного из DerivedType (возможно, EvenMoreDerivedType), этот код будет работать некорректно.

Альтернативный способ проверки того, указываете ли вы на объект некоторого типа, который является более надежным, заключается в использовании оператора dynamic_cast. dynamic_cast выполняет проверенный тип при выполнении во время выполнения, который даст допустимый указатель, если листинг преуспеет и NULL в противном случае. Например:

Base* ptr = /* ... */;
DerivedType* derived = dynamic_cast<DerivedType*>(ptr);
if (derived) {
    /* ... points to a DerivedType ... */
}

Это имеет дополнительное преимущество: если ptr указывает на что-то вроде EvenMoreDerivedType, приведение будет по-прежнему успешным, потому что EvenMoreDerivedType наследует от DerivedType.

В качестве последней мысли вы иногда видите такой код:

Base* ptr = /* ... */
if (DerivedType* derived = dynamic_cast<DerivedType*>(ptr)) {
     /* ... points to a DerivedType ... */
}

Это локально - привязывает указатель derived к телу оператора if и использует тот факт, что ненулевые значения оцениваются на true в С++. Я лично считаю, что это легче читать и меньше подвергать ошибкам, но, во что бы то ни стало, идет с тем, что вам просто легче.

Надеюсь, это поможет!

Ответ 2

В то время как ответ DeadMG правильный (я много раз использовал typeid), я думал, что выброшу его там для потомков. "Правильный" способ сделать это из объектно-ориентированного представления:

Class Base
{
    virtual void something() {
        // probably a no-op, but maybe some default stuff
    }
}

Class Child : public Base
{
    virtual void something() {
        // do your child-specific code here
    }
}

Base* childObject = new Child();
childObject->something();  // does the right thing

Ответ 3

Вы можете использовать typeid().

if (typeid(childObject) == typeid(ChildType)) {
}

Если это возвращает true, то вы знаете его дочерний класс.