В C++, когда виртуальная функция вызывается из конструктора, она не ведет себя как виртуальная функция. Я думаю, что все, кто столкнулся в первый раз, были удивлены, но, с другой стороны, это имеет смысл, если производный конструктор еще не запущен, объект не, а , полученный, и как можно вызывать производную функцию? Предварительные условия не имели возможности быть настроенными. Пример:Виртуальные функции в конструкторах, почему языки отличаются?
class base {
public:
base()
{
std::cout << "foo is " << foo() << std::endl;
}
virtual int foo() { return 42; }
};
class derived : public base {
int* ptr_;
public:
derived(int i) : ptr_(new int(i*i)) { }
// The following cannot be called before derived::derived due to how C++ behaves,
// if it was possible... Kaboom!
virtual int foo() { return *ptr_; }
};
Это точно то же самое для Java и .NET пока они решили пойти другим путем, было единственной причиной, принцип наименьшего удивления?
Какой, по вашему мнению, правильный выбор?
Как это больше подходит для компилятора? Он просто сводится к установке vptr после вызова конструктора базового класса. Я бы сказал, что другие семантики сложнее реализовать, так как вам нужно убедиться, что после установки vptr в конструкторе производного класса он не должен быть переоценен конструкторами базовых классов. (Предполагается, что динамическая диспетчеризация обрабатывается с помощью указателей на таблицы виртуальных методов, что является наиболее распространенным подходом.) – 2012-05-25 16:17:20