继承与虚函数

昨天我看孙鑫的视频第三课(MFC的来龙去脉),在孙鑫讲到CWinApp的构造函数时,函数内部有个pThreadState->m_pCurrentWinThread= this;  孙鑫强调这里的this是指的子类的对象的指针,还叫我们下来自己做个测试程序。      然后我自己做了个测试程序:

#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
class people
{
public:
           people()
           {
                  r=this;
            }
            void pprint()
            {
                   cout<<"people"<<endl;
             }
              people *r;
};
class police:public people
{
public:
             police()
             {
              }
             void pprint()
             {
                    cout<<"police"<<endl;
             }
};


police man;


int _tmain(int argc, _TCHAR* argv[])
{
          man.r->pprint();
          people *p=new police();
          p->pprint();
          people pp;
          pp.pprint();
          return 0;
}

这个程序按理说我觉得应该是显示为:

police
police
people
但是显示结果却是
people
people
people
我就很纳闷了,这到底是什么原因?后来我在people类当中的pprint函数加上了一个virtual,这样一来结果就成第一种结果了!我就在想为什么不加virtual的时候他会都显示people呢,我开先认为是man.r没有指向police对象的指针,后来单步调试的时候发现,man.r的确指向的是一个police对象的指针,那到底又是为什么一个指向police对象的指针调用pprint函数的时候会是调用基类的pprint呢?    我后来上csdn问了这个问题,但是社友们回答的和我想问的完全占不上边,可能是我的表达有误吧! 今天我又通过个调试,我觉得这个问题应该是这样的:

首先说明一点,类当中所有的非静态函数都有一个隐含的形参  那就是 const 类名* this(我这里是const people* this和const police* this),这就不难理解上面那两个类的构造函数了。

people(const people* this)
{
        r=this;
}

police(const police* this)
{
}
大家应该知道一个基类的指针允许传递一个派生类对象的指针给它。所有当我们构造police man的时候(const police* this=&man),要先调用基类的构造函数(派生类把当前对象的指针传给基类做隐含形参,即const people* this=&man),所以man.r的确是指向的一个police对象的指针。那为什么man.r->pprint()调用会显示为people呢?我认为应该是由于r是一个people类型的指针,虽然它指向的是一个police对象,但是本身是people对象指针,当调用pprint()的时候他会在当前类(people类)中查找这个函数,当找不到时程序会报错(pprint()不是people的函数)。当找到时,由于r是一个指向police对象的指针,系统会查看它是否是虚函数,不是虚函数的话,系统将直接调用这个函数;如果是虚函数的话,系统会查找police类是否有这个函数,police类如果有这个函数,系统将直接调用police类的函数;police类没有这个函数的话,系统将调用基类people的函数pprint()。这样就能解释了在基类中加上virtual和不加virtual的第一个数据的显示结果!后面两个结果的道理完全和第一个的一样。

我如果说的有错的地方,还请大虾们帮忙指正!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值