【C++】深度探索C++对象模型之类存储

本文将继上篇文章,【C++】深度探索C++对象模型之虚拟成员函数(virtual member function), 

继续探索C++类中,

  • data member(数据成员),
  • member function(成员函数),
  • virtual member function(虚函数),
  • 以及在虚拟继承中,单继承,多重继承等各个角度,来探索C++类中的存储。

(申明,本文章中涉及的所有运行,运行环境为: Codeblocks 13.12

一、数据成员,成员函数,以及虚函数内存占用问题

首先通过以下一段源码,进行抛砖引玉
class A {};

class B{
public:
    B(){}
    ~B() {}
};

class C{
public:
    C() {}
    virtual ~C() {}
};

class D {
public:
    D() {}
    ~D() {}

private:
    int m_data;
    char c;
};

int main()
{
    cout << "A = " << sizeof(A) << endl;
    cout << "B = " << sizeof(B) << endl;
    cout << "C = " << sizeof(C) << endl;
    cout << "D = " << sizeof(D) << endl;
    return 0;
}
上述代码中,运行的结果如下:

运行结果分析:
1、A是空类,大小为1,其中的主要理由是:空类并非空,它隐藏着1 byte的大小,由编译器安插进去的一个char,使得以这个类实例化的object,在内存中拥有独一无二的地址。
2、B存在构造函数,以及析构函数。然而大小依旧为1。说明对象所占用的空间大小,与类成员函数无关。
3、C的大小为4。首先,应该注意的是,1中所说的标志独一无二的1 byte char将被此时存在的数据成员而替代。也就是不再需要那个1 byte char来指示地址,因为类成员中本身就存在地址。 这C中的这个类成员,就是一个vptr, 指向类C的virtual table。所以sizeof(C)其实就是求出了类C中的指向virtual table 指针的大小。
4、D进一步说明了,对象所占用的空间大小,与类成员函数无关,而与数据成员,虚函数的指针等有关。当然,这里的大小,需要进行补齐。因为原先的大小为 4 + 1, 但由于自动补齐,使得最终大小变成了 4 + 4。

二、成员函数的存储方式

首先,直观的是,用类去定义对象,系统将会为对象分配存储空间。如果一个类包含了数据成员和函数,那么就需要单独为数据和函数分配存储空间。
所以,直观的感觉是,如果我们为一个类分配了10个对象,那么,存储的示意图如下:
                                                                    
显然,因为函数的执行流程都是一致的。如果能够将函数单独分离出来,那么必然使得存储空间大大得到优化。也就是如下图所示。            
                                                                                                                  
                                                                                    
显然,上述也正是编译器所设计的方案。
所以在1中D的大小,正是说明了一个对象所占的空间大小只取决于该对象中的数据成员以及可能存在的vptr的大小。而函数是存储在对象空间之外的。

问题是,既然调用的是同一段函数代码,那如何区分?
C++使用this指针,来区分对象,类似于在每个函数的调用入口中,都加入了this指针的形式参数,以使得辨认出不同的对象。

总结一下:
  • 函数的地址存在于代码区,不占用对象内存
  • 但是对于含有虚函数的类来说,实例化后的对象中必然存在一个虚拟指针vptr指向类的虚函数表,并占用一个指针的大小。

待续


参考文献:
  1. 侯捷  深度探索C++对象模型
  2. http://c.biancheng.net/cpp/biancheng/view/187.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值