关闭

C++与C#关于虚函数调用的一点比较

1470人阅读 评论(0) 收藏 举报

在C++FAQ上看到一个关于虚函数的重载说明,原贴内容如下:

[23.3] 当基类构造函数调用虚函数时,为什么不调用派生类重写的该虚函数?

当基类被构造时,对象还不是一个派生类的对象,所以如果 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()却能够访问它。这将是灾难。

意思是说在C++中,如果基类的构造函数中调用它定义的的虚函数,即使在派生类中对这个虚函数进行了重写,实际运行中调用的仍是基类的版本。具体原因可以参见上面的说明,大概意思是在基类的构造函数中,子类对象还未被构造出来,所以这个时候调用的仍是基类的。

但是在C#中,同样的情况,基类中调用的却是派生类重写后的版本。我在本机是试过,运行结果是这样的,但是不是太明白为什么。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:4232次
    • 积分:61
    • 等级:
    • 排名:千里之外
    • 原创:3篇
    • 转载:1篇
    • 译文:0篇
    • 评论:0条
    文章分类
    文章存档