C++中的对象模型
来源:互联网 发布:mac不能同时登陆2个qq 编辑:程序博客网 时间:2024/06/03 22:58
所谓多态,即“多种形态“。
C++中虚函数的主要作用就是实现多态,每一个具有虚函数的类都叫做多态类。这个虚函数或者是从基类继承来的,或者是自己新增的。C++编译器为每一个多态类至少创
建一个虚函数表(vtable),他其实就是一个函数指针数组,其中存放着这个类所有的虚函数的地址及该类的类型信息,其中也包括那些继承但未改写的虚函数。简单地说父类
的指针/引用调用重写的虚函数,当父类指针/引用指向父类对象时调用的是父类的函数,指向子类对象时调用的是子类的函数。
【以下测试均在windows7 32位vs2008环境下的测试】
1、探索虚函数表
虚函数表是通过一块连续内存来存储虚函数的地址。这张表解决了继承、虚函数(重写)的问题。在虚函数的对象实例中都存在一张虚函数表、虚函数表就像一张地图、指
明了实际应该调用的虚函数。
#include<iostream>
using namespace std;
class Base
{
public:
virtual void func1()
{ }
virtual void func2()
{ }
private:
int a;
};
void Test1()
{
Base b1;
}
int main()
{
Test1();
return 0;
}
【虚函数表】
2、探索单继承对象模型
class Base
{
public:
virtual void func1()
{
cout<<"Base::func1"<<endl;
}
virtual void func2()
{
cout<<"Base::func2"<<endl;
}
private:
int a;
};
class Derive:public Base
{
public:
virtual void func1()
{
cout<<"Derve::func1"<<endl;
}
virtual void func3()
{
cout<<"Derve::func3"<<endl;
}
virtual void func4()
{
cout<<"Derve::func4"<<endl;
}
private:
int b;
};
typedef void(*FUNC)();
void PrintVTable(int *VTable)
{
cout<<"虚表地址->"<<VTable<<endl;
for(int i=0;VTable[i]!=0;++i)
{
printf("第%d个虚函数地址:0X%x,->",i,VTable[i]);
FUNC f=(FUNC) VTable[i];
f();
}
cout<<endl;
}
void Test1()
{
Base b1;
Derive d1;
int* VTable1=(int*)(*(int*)&b1);
int* VTable2=(int*)(*(int*)&d1);
PrintVTable(VTable1);
PrintVTable(VTable2);
}
VS2008监视窗口中的虚表
可以看到派生类Derive::func1重写基类Base::func1,覆盖了相应虚表位置上的函数。(可以看到这里没有看到派生类Derive中的func3和func4,这个函数就放在func2的后面,这
里没有显示是vs的问题(bug))。
【单继承对象模型】
3、探索多重继承的内存分布
class Base1
{
public:
virtual void func1()
{
cout<<"Base1::func1"<<endl;
}
virtual void func2()
{
cout<<"Base1::func2"<<endl;
}
private:
int b1;
};
class Base2
{
public:
virtual void func1()
{
cout<<"Base2::func1"<<endl;
}
virtual void func2()
{
cout<<"Base2::func2"<<endl;
}
private:
int b2;
};
class Derive:public Base1,public Base2
{
public:
virtual void fun1()
{
cout<<"Derive::func1"<<endl;
}
virtual void fun3()
{
cout<<"Derive::func3"<<endl;
}
private:
int d1;
};
typedef void(*FUNC)();
void PrintVTable(int *VTable)
{
cout<<"虚表地址->"<<VTable<<endl;
for(int i=0;VTable[i]!=0;++i)
{
printf("第%d个虚函数地址:0X%x,->",i,VTable[i]);
FUNC f=(FUNC) VTable[i];
f();
}
cout<<endl;
}
void Test1()
{
Derive d1;
int* VTable=(int*)(*(int*)&d1);
PrintVTable(VTable);
VTable=(int*)(*((int*)&d1+sizeof(Base1)/4));
PrintVTable(VTable);
}
【多重继承对象模型】
4、多态
多态即多种形态,C++的多态分为静态多态和动态多态。
(1)静态多态就是重载,因为是在编译期决议确定,所以称为静态多态。
(2)动态多态就是通过继承重写基类的虚函数实现的多态,因为是在运行时决议确定、所以称为动态多态。
- 【C++】浅析C++中的对象模型
- 【C++】浅析C++中的对象模型
- 【C++】虚函数在不同继承方式中的对象模型
- javascript中的对象模型
- 继承中的对象模型
- 继承中的对象模型
- C++中的对象模型
- Objective-C对象模型
- Objective-C对象模型
- objective C 对象模型
- C ++ 对象模型
- Objective-C 对象模型
- 【C++】对象模型
- Objective-C对象模型
- 对象模型中的常见对象
- VB6中的FSO对象模型
- ATL中的创建对象模型
- C++ 继承中的对象模型
- html的src引用七牛的连接,页面加载出现403
- 2017年要学习的三个CSS新特性
- “extern ”和 “static ” 遇上了,就提一點!
- MySql表结构修改详解
- XCAT的安装与简单使用
- C++中的对象模型
- Retrofit缓存
- Linux cp -a用法
- DBA常用的MySQL语句
- 百度地图:定位,轨迹,白板,加载崩溃,定位到非洲
- 各个浏览器开启CSS Grid Layout的方式
- AndroidStudio插件GsonFormat快速实现JavaBean
- Android短信发送流程之多收件人发送(原)
- ActivityOptions过场动画