Вызов виртуальной функции из конструктора - PullRequest
2 голосов
/ 03 февраля 2009

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

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

#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

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

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

Ответы [ 3 ]

18 голосов
/ 03 февраля 2009

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

См. Также этот вопрос StackOverflow .

4 голосов
/ 03 февраля 2009

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

2 голосов
/ 03 февраля 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...