C++对象模型

本文详细解释了C++中对象布局、对象封装成本、对象模型(包括静态和非静态成员)、继承机制(特别是虚继承),以及默认构造函数和拷贝构造函数的生成规则。通过这些内容,读者能更好地理解C++语言的工作原理和潜在性能优化点。
摘要由CSDN通过智能技术生成

前言       

        很多人会误以为C++的效率低于C,实质上C++ 相对C语言并没有过多的开销,由于对对象模型不理解,很多人会误以为C++ 编译器会在背后偷偷干一些事情。 对象布局不是C++的语言标准,所以每个编译器可以有自己的实现,但很多时候各编译器的实现是相同的。讨论C++的对象布局,可以了解其背后做了什么事情,理解对象的开销。

对象

对象封装后的成本

     通过class封装函数和成员变量,并不会增加额外的成本。如下代码,和C定义一个struct变量和一个prt函数的成本是一致的。class的data member和struct一样组织,member function,是所有的object共用的。

class C
{
private:
    int a;
    char b;

public:
    C()
    {
    }

    void prt()
    {
    }
}

对象模型

      C++中有两种data member:static 和 nonstatic,三种class member functions:static、nonstatic 和 virtual。

      nonstatic data member 置于每个class object中,static data members则放在所有的class object之外,static 和 nonstatic function member 也被放在所有的class object之外,virtual functions则通过以下两个步骤支持:

      (1)通过virtual table保存指向各个virtual function的指针

      (2)每个object起始地址添加一个指向virtual table的指针: vptr。virtual table 的首位置保存了对象类型。从而实现了运行时类型识别。

继承

        包括单一继承、多重继承(最好是少用)、虚继承(共享继承,从来没见代码中实际用过)。C++的派生类data member和基类的data member是紧凑存储的,base class data member 直接放在deriverd class中,从而达到更高效率。

默认构造函数的构建

        什么时候编译器会自动添加一个默认构造函数?看下面的代码

class Foo()
{
public:
    int val;
    Foo *pnext;
};

void foo_bar()
{
    Foo bar;
    if (bar.val || bar.pnext)
    {
        ...
    }
}

        没有任何构造函数的时候,编译器会生成一个默认构造函数,默认构造函数没做什么有效的事情,上面例子中,需要生成一个构造函数将变量初始化为0才行。生成的默认构造函数会包含必要的代码。Bar的默认构造函数会自动调用Foo的默认构造函数。

class Bar
{
    Foo f;
    char *p;
};

 Copy constructor的构建

        如果没有定义拷贝构造函数,会生成一个默认拷贝构造函数。默认拷贝构造函数,会直接复制内建类型的值,对于嵌套的object,则采用递归的方式执行成员初始化。例如:

class C
{
private:
    char *p;
    int a;
    Foo f;
};

class C的默认拷贝构造函数,会直接复制p和a的值,然后递归初始化f。

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值