Не может быть удручен, потому что класс не полиморфен? - PullRequest
40 голосов
/ 12 декабря 2011

Возможно ли наследование без виртуальных методов?Компилятор говорит, что следующий код не является полиморфным.

Пример:

Class A(){
    int a;
    int getA(){return a;};
}


Class B(): A(){
    int b;
    int getB(){return b;};
}

В другом классе мы пытаемся выполнить переход от объекта A к объекту B:

 A *a;
 B *b = dynamic_cast<B*>(a)

, но это дает следующую ошибку:

 cannot dynamic_cast ... (source type is polymorphic)

Ответы [ 5 ]

67 голосов
/ 12 декабря 2011

Синтаксические ошибки не выдерживают, вы не можете dynamic_cast неполиморфный тип.static_cast - это приведение, которое вы использовали бы в этом случае, если вы знаете, что на самом деле это объект целевого типа.

Причина, по которой: static_cast обычно компилятор выполняет проверку во время компиляции "Может ли входной сигнал быть приведен к выходному?"Это может быть использовано в случаях, когда вы повышаете или понижаете иерархию наследования указателей (или ссылок).Но проверка выполняется только во время компиляции, и компилятор предполагает, что вы знаете, что делаете.

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

Самый простой случай, и, вероятно, стоит того, если вы передаете указатели подобным образом, стоит рассмотреть возможность создания базового классадеструктор виртуальный.Помимо возможности использования динамического приведения, он также позволяет вызывать надлежащие деструкторы при удалении указателя базового класса.

24 голосов
/ 12 декабря 2011

Для успешного применения оператора dynamic_cast необходим хотя бы один виртуальный метод в классе для run-time type information (RTTI).

13 голосов
/ 28 июня 2013

просто сделайте деструктор виртуальным (всегда используйте для любого класса только для безопасности).

4 голосов
/ 12 декабря 2011

да, dynamic_cast для неполиморфных типов не допускается.Базовый класс должен иметь хотя бы один виртуальный метод.Только тогда этот класс можно назвать полиморфным.

В этой статье описан похожий пример: http://www.cplusplus.com/doc/tutorial/typecasting/

2 голосов
/ 12 декабря 2011
A a;
B *b = dynamic_cast<B*>(a)

Здесь a - объект, а b - указатель.

На самом деле в C ++ разрешены как апкастинг, так и трансляция. Но при использовании downcasting следует обратить внимание на 2 вещи: 1 Суперкласс должен иметь хотя бы один виртуальный метод. 2 Поскольку суперкласс «меньше», чем подкласс, следует осторожно использовать объект памяти.

...