非多态情况 (动态)
来源:互联网 发布:java程序员壁纸 编辑:程序博客网 时间:2024/05/28 23:11
一. 非多态分类:
C++Primer 第三版中文版Page752有如下记载:
“当成员函数是虚拟的时候,通过一个类对象(指针或引用)而被调用的该成员函数,是在该类对象的动态类型中被定义的成员函数。”
这句话有两个元素至关重要,
a.虚成员函数
b.类对象的指针或引用
而此两点有无的组合和有四种情况:
只有a,b同时符合才能实现动态联编(((Father*)lpFson)->DisplayV()结果参考),
而其他三种情况均不符合,编译器在编译期间将确定调用函数。
编译器也是根据此两点来确定到底是否动态联编。
下面对其他三种情况非动态联编进行说明举例。
1)子类覆盖父类函数时,指向子类对象的指针强制转换成指向父类的指针,然后调用此覆盖函数时,不进行动态动态绑定。也就是调用的是父类的函数,而非子类的函数((Father*)lpFson)->Display();结果参考)。【a不符】
2)子类覆盖父类函数时,子类对象强制转换成父类,然后调用此覆盖函数时,不进行动态动态绑定。也就是调用的是父类的函数,而非子类的函数(((Father)son).DisplayV();结果参考)。【b不符】
3)子类隐藏父类函数时,子类对象强制转换成父类,然后调用此隐藏函数时,不进行动态动态绑定。也就是调用的是父类的函数,而非子类的函数(((Father)son).Display();结果参考)。【a,b都不符】
代码验证:
class Father
{
public:
Father(int i)
{
var1 = i;
}
public:
~Father(void){};
void Display()
{
TRACE("Father::Display var1 = %d/n",var1);
}
virtual void DisplayV()
{
TRACE("Father::DisplayV var1 = %d/n",var1);
}
private:
int var1;
};
//class Son
class Son : public Father
{
public:
Son(int i,int j):Father( i)
{
var2 = j;
}
public:
~Son(void){};
void Display()
{
TRACE("Son::Display var2 = %d/n",var2);
}
virtual void DisplayV()
{
TRACE("Son::DisplayV var2 = %d/n",var2);
}
private:
int var2;
int var3;
};
//调用呼出函数
void CTianTestDlg::OnBnClickedCancel2()
{
Son son(1,2);
son.Display();
son.DisplayV();
((Father)son).Display(); //输出:Father::Display var1 = 1
((Father)son).DisplayV(); //输出:Father::DisplayV var1 = 1
//指针运行情况
TRACE("----------------------------------/n");
Son *lpFson = &son;
lpFson->Display();
lpFson->DisplayV();
((Father*)lpFson)->Display();//输出:Father::Display var1 = 1
((Father*)lpFson)->DisplayV();//输出:Son::Display var1 = 1
}
二. 非多态及多态实现
1.简单理解上
编译器根据元素a和b很容易判断出来是静态编译,然后根据此时调用函数的定义类型就可以决定调用哪个函数,(进行过强制转换,就是转换后的的类的函数,未转换过的话,就是定义时候的类型)
而如果是动态编译,将根据指向的实在对象里记录的虚拟表指针,在动态运行时查虚拟表确定函数。
2.从编译器生成的汇编代码的验证:
请参考:
浅析C++中虚函数的调用及对象的内部布局
http://blog.csdn.net/starlee/archive/2008/02/13/2089358.aspx
里面有详细的汇编代码说明
<注>作为例外,类的构造函数在符合a,b条件时不进行动态联编,因为这个时候子类的对象还没有创建好,无法实现动态联编。
- 非多态情况 (动态)
- 动态sql使用情况
- 非多态情况
- SQL 动态排序的部分情况实现
- strace 查看加载动态库的情况
- 根据页面情况动态加载JS
- linux指令-动态查看系统资源情况
- 情况三:编译动态库+静态库
- Oracle之一键获取总体情况 动态
- 动态调用Dll(未注册的情况下)
- 在不刷新的情况下动态添加表格行
- C# 中的Winform 动态显示当前数据循环情况
- __declspec(thread)不支持使用LoadLibrary动态加载的情况
- 根据不同情况使用静态页和动态页
- 在不破坏背景的情况下实现动态文字
- solaris系统动态查看swap的使用情况
- 根据不同的情况动态改变menu菜单项
- 无OS情况下,8051如何实现动态内存分配
- ReaderWriterLock要点
- Windows编程中的映射模式和坐标转换
- 欢迎使用CSDN论坛阅读器 : CSDN Reader(附全部源代码) 最新版本:20090608
- Scoping.py源代码分析
- BoundsChecker 内存泄露 检测 简易使用教程
- 非多态情况 (动态)
- 淘宝 TOP 平台Open API入门篇
- 读《拒绝形式化的软件工程文档》
- 色环电阻和电感区别
- ReaderWriterLock要点
- 输入框函数POPUP_GET_VALUES
- UML用例图,类图,顺序图
- 让开发自动化: 文档化一键通
- 前端开发大众手册(包括工具、网址、经验等)