После перемещения указателя в производном классе виртуальный метод производного класса по-прежнему вызывается, что мне кажется неправильным, так как срезы должны были произойти.
Не могли бы вы прокомментировать, что не так с этим кодом?
class Base
{
public:
virtual void Hello() { cout << "Hello Base" << endl; }
};
class Derived: public Base
{
public:
void Hello() { cout << "Hello Derived" << endl; }
};
int main()
{
Derived* der = new Derived;
Base* base = dynamic_cast<Base*> (der);
if (base) base->Hello();
}
вывод: Hello Derived
Нарезка не произошла, потому что вы не работали с какими-либо значениями Base
Просто указатели на это.
Это может привести к нарезке:
Base base = *der;
Но если вы хотите вызвать функцию и подавить динамическую диспетчеризацию, вы можете просто сделать это:
base->Base::Hello();
Вызываемая функция указывается статически. Это работает с der
тоже, конечно, избегая посредника.
Ваш dynamic_cast
здесь не нужно Вы можете неявно выгружать, потому что это легко проверить во время компиляции. Ты можешь использовать static_cast
опускать руки вниз, но это зависит от вас, чтобы убедиться, что это действительно правильно; dynamic_cast
это просто проверенная версия этого.
Приведение указателя относится к статической системе типов, которая является безопасной во время компиляции. Например. кастинг говорит компилятору «поверь мне». Это не имеет никакого отношения во время выполнения. Более приятные операции приведения, такие как dynamic_cast, предоставляют некоторые проверки во время выполнения (не делайте этого, если это не имеет смысла), но это по-прежнему не влияет на полиморфизм, это просто более квалифицированное «доверять мне» … доверяйте мне, если я не делаю что-то безумное
Полиморфизм заключается в том, чтобы делать правильные вещи во время выполнения. Когда вы вызываете виртуальный метод через указатель, он будет выполнять правильную операцию для экземпляра объекта.
В C ++ вы можете запросить конкретное разрешение, используя оператор ::, но это обычно зарезервировано для деталей реализации.