南柯一梦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指针在派生类生成的对象当中”?意义何在?
- 南柯一梦50178的分享
- 毕业生自传(南柯一梦)
- 购物分享--享受购物分享的乐趣
- JS 百度分享 自定义分享的地址
- 数据的浅分享和深分享
- 百度分享--分享按钮的实现
- 敏捷分享 -- 分享会的准备 1
- 敏捷分享 -- 分享会的准备 2
- 分享一款值得分享的写作工具
- 微信分享的相关技术分享
- 源于百度分享的“一键分享”
- 分享Ebook的网站
- 分享全球化的益处
- 分享他们的智慧
- 我的作品分享
- 谢谢您的分享。。。。
- 分享的快乐
- 软件工程师的经验分享
- VC6.0使用技巧
- createThread函数的使用
- RedHat / CentOS Install and Configure Cacti Network Graphing Tool
- linux监控命令和工具
- UVA 102
- 南柯一梦50178的分享
- 基于v4l2的webcam应用, 本地预监
- 用树状数组解决区间查询问题
- MySQL内存池结构源码 my_alloc.h
- HTTP幂等性概念和应用
- 一段代码的反汇编
- 修改SGA参数,导致oracle崩溃
- 很多事情不是因为困难而不去做,而往往是因为不去做才显得困难
- C语言类型转换