这里我们主要探究C++里面的默认拷贝和移动构造行为探究,结合实践测试单元进行总结归纳分析.
深拷贝和浅拷贝
进行测试之前,我们首先要弄明白,c++中深拷贝和浅拷贝的意思.
深拷贝:触发拷贝构造和移动构造
浅拷贝:按值赋值
拷贝构造和移动构造
要理解好拷贝构造和移动构造,一定要理解好,一定要结合设计目的和对象的生命周期2个维度来进行理解!
拷贝构造行为核心思想是为了产生一个对象的副本,副本会完全拷贝实体数据,同时副本产生之后,有自己独立的生命周期,和原对象是完全独立的2个个体.
移动构造本质上是让新产生的对象全盘接收原有对象的实体数据,同时原有对象的生命周期很快就要结束.
默认行为探究
#include <iostream>
#include <string>
using namespace std;
class A
{
public:
A()
{
p = new int(5);
cout << "A:()" << std::endl;
}
A(const A& other)
{
cout << "A::(A&) 拷贝构造函数" << endl;
p = new int(*other.p);
}
A(A&& other)
{
cout << "A::(A&&) 移动构造函数" << endl;
p = other.p;
other.p = NULL;
}
A operator=(const A&)
{
cout << "A operator=(const A&)" << endl;
}
A operator=(A&&)
{
cout << "A operator=(A&&)" << endl;
}
~A()
{
cout << "A::~A()析构函数" << endl;
delete p;
}
int* p;
int a = 5;
};
struct mystruct {
A a;
};
上面只是一个很简单的demo,那么问题来了,当我们要对mystruct进行拷贝构造和移动构造时,A的行为究竟是怎么样的?
struct mystruct s1;
struct mystruct s2 = s1;
struct mystruct s3 = std::move(s1);
控制台输出 :
OK,到这一步,其实已经很明确了:
总结:
- 类或者结构体执行拷贝构造函数,如果类或者结构体内部的成员同样为类类型时,同样会触成员的拷贝构造。
- 类或者结构体执行移动构造函数,如果类或者结构体内部的成员同样为类类型时,同样会触成员的移动构造。
- 基本数据类型直接按值拷贝,指针类型执行赋值操作
- 1和2针对类的成员,类的成员的成员,。。。。适用,直到最后一层.