拷贝,赋值与销毁
- 拷贝构造函数
- 即使我们自己定义了一个拷贝构造函数,编译器也会自动生成一个
- 通常,拷贝构造函数是一个第一参数为自身引用的函数
- 类内:Sales_data (const Sales_data&){…}
- 拷贝构造函数被用来初始化非引用类类型参数。这一特性也解释了,为什么拷贝构造函数的参数必须为引用类型
- 拷贝构造函数就是在新建类的时候使用:
- 如果A是一个已经定义的类,那么:
- Sales_data trans = A;//就会使用拷贝构造函数
- 拷贝赋值运算符
- 而:
- Sales_data trans;
- trans = A;//则会用拷贝赋值运算符
- 析构函数
- 无论何时,一个变量被销毁,就会调用其析构函数
- 变量在离开时作用域时被销毁
- 当一个对象被销毁时,其成员被销毁
- 容器被销毁时,其元素被销毁
- 动态分配的对象,其指针delete时,被销毁
- 需要析构函数的类页需要拷贝和赋值操作
- 需要拷贝操作的类也需要要赋值操作,反之亦然
对象移动
- 当有些类含有不能共享的资源时,是不能拷贝的
- 或者一些对象比较大,,或者本身要求分配内存空间。则进行不必要的拷贝的代价是很大的
- 类似的,在旧版本标准库中,容器中保存的类必须是可拷贝的
- 而新标准在中,我们多了一种选择,移动。
- 右值引用:就是两个&&
- 左值是对象,右值是对象的值
- 左值引用:
- int a = 10;
- int &b = a;
- int &c = a * 20; //错误,a*20是一个右值
- 右值引用:
- int &&c = a * 20; //正确
移动构造函数和移动赋值运算符
-
两者的差别就在于,一个是直接用于初始化,一个是,创建后,赋值
-
不抛出异常的移动构造函数和移动赋值运算符必须标记为noexpect
-
和拷贝构造函数相同,其第一个参数是该类类型的引用
-
一定要记住,在移动后的指针,要nullptr
-
移动构造函数
-
移动赋值运算符