目录
一、默认构造
默认构造函数就是在创建类的时候没有声明构造函数或类在声明的时候,没有任何初始化参数就会调用默认构造函数。系统会提供一个默认的构造函数。
- 构造函数中未初始化的变量,直接使用会报错;
- 如果类中显示声明了任何构造函数,默认构造函数就不会自动提供。
二、拷贝构造函数
当用一个已初始化的自定义类类型对象去初始化另一个新构造的对象的时候,拷贝构造函数就会被自动调用。也就是说,当类的对象需要拷贝时,拷贝构造函数将会被调用。
默认调用拷贝构造函数的三种情况:
- 一个对象以值传递的方式传入函数体;
- 一个对象以值传递的方式从函数返回;
- 一个对象需要通过另一个对象进行初始化。
如果类中没有显示地声明一个拷贝构造函数,编译器会提供一个默认的拷贝构造函数。该构造函数完成对象的位拷贝。位拷贝又称为浅拷贝。
- 浅拷贝:类中的资源没有重新分配。类中有指针分配内存了,新的对象不会分配内存;
- 深拷贝:类在复制过程中,资源会重新分配。会开辟空间复制被复制对象中指针指向的数据;
- 最好自定义拷贝构造;
注意:如果实行位拷贝,例如 A = B。这时,如果B中有一个成员变量指针已经申请了内存,那A中的那个成员变量也指向同一块内存。这就出现了问题:当B把内存释放了(如:析构),这时A内的指针就是野指针了,出现运行错误。
拷贝赋值操作符:当未声明错操作运算符“=”时,系统会默认提供一个“=”的函数声明,但它默认执行的是浅拷贝。
三、转移构造函数
左值:指表达式结束后依然存在的对象。
右值:指表达式结束后不再存在的临时对象。
右值对象的产生:
1)不同类型(变量)的转换;
2)调用函数传值时;
3)表达式求值时;
用到临时对象(右值)的时候,就会执行移动语义。std::move():可以将右值转为左值。
通俗讲,移动语义就是将临时变量的地址,赋值给新的对象。
使用临时对象的值初始化另一个对象值,不会要求对对象的复制:因为临时对象不会有其它使用,因而,它的值可以被移动到目的对象。做到这些,就要使用移动构造函数和移动赋值:
移动操作的概念对对象管理它们使用的存储空间很有用的,诸如对象使用new和delete分配内存的时候。在这类对象中,拷贝和移动是不同的操作:从A拷贝到B意味着,B分配了新内存,A的整个内容被拷贝到为B分配的新内存上。 而从A移动到B意味着分配给A的内存转移给了B,没有分配新的内存,它仅仅包含简单地拷贝指针。