-
拷贝构造函数
形式是普通构造函数的参数列表表中有常对象的引用。
为什么是引用?如果不是引用,拷贝构造函数的参数是值传递,值传递又会调用拷贝构造函数,陷入死循环。直接初始化与拷贝初始化
string str(“hello”) 直接初始化
string str = "hello"是拷贝初始化
要求编译器将右侧运算对象拷贝到正在创建的对象中拷贝初始化不仅在我们使用=定义变量时发生,
还有:将一个对象作为实参传递给一个非引用类型行参数(就是上面的拷贝构造函数为什么是引用)
返回非引用类型的函数返回一个对象
列表初始化是拷贝
2.拷贝赋值运算符
重载运算符本质是函数,与拷贝构造函数类似。
- 析构函数
销毁类类型的成员需要执行成员自己的析构函数。内置类型没有析构函数,因此销毁内置类型成员什么都不需要做。
容器、变量和临时对象都会自动销毁,动态分配的对象,指针需要手动delete销毁。
析构函数并不直接销毁成员,而是析构函数执行之后,各成员调用自己的析构函数。
4.三/五法则
有析构函数就一定需要拷贝和赋值操作,定义析构,说明有指针,有指针的话,拷贝和赋值就不可以使用合成的。合成的拷贝和赋值的对象撤销时,会两次delete指针
- 解决方法
定义自己的拷贝构造函数,不是直接拷贝指针,而是拷贝指针指向的对象。
之前 p1 = p2;
现在 p1 = new string(*p2)
6.移动构造函数
移动构造函数的第一个参数是该类类型的一个右值引用。
移动后,源对象处于这样一个状态,销毁它是无害的。
(str &&s):a(a1),b(b1),c(c1){
a1 = b1 = c1 = nullptr
}
nullptr是保证析构时,是无害的