一道C++多态的题目,考察多态和构造顺序的。求输出结果:#include<iostream>
#include<vector>
classBase
{
public:
Base(){ cout<<"Base::Base()"<<endl; virt(); }
virtualvoidvirt() { cout<<"Base::virt()"<<endl; }
voidfunc(){ cout<<"Base::func()"<<endl; }
};
classDerived :publicBase
{
public:
Derived(){ cout<<"Derived::Derived()"<<endl; virt(); }
virtualvoidvirt() { cout<<"Derived::virt()"<<endl; }
voidfunc() { cout<<"Derived::func()"<<endl; }
};
intmain(){
Derived d;
Base*pb=&d;
pb->func();
pb->virt();
return0;
}
分析:
首先基类和派生类的函数分为两种,一种是虚函数,一种是非虚函数。
关于多态。那么两种函数的区别在于虚函数是动态绑定的,非虚函数是静态绑定的。基类指针pb的静态类型是Base,动态类型是Derived,那么调用静态绑定的函数当然是符合其静态类型。
关于构造顺序。无需多说,当然是先构造基类,然后构造派生类。
至于深层次的原因和虚函数virt()的调用,那需要《深入探索C++对象模型》。。。在基类的构造函数中调用virt(),因为此时派生类的对象还没开始构造呢,所以只有基类对象存在,因此调用virt()函数只能是调用基类的版本。但是当调用了派生类的构造函数之后,派生类的对象就存在了,这个时候再调用虚函数,将得到派生类的版本。
这是因为两条原则:
构造函数的函数体(或构造函数所调用的函数)能可靠地访问基类中声明的数据成员和/或构造函数所属类声明的数据成员。这是因为所有这些数据成员被保证在构造函数函数体开始执行时已经被完整的建立。
在基类的构造函数执行期间,对象还不是一个派生类的对象。
所以输出结果就是:
Base::Base()
Base::virt()
Derived::Derived()
Derived::virt()
Base::func()
Derived::virt()
通过 Wiz 发布
原文链接: https://www.cnblogs.com/microgrape/archive/2011/05/11/2043770.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/25302
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!