почему виртуальный метод производного класса вызывается после апкастинга?

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

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

2

Решение

Нарезка не произошла, потому что вы не работали с какими-либо значениями BaseПросто указатели на это.

Это может привести к нарезке:

Base base = *der;

Но если вы хотите вызвать функцию и подавить динамическую диспетчеризацию, вы можете просто сделать это:

base->Base::Hello();

Вызываемая функция указывается статически. Это работает с der тоже, конечно, избегая посредника.


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

3

Другие решения

Приведение указателя относится к статической системе типов, которая является безопасной во время компиляции. Например. кастинг говорит компилятору «поверь мне». Это не имеет никакого отношения во время выполнения. Более приятные операции приведения, такие как dynamic_cast, предоставляют некоторые проверки во время выполнения (не делайте этого, если это не имеет смысла), но это по-прежнему не влияет на полиморфизм, это просто более квалифицированное «доверять мне» … доверяйте мне, если я не делаю что-то безумное

Полиморфизм заключается в том, чтобы делать правильные вещи во время выполнения. Когда вы вызываете виртуальный метод через указатель, он будет выполнять правильную операцию для экземпляра объекта.

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

2

По вопросам рекламы [email protected]