南柯一梦50178的分享

来源:互联网 发布:怎样当网络歌手 编辑:程序博客网 时间:2024/05/16 05:43

在孙鑫老师的论坛中有答案,但是对答案有些疑惑,于是注册了一个账号想发表一下问题,可是新注册用户在1440分钟以内不能发言,结果过了一天还是没能提个问题,真是郁闷之极啊!于是先在这里写我的问题。

在第三讲中,孙老师说基类中使用的this指针在派生类生成的对象当中,是指向派生类对象的,可是我按他说的方法去测试一下,结果是指向基类对象,这是为什么?

 


 

class Point
{
public:
 void output()  {cout<<"
调用了基类的output()函数
.";}
 void cjp()  { this->output();}
};

class test:public Point
{
public:
 void output ()  {  cout<<"
调用了派生类的output函数。
"; }
};

void main()
{
 test tt;
 tt.cjp();
}//endof main()

 

按孙老师的意思应该输出:“调用了派生类的output函数”,但是结果是 "调用了基类的output()函数."
说明this指针指向的是基类的对象,这与孙老师的意思相反,

我的问题出在那里?   是我对他的意思理解有误?

 


下面是孙老师在论坛上的回答:

 帖子位置 http://www.sunxin.org/bbs/dispbbs.asp?boardID=2&ID=10641&page=1

  VC视频第三课this指针说明

我在论坛的VC教学视频版面发了帖子,是模拟MFC类库的例子写的,主要是说明在基类的构造函数中保存的this指针是指向子类的,我们在看一下这个例子:

例1- 3

#include <iostream.h>

class base;

base * pbase;

class base

{

public:

       base()

       {

              pbase=this;

              

       }

       virtual void fn()

       {

              cout<<"base"<<endl;

       }

};

class derived:public base

{

       void fn()

       {

              cout<<"derived"<<endl;

       }

};

derived aa;

void main()

{

       pbase->fn();

}

我在base类的构造函数中将this指针保存到pbase全局变量中。在定义全局对象aa,即调用derived aa;时,要调用基类的构造函数,先构造基类的部分,然后是子类的部分,由这两部分拼接出完整的对象aa。这个this指针指向的当然也就是aa对象,那么我们在main()函数中利用pbase调用fn(),因为pbase实际指向的是aa对象,而aa对象内部的虚表指针指向的是自身的虚表,最终调用的当然是derived类中的fn()函数。

在这个例子中,由于我的疏忽,在derived类中声明fn()函数时,忘了加public关键字,导致声明为了private(默认为private),但通过前面我们所讲述的虚函数调用机制,我们也就明白了这个地方并不影响它输出正确的结果。不知道这算不算C++的一个Bug,因为虚函数的调用是在运行时确定调用哪一个函数,所以编译器在编译时,并不知道pbase指向的是aa对象,所以导致这个奇怪现象的发生。如果你直接用aa对象去调用,由于对象类型是确定的(注意aa是对象变量,不是指针变量),编译器往往会采用早期绑定,在编译时确定调用的函数,于是就会发现fn()是私有的,不能直接调用。:)

许多学员在写这个例子时,直接在基类的构造函数中调用虚函数,前面已经说了,在调用基类的构造函数时,编译器只“看到了”父类,并不知道后面是否后还有继承者,它只是初始化父类对象的虚表指针,让该虚表指针指向父类的虚表,所以你看到结果当然不正确。只有在子类的构造函数调用完毕后,整个虚表才构建完毕,此时才能真正应用C++的多态性。换句话说,我们不要在构造函数中去调用虚函数,当然如果你只是想调用本类的函数,也无所谓。

 


 我的问题:

  如果说this指针指向派生类的对象,那么是不是意味着基类里使用的this指针与派生类里使用的this指针完全等同?

 但事实上,要使基类里的this指针调用到派生类的fn()函数,基类中的fn()函数必须是虚函数,否则会像我的试验中一样,调用到基类的fn()函数。在我的试验中,如果把基类Point中的output声明为虚函数,那么cjp()调用的结果会是我们想要的结果:即调用派生类的output()函数。

如果基类里使用的this指针与派生类里使用的this指针不是一回事,那么孙老师为什么要提出“说基类中使用的this指针在派生类生成的对象当中”?意义何在?

 

 

原创粉丝点击