透析C++类对象的内存模型

开发 后端
下文着重介绍在C++语言中,如果类中有虚函数,那么它就会有一个虚函数表的指针,在类对象最开始的内存数据中出现。

虽然有许多人对C++类对象表示怀疑,但在年复一年的不断发展中,他的使用率也在不断提高。如过要想对C++类对象充分了解,但前提是要深入理解到底什么是C++类对象,及他是怎么运作的。

首先介绍一下C++中有继承关系的类对象内存的布局:在C++中,如果类中有虚函数,那么它就会有一个虚函数表的指针__vfptr,在类对象最开始的内存数据中。之后是类中的成员变量的内存数据。

对于子类,最开始的内存数据记录着父类对象的拷贝(包括父类虚函数表指针和成员变量)。 之后是子类自己的成员变量数据。对于子类的子类,也是同样的原理。但是无论继承了多少个子类,对象中始终只有一个虚函数表指针。

为了探讨C++类对象的内存布局,先来写几个类和函数首先写一个基类:然后,我们多种不同的继承情况来研究子类的内存对象结构。

1. 无虚函数集继承

  1.  //子类1,无虚函数重载     
  2. class Child1 : public Base     
  3. {     
  4. public:     
  5. virtual void f1() { cout << "Child1::f1" << endl; }     
  6. virtual void g1() { cout << "Child1::g1" << endl; }     
  7. virtual void h1() { cout << "Child1::h1" << endl; }     
  8. int child1;     
  9. protected:     
  10. private:     
  11. };   

2. 有一个虚函数继承

  1.  //子类1,无虚函数重载     
  2. class Child1 : public Base     
  3. {     
  4. public:     
  5. virtual void f1() { cout << "Child1::f1" << endl; }     
  6. virtual void g1() { cout << "Child1::g1" << endl; }     
  7. virtual void h1() { cout << "Child1::h1" << endl; }     
  8. int child1;     
  9. protected:     
  10. private:     
  11. };   

虚拟继承的子类的内存结构,和普通继承完全不同。虚拟继承的子类,有单独的虚函数表, 另外也单独保存一份父类的虚函数表,两部分之间用一个四个字节的0x00000000来作为分界。

子类的内存中,首先是自己的虚函数表,然后是子类的数据成员,然后是0x0,之后就是父类的虚函数表,之后是父类的数据成员。如果子类没有自己的虚函数,那么子类就不会有虚函数表,但是子类数据和父类数据之间,还是需要0x0来间隔。

因此,在虚拟继承中,子C++类对象和父类的数据,是完全间隔的。存放子类自己的虚函数表和数据,中间以0x分界,最后保存父类的虚函数和数据。如果子类重载了父类的虚函数,那么则将子类内存中父类虚函数表的相应函数替换。

【编辑推荐】

  1. 简介学习C++总结之谈
  2. 对C++库函数进行学习探索总结笔记
  3. C++类库设计的基本构思与方法
  4. C++语言真的还有市场价值?
  5. C++类库设计的基本构思与方法
责任编辑:chenqingxiang 来源: pcppc.cn
相关推荐

2011-06-21 10:17:41

c++内存模型

2010-01-28 13:45:06

C++数组

2010-01-19 14:28:41

C++ main()函

2010-01-18 09:39:25

C++语言

2010-01-22 13:45:36

C++代码

2010-01-20 14:13:33

C++变量

2010-01-21 10:04:14

C++语言

2010-01-25 14:18:46

C++对象模型

2020-10-23 18:46:58

C++程序类别

2010-01-27 10:13:22

C++类对象

2011-06-01 10:19:41

基类对象派生类对象

2011-07-20 13:40:09

拷贝构造函数

2024-07-25 14:18:29

2010-01-21 13:33:44

C++基类

2010-01-15 18:35:25

C++的类

2011-04-11 09:47:50

C++内存管理

2010-01-28 13:27:12

C++类定义

2009-08-28 09:43:05

C#事件

2010-01-21 13:48:30

C++基类

2011-06-16 09:28:02

C++内存泄漏
点赞
收藏

51CTO技术栈公众号