cpp拷贝构造的3/5法则

来源

由于拷贝控制操作是由三个特殊的成员函数来完成的,所以我们称此为“C++三法则”。在较新的 C++11 标准中,为了支持移动语义,又增加了移动构造函数和移动赋值运算符,这样共有五个特殊的成员函数,所以又称为“C++五法则”。也就是说,“三法则”是针对较旧的 C++89 标准说的,“五法则”是针对较新的 C++11 标准说的。为了统一称呼,后来人们把它叫做“C++ 三/五法则”。

CPP拷贝构造

在这里插入图片描述
这个命名,原来看c++ primer的时候,搞的我有点晕,今天梳理一下:
这个命名可以看做 内容来源 + 内容去向 来看.
内容来源分类两个:1.copy旧资源(拷贝) 2.move旧资源(移动)
内容去向分为两个:1.new 新的内容 (构造) 2.cove 旧内存(赋值)
上面组合一下就可以得到4个需要定义个拷贝构造函数,拷贝赋值函数,移动构造函数,移动赋值函数.再加上一个默认构造函数.
其他的一些规律:

  1. 构造函数都是没有返回值的
  2. 赋值函数需要返回this指针,为了实现a = b = c连续赋值操作.
  3. 拷贝函数输入参数都是常引用,因为不会修改原来的内容,就是copy一下.
    在这里插入图片描述

3/5法则

  1. 需要析构函数的类也需要拷贝构造函数和拷贝赋值函数。(同时定义这三个函数)
  2. 需要拷贝操作的类也需要赋值操作,反之亦然。
  3. 析构函数不能是删除的
  4. 如果一个类有删除的或不可访问的析构函数,那么其默认和拷贝构造函数会被定义为删除的。
  5. 如果一个类有const或引用成员,则不能使用合成的拷贝赋值操作。

案例1:
在这里插入图片描述
注意:这里vector里面没有定义拷贝构造函数,拷贝赋值也没有.只有一个基础的构造函数,用于分配内存.

在这里插入图片描述
1.是浅拷贝 2.double free的问题.
解决方法:
1.禁止浅拷贝
在这里插入图片描述
2.定义拷贝构造函数,重新分配内存,把来源内容拷贝到新内存中去.
在这里插入图片描述
cpp中默认构造函数的关系
在这里插入图片描述
在这里插入图片描述

第二案例:

有定义三个函数

class Car //A very simple class just to demonstrate what these definitions mean.
//It's pseudocode C++/Javaish, I assume strings do not need to be allocated.
{
private String sPrintColor;
private String sModel;
private String sMake;

public changePaint(String newColor)
{
   this.sPrintColor = newColor;
}

public Car(String model, String make, String color) //Constructor
{
   this.sPrintColor = color;
   this.sModel = model;
   this.sMake = make;
}

public ~Car() //Destructor
{
//Because we did not create any custom types, we aren't adding more code.
//Anytime your object goes out of scope / program collects garbage / etc. this guy gets called + all other related destructors.
//Since we did not use anything but strings, we have nothing additional to handle.
//The assumption is being made that the 3 strings will be handled by string's destructor and that it is being called automatically--if this were not the case you would need to do it here.
}

public Car(const Car &other) // Copy Constructor
{
   this.sPrintColor = other.sPrintColor;
   this.sModel = other.sModel;
   this.sMake = other.sMake;
}
public Car &operator =(const Car &other) // Assignment Operator
{
   if(this != &other)
   {
      this.sPrintColor = other.sPrintColor;
      this.sModel = other.sModel;
      this.sMake = other.sMake;
   }
   return *this;
}

}


Car car1 = new Car("mustang", "ford", "red");
Car car2 = car1; //Call the copy constructor
car2.changePaint("green");
//car2 is now green but car1 is still red.

没有定义这三个函数


class Car //A very simple class just to demonstrate what these definitions mean.
//It's pseudocode C++/Javaish, I assume strings do not need to be allocated.
{
private String sPrintColor;
private String sModel;
private String sMake;

public changePaint(String newColor)
{
   this.sPrintColor = newColor;
}

public Car(String model, String make, String color) //Constructor
{
   this.sPrintColor = color;
   this.sModel = model;
   this.sMake = make;
}

public ~Car() //Destructor
{
//Because we did not create any custom types, we aren't adding more code.
//Anytime your object goes out of scope / program collects garbage / etc. this guy gets called + all other related destructors.
//Since we did not use anything but strings, we have nothing additional to handle.
//The assumption is being made that the 3 strings will be handled by string's destructor and that it is being called automatically--if this were not the case you would need to do it here.
}

}


//Shallow copy example
//Assume we're in C++ because it's standard behavior is to shallow copy objects if you do not have a constructor written for an operation.
//Now let's assume I do not have any code for the assignment or copy operations like I do above...with those now gone, C++ will use the default.

 Car car1 = new Car("ford", "mustang", "red"); 
 Car car2 = car1; 
 car2.changePaint("green");//car1 is also now green 
 delete car2;/*I get rid of my car which is also really your car...I told C++ to resolve 
 the address of where car2 exists and delete the memory...which is also
 the memory associated with your car.*/
 car1.changePaint("red");/*program will likely crash because this area is
 no longer allocated to the program.*/

reference

C++之三五法则
stackOverFlow:What is The Rule of Three?
stackOverFlow: What is the copy-and-swap idiom?
双笙子佯谬【公开课】第02讲:RAII与智能指针

C++ 类的特殊成员是什么?有什么坑?如何写好一个类?

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值