c++中的拷贝构造函数原理

有时候即使用同类对象初始化另一个对象,如下:

Type a;
Type b(a);

根据《深入探索C++对象模型》的描述,当类型展现出bitwise copy semantics(位逐次拷贝)时,编译器不需要为该类合成一个默认拷贝构造函数。即只需将对象中的数据按位复制。

实际运行过程中,查看汇编代码,编译器未产生调用。也就是说,编译器没有为测试类型合成默认拷贝构造函数。

C++中,copy constructor 的实现有两种:default memberwise initialization 和 user defined initialization 。前者由编译器执行,后者由程序员自定义的copy constructor 执行。其中default memberwise initialization 又可划分为bitwise copy 和 default copy constructor 。只有当用户未定义自己的copy constructor,且当前类型不能展现出bitwise copy semantics,编译器会合成default copy constructor 。

一个class 不展现出 bitwise copy semantics,有4种情况:

  1. 一个类内含一个对象成员而后者的类型声明有一个拷贝构造函数(无论显示声明还是编译器合成)。
  2. 一个类继承自一个基类而后者存在一个拷贝构造函数。
  3. 一个类声明一个或多个虚函数。
  4. 一个类派生自一个继承串链,其中有一个或多个虚基类。

(实际上按照《深度探索C++对象模型》中的描述,默认构造函数也是未必会被合成出来,可合成默认构造函数的情况与上述相同。
原文:
C++新手一般有两个常见的误解:
1.任何class如果没有定义default constructor ,就会被合成一个出来。
2.编译器合成出来的default constructor 会显示设定class 内每一个data member 的默认值。)

上述4种情况中,前两者的编译器将member object 或 base class 的copy constructor 调用操作安插到被合成的copy constructor 中。其他data member 也会被复制。

什么情况下会用到copy constructor 呢?
1. 用对象显示初始化操作。
2. 用对象初始化函数参数。
3. 用函数返回值初始化对象。

在这几种情况下,编译器会将这些操作做一些转化。
1. 在显示初始化对象时,会将定义的初始化操作剥夺,安插一个copy constructor 的操作。
2. 在初始化函数参数时,调用copy constructor 把实际参数直接建立在其应该的位置上。函数返回前,局部对象的destructor 会被执行。
3. 在返回值用于初始化时,会为函数加上一个额外参数,类型是class object 的一个reference ,用来放置copy constructor 得到的返回值。在return 指令之前安插一个copy constructor 调用操作。

举一个第三种情况的例子,比如:

Type func(int a,int b)
{
    Type x(a,b);
    //...
    return x;
}  

会被转换为:

void func(Type & _result , int a , int b)
{
    Type x(a,b);
    //...
    _result.Type::Type(x);  //拷贝构造函数
    return;
}

从使用者层面可以做出优化,不需要调用copy constructor,而是调用constructor 。

Type func(int a,int b)
{
    return Type(a,b);
}

可以转换为:

void func(Type & _result, int a, int b)
{
    _result.Type::Type(a,b);  //带参构造函数
    return ;
}

因此,并非用函数返回值初始化对象时,总会调用copy constructor

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值