C++ 虚函数在基类与派生类对象间的表现及其分析
来源:互联网 发布:lazada销量数据分析 编辑:程序博客网 时间:2024/05/17 09:01
转载地址:http://www.cnblogs.com/Romi/archive/2013/09/18/3329132.html
近来看了侯捷的《深入浅出MFC》,读到C++重要性质中的虚函数与多态那部分内容时,顿时有了疑惑。因为书中说了这么一句:使用“基类之指针”指向“派生类之对象”,由该指针只能调用基类所定义的函数,如果要让基类的指针使用派生类中定义的函数,就将该函数定义为虚函数。
但在“Object slicing与虚函数”这一小节给出了一个及其经典的例子,它指出,在向上(即向基类)强制转型时,会造成对象内容的被切割。
下面用示例进行说明:
1 #include "stdafx.h" 2 #include <iostream> 3 using namespace std; 4 5 class A 6 { 7 public: 8 virtual void fn(){cout<<"A fn"<<endl;} 9 }; 10 11 class B: public A 12 { 13 public: 14 virtual void fn(){cout<<"B fn"<<endl;} 15 }; 16 17 int main(int argc, char* argv[]) 18 { 19 B b1; 20 A a1=(A)b1; 21 A * a2=(A*)&b1; 22 a1.fn(); 23 a2->fn(); 24 return 0; 25 }
结果如下:
通过调试分析其内存模型如下:
可知,通过A a1=(A)b1传值时,对象中指向虚函数表的指针__vfptr值不同,但是通过A *a2=(A*)&b1传址操作时,对象中指向虚函数表的指针__vfptr值是相同的,调用的是类B对象的虚函数表中虚函数fn()。注意,对象调用的是哪个类的虚函数就要看类对象的虚函数表中的函数是哪一个。这句话也好理解,a1虚函数表中fn()是A::fn(),a2虚函数表中fn()是B::fn(),所以出现以上结果。
在如下包含父类的父类的继承中:
1 class A 2 { 3 public: 4 virtual void fn(){cout<<"A fn"<<endl;} 5 }; 6 7 class B: public A 8 { 9 public:10 virtual void fn(){cout<<"B fn"<<endl;}11 };12 13 class C: public B14 {15 public:16 };17 C c;18 A a1=(A)c;19 A * a2=(A*)&c;20 a1.fn();21 a2->fn();
这时,a1虚函数表中fn()为A::fn(),a2虚函数表中fn()为B::fn(),因为类C对象的虚函数表中fn()为B::fn(),a2中指向虚函数表的指针值与类C对象指向虚函数表的指针值相同。
侯捷的书中有句话是这么对它进行解释的:由于(A)b1.fn()是传值而非传地址操作,编译器以所谓的拷贝构造函数把A对象内容复制了一份,使得b1的虚函数表内容与A对象的虚函数表内容相同。
看来,得多读圣贤书,读懂读透啊!
- C++ 虚函数在基类与派生类对象间的表现及其分析
- 继承与派生:虚基类及其派生类的构造函数
- !!!!!!!!!!!!!!!!C++:派生类中重定义基类的成员函数与虚函数区别在哪里?
- 虚函数在基类与派生类对象的执行过程
- 派生类的构造函数及其对象的初始化
- 四十二、继承与派生:虚基类及其派生类的构造函数
- C#——面向对象——继承——派生类及其构造函数
- 指向派生类对象的基类指针与虚函数
- 虚基类及其派生类的构造函数
- 虚基类及其派生类的构造函数
- 派生类的派生类中(override)的表现
- 【C++继承与派生之二】有子对象的派生类的构造函数
- 抽象类 纯虚函数 虚函数 派生类 派生类对象 基类对象 ——调用顺序,用基类调用派生类的方法
- 派生类对象成员函数与基类成员函数的重载
- C++-继承:基类与派生类对象的关系&&继承与组合
- 基类对象与派生类对象的使用关系
- C++虚函数的陷阱--派生类对象的基类函数调用基类虚函数出错
- 构造函数在派生类与基类浅谈
- opencv学习(7)——图像平滑
- <<沧浪之水>> 读书笔记
- 信号量 PK 自旋锁
- java并发锁-Lock之队列同步器
- 7
- C++ 虚函数在基类与派生类对象间的表现及其分析
- EasyUI学习总结(二)——EasyUI布局
- ubuntu 出现signature canot be verified 错误
- TCP/IP详解学习笔记(2)-数据链路层
- ActiveMQ - Exclusive Consumer 独占消费
- 计蒜客 菜鸟物流的运输网络
- TCP/IP详解学习笔记(3)-IP协议,ARP协议,RARP协议
- mongoVUE 出现“Unable to connect to server 127.0.0.1:27017: 由于目标计算机积极拒绝,无法连接。 127.0.0.1:27017.”
- js设计模式至观察者模式--不同模块间解耦