手机版
你好,游客 登录 注册
背景:
阅读新闻

C++类对象的内存模型

[日期:2014-12-31] 来源:Linux社区  作者:Linux [字体: ]

内存模型描述的是程序中各变量(实例域、静态域和数组元素)之间的关系,以及在实际计算机系统中将变量存储到内存和从内存取出变量这样的低层细节.不同平台间的处理器架构将直接影响内存模型的结构. 

首先介绍一下C++中有继承关系的类对象内存的布局: 

在C++中,如果类中有虚函数,那么它就会有一个虚函数表的指针__vfptr,在类对象最开始的内存数据中。之后是类中的成员变量的内存数据。 

对于子类,最开始的内存数据记录着父类对象的拷贝(包括父类虚函数表指针和成员变量)。之后是子类自己的成员变量数据。 

对于子类的子类,也是同样的原理。但是无论继承了多少个子类,对象中始终只有一个虚函数表指针。

虚函数表指针

 

为了探讨C++类对象的内存布局,先来写几个类和函数

 

首先写一个基类:

 

class Base 

public: 
virtual void f() { cout << "Base::f" << endl; } 
virtual void g() { cout << "Base::g" << endl; } 
virtual void h() { cout << "Base::h" << endl; } 
int base; 
protected: 
private: 
}; 

然后,我们多种不同的继承情况来研究子类的内存对象结构。

1. 无虚函数集继承

//子类1,无虚函数重载 
class Child1 : public Base 

public: 
virtual void f1() { cout << "Child1::f1" << endl; } 
virtual void g1() { cout << "Child1::g1" << endl; } 
virtual void h1() { cout << "Child1::h1" << endl; } 
int child1; 
protected: 
private: 
}; 

这个子类Child1没有继承任何一个基类的虚函数,因此它的虚函数表如下图:

我们可以看出,子类的虚函数表中,先存放基类的虚函数,在存放子类自己的虚函数。

2. 有一个虚函数继承

//子类2,有1个虚函数重载 
class Child2 : public Base 

public: 
virtual void f() { cout << "Child2::f" << endl; } 
virtual void g2() { cout << "Child2::g2" << endl; } 
virtual void h2() { cout << "Child2::h2" << endl; } 
int child2; 
protected: 
private: 
}; 

当子类重载了父类的虚函数,则编译器会将子类虚函数表中对应的父类的虚函数替换成子类的函数。

3. 全部虚函数都继承

//子类3,全部虚函数重载 
class Child3 : public Base 

public: 
virtual void f() { cout << "Child3::f" << endl; } 
virtual void g() { cout << "Child3::g" << endl; } 
virtual void h() { cout << "Child3::h" << endl; } 
protected: 
int x; 
private: 
}; 

C++ Primer Plus 第6版 中文版 清晰有书签PDF+源代码 http://www.linuxidc.com/Linux/2014-05/101227.htm

读C++ Primer 之构造函数陷阱 http://www.linuxidc.com/Linux/2011-08/40176.htm

读C++ Primer 之智能指针 http://www.linuxidc.com/Linux/2011-08/40177.htm

读C++ Primer 之句柄类 http://www.linuxidc.com/Linux/2011-08/40175.htm

C语言梳理一下,分布在以下10个章节中:

  1. Linux-C成长之路(一):Linux下C编程概要 http://www.linuxidc.com/Linux/2014-05/101242.htm
  2. Linux-C成长之路(二):基本数据类型 http://www.linuxidc.com/Linux/2014-05/101242p2.htm
  3. Linux-C成长之路(三):基本IO函数操作 http://www.linuxidc.com/Linux/2014-05/101242p3.htm
  4. Linux-C成长之路(四):运算符 http://www.linuxidc.com/Linux/2014-05/101242p4.htm
  5. Linux-C成长之路(五):控制流 http://www.linuxidc.com/Linux/2014-05/101242p5.htm
  6. Linux-C成长之路(六):函数要义 http://www.linuxidc.com/Linux/2014-05/101242p6.htm
  7. Linux-C成长之路(七):数组与指针 http://www.linuxidc.com/Linux/2014-05/101242p7.htm
  8. Linux-C成长之路(八):存储类,动态内存 http://www.linuxidc.com/Linux/2014-05/101242p8.htm
  9. Linux-C成长之路(九):复合数据类型 http://www.linuxidc.com/Linux/2014-05/101242p9.htm
  10. Linux-C成长之路(十):其他高级议题

更多详情见请继续阅读下一页的精彩内容http://www.linuxidc.com/Linux/2014-12/111047p2.htm

linux
相关资讯       C++  内存模型 
本文评论   查看全部评论 (0)
表情: 表情 姓名: 字数

       

评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为���直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款