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

Невозможно понизить, потому что класс не является полиморфным?

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

Пример:

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)
4b9b3361

Ответ 1

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

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

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

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

Ответ 2

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

Ответ 3

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

Ответ 4

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

В этой статье объясняется аналогичный пример: http://www.cplusplus.com/doc/tutorial/typecasting/

Ответ 5

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

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

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