您的位置:首页 > 编程语言 > C语言/C++

C++对象模型

2016-05-10 18:02 399 查看
什么是C++对象模型?引用《深度探索C++对象模型》中的两个概念:
语言中直接支持面向对象程序设计的部分

对各种支持的底层实现机制

In my opinion 对象模型是对象在存储空间上的空间比时间更优,并对C++面向对象的技术加以支持,如虚指针虚表指针支持多态性。什么是多态?
●多态
C++中虚函数的作用主要是为了实现多态机制。多态,是指在继承层次中,父类的指针可以具有多种形态——当他指向某个子类对象时,通过它能调用到子类的函数,而非父类的函数。简单滴讲,当使用基类的指针或引用重写的虚函数时,当使用父类调用的就是父类的虚函数,指向子类就是子类的虚函数。
#include<iostream>
using namespace std;
class Person
{
public:
virtual void BuyTicket()
{
cout<<"买票"<<endl;
}
};
class Student
{
public:
virtual void BuyTicket()
{
cout<<"买票半价"<<endl;
}
};
void Fun(Person& P)
{
P.BuyTicket();
}
void Test()
{
Person P;
Student S;
Fun(P);
Fun(S);
}
虚函数表解析
含有虚函数或其父类含有虚函数的类,编译器都会为其添加一个虚函数表vptr,(先了解虚函数表,有助于C++对象模型的理解)
继承下的C++对象模型。分析C++对象在下面情形中的内存布局:
单继承:子类单一继承自父类,分析了子类重写父类函数,子类定义了新的虚函数情况下子类对象的内存布局。
多继承:子类继承于多个父类,分析了子类重写父类函数,子类定义了新的虚函数情况下子类对象的内存布局,同时分析了虚继承下的菱形继承。
虚继承:分析了单一继承体系下的虚继承、多重基层下的虚继承、重复继承下的虚继承。

●虚表

class Base
{
public:
Base(int i)
:basel(i)
{}
vitual void print(void)
{
cout<<"调用了虚函数的Base::Print()";
}
virtual stel()
{
cout<<"调用了虚函数的Base::stel()";
}
virtual ~Base()
{}
private:
int basel
};


当一个类本身定义了虚函数,或其父类有虚函数时,为了支持多态机制,编译器将为该类添加一个虚函数表指针,虚函数指针一般都放在对象内存布局的第一个位置上,这是因为保证在多层继承或多重继承下能最高效率地取到虚函数表。

当vptr位于对象内存最前面时,对象的地址即为虚函数指针地址。
每个类对象都拥有一个虚表指针, 由编译器为其生成。虚表指针的设定与重置皆由类的复制控制(也是构造函数,析构函数,赋值操作符)来完成。vptr的位置为编译器决定,传统上它被放在所有显示声明的成员之后, 不过现在许多编译器把vptr放在一个类对象的最前端。
●菱形继承
菱形继承也称钻石继承或重复继承,它指的是基类被某个派生类简单重复继承了多次,




●虚拟继承
菱形虚拟继承下,派生类对象又有不同的构成了,在D类的内存构成上,有以下几点:
在D类对象的内存中,基类出现的顺序是:先是B1类(最左父类),然后B2类(次左父类),最后是B类(虚祖父类)
菱形继承下的对象模型是:


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息