先上代码:
// c_datastructure.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<iostream>
#include<string>
using namespace std;
class Base {
public:
Base() {
fun();
}
virtual void fun() { cout << "Base" << endl; }
};
class A :public Base {
public:
A() :Base(), a(a) {}
virtual void fun() { cout << "A" << endl; }
private:
int a;
};
int main()
{
cout << "************" << endl;
Base *a = new A;
delete a;
return 0;
}
此时发挥作用的是Base:fun()而不是派生类A:fun(),也就是虚函数在构造函数中不起作用。 当实例化一个派生类对象时,首先进行基类部分的构造,然后再进行派生类部分的构造。即创建A对象时,会先调用Base的构造函数,再调用A的构造函数。 当在构造基类部分时,派生类还没被完全创建,从某种意义上讲此时它只是个基类对象。即当Base::fun()执行时A对象还没被完全创建,此时它被当成一个Base对象,而不是A对象,因此fun绑定的是Base的fun
C++之所以这样设计是为了减少错误和Bug的出现。假设在构造函数中虚函数仍然“生效”,即Base::fun()中的fun();所调用的是A::fun()。当Base::fun()被调用时派生类中的数据a还未被正确初始化,这时执行A::fun()将导致程序对一个未初始化的地址解引用,得到的结果是不可预料的,甚至是程序崩溃(访问非法内存)。