您的位置:首页 > 其它

虚函数的“陷阱”

2015-06-08 15:24 393 查看
首先要说明,我不是一个理论派,很少努力的阅读课外书籍,只是用到的时候才去找。因此理论上有缺失,导致对本文出现的“陷阱”认识不足。当然,对于一些专业知识比较强的朋友来说,这不是“陷阱”,只是对我当前的知识水平而言。

先举个例子吧,更好说明情况。假设有两个类,有两个虚函数。

[cpp] view
plaincopy

#if !defined FATHER

#define FATHERclass CFather

{

public:

CFather();

virtual ~CFather();

virtual void Test();

virtual void Hello();

};

#endif

/////////////////////////

#include "stdafx.h"

#include "Father.h"

CFather::CFather()

{

}



CFather::~CFather()

{

}



void CFather::Test()

{

printf("我是老子\r\n");

Hello();

}



void CFather::Hello()

{

printf("老子在HIGH\r\n");

}

/////////////////////////

#if !defined SON

#define SON



#include "Father.h"

class CSon : public CFather

{

public:

CSon();

virtual ~CSon();

virtual void Test();

virtual void Hello();

};

#endif

/////////////////////

#include "stdafx.h"

#include "Son.h"

CSon::CSon()

{

}



CSon::~CSon()

{

}



void CSon::Test()

{

CFather::Test();

}



void CSon::Hello()

{

printf("儿子在HIGH\r\n");

}

/////////////////////

#include "stdafx.h"

#include "son.h"

int main(int argc, char* argv[])

{

CSon son;

son.Test();

return 0;

}



各位看官,请大家想想,son.Test()会输出什么结果呢?

实际的结果是:

我是老子

儿子在HELLO



也就是说,

void CFather::Test()

{

printf("我是老子\r\n");

Hello();

}

中的Hello()不是调用的CFather的Hello,而是CSon的Hello函数。

以前写了那么多代码,还从来没有写过在一个虚函数中调用本类的另一个虚函数......,所以,对这种机制还一直不清楚。

更让人误会的是,在DEBUG状态下,在CFather::Test函数的Hello()行设置断点,使用调试器查看, 其调用的函数是CFather类的函数,而不是CSon类的函数(VS2008实际测试没有出现这个现象)。

经过这个事件,可以发现虚函数也不是乱定义的。有些朋友可能喜欢将函数定义成虚函数,而不考虑是否符合虚函数的机制要求,因此容易产生一些自己不可理解的现象,产生很多的困惑。

对于此类问题,有什么不同看法,还请指正。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: