2009-02-03 6 views
2

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

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

#include <iostream> 

class Base 
{ 
public: 
    Base() { print(); } 
    ~Base() {} 

protected: 
    virtual void print() { std::cout << "base\n"; } 
}; 

class Child : public Base 
{ 
public: 
    Child() {} 
    ~Child() {} 

protected: 
    virtual void print() { std::cout << "child\n"; } 
}; 

int main() 
{ 
    Base b; 
    Child c; 
} 

Это печатает:

base 
base 

Когда экземпляр Ребенка создается, почему Base :: печать() называется? Я думал, что с помощью виртуального ключевого слова функция может быть заменена на производный класс.

В какой момент я смутился?

+0

Возможный дубликат [виртуальная функция C++ от конструктора] (http://stackoverflow.com/questions/496440/c-virtual-function-from-constructor) – Mark

ответ

18

Вы вызываете виртуальный метод в конструкторе, который не будет работать, поскольку дочерний класс еще не полностью инициализирован.

См. Также this StackOverflow question.

+0

К сожалению, тот же самый вопрос, странный, что никто не появился в моих поисках. Не стесняйтесь закрыть этот вопрос, если кто захочет. – Mizipzor

2

Для получения подробного объяснения см. this link (для того, чтобы не вызывать виртуальные функции из ctor/dtor).

+1

Просто просмотренную статью, хотя она имеет очень действительные точки, как указано в связанном вопросе, нет ничего «C++ invalid» о вызове виртуальных функций в ctor. Вы просто должны быть уверены в том, что получаете. Хотя я допускаю, что такая практика может породить путаницу. – Mizipzor

4

Хотя ваша текущая проблема - вызов виртуального метода от конструктора, о котором говорили другие, я заметил, что вы не сделали деструкторов виртуальными. Обычно это плохо. В вашем случае деструкторы являются nops, и нет элементов, которые являются объектами с деструкторами, но если ваш код меняется, легко бывает плохо.

+0

Да, я часто получаю эту проблему, забывая сделать виртуальный деструктор. Спасибо за хедз-ап, но я знаю о потенциальных проблемах. – Mizipzor

+0

Mr Fooz: +1 для напоминания –