虚函数的“陷阱”
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实际测试没有出现这个现象)。
经过这个事件,可以发现虚函数也不是乱定义的。有些朋友可能喜欢将函数定义成虚函数,而不考虑是否符合虚函数的机制要求,因此容易产生一些自己不可理解的现象,产生很多的困惑。
对于此类问题,有什么不同看法,还请指正。
先举个例子吧,更好说明情况。假设有两个类,有两个虚函数。
[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实际测试没有出现这个现象)。
经过这个事件,可以发现虚函数也不是乱定义的。有些朋友可能喜欢将函数定义成虚函数,而不考虑是否符合虚函数的机制要求,因此容易产生一些自己不可理解的现象,产生很多的困惑。
对于此类问题,有什么不同看法,还请指正。
相关文章推荐
- win7文件或文件夹无法删除的解决方案
- struts2使用session 的三种方式
- 32位和64位系统区别及int字节数
- 23、List集合
- spring配置jdbc与hibernate数据源
- Android中如何使用Cursor遍历Sqlite
- YARN Fair Scheduler 配置
- spring security源码分析之core包
- 秦刚:商场小店铺生存艰难怎么办?
- UVA 1590 IP Networks
- Java_获取当前月最后一天
- googletest试用
- Linux
- ListView的相关研究(一)
- Java Project和Web Project
- 预处理指令--宏定义
- spl_autoload_register更改框架文件引用模式
- 构造json串
- I2S音频总线学习(二)I2S总线协议
- django1.7后集成south的使用方法