说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

请教:构造函数为啥不能是虚函数?

编辑:说三道四文库 发布时间:2018-02-24 10:14
HTML文档下载 WORD文档下载 PDF文档下载
因为构造派生类对象时,会自动调用基类构造函数。而当执行基类构造函数时(即基类对象被构造时),派生类对象还不存在,而如果基类构造函数如果是虚函数,就会调用派生类构造函数,如果派生类构造函数访问了派生类特有的数据(即基类中没有的数据)时,会造成灾难!
同样道理,即使基类的构造函数调用了虚函数,该虚函数也不会执行派生类的代码,而是执行基类中该函数代码。

见 http://localhost/asp/sunidoc.asp?act=-2&article=224 中的一段

[23.1] 当基类构造函数调用虚函数时,为什么不调用派生类重写的该虚函数? 
当基类被构造时,对象还不是一个派生类的对象,所以如果 Base::Base() 调用了虚函数 
virt(),则 Base::virt() 将被调用,即使 Derived::virt() (译注:即派生类重写的虚 
函数)存在。 

同样,当基类被析构时,对象已经不再是一个派生类对象了,所以如果 Base::~Base() 
调用了 virt(),则 Base::virt() 得到控制权,而不是重写的 Derived::virt()。 

当你可以想象到如果 Derived::virt() 涉及到派生类的某个成员对象将造成的灾难的时候, 
你很快就能看到这种方法的明智。详细来说,如果 Base::Base() 调用了虚函数 virt(), 
这个规则使得 Base::virt()被调用。如果不按照这个规则,Derived::virt()将在派生对象 
的派生部分被构造之前被调用,此时属于派生对象的派生部分的某个成员对象还没有被构造, 
而 Derived::virt() 却能够访问它。这将是灾难。
VPTR 的状态是由被最后调用的构造函数确定的!
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘