重学C++ (八) 复制控制

1.只有单个形参,且该形参是对本类类型对象的【引用】(常用const修饰),这样的构造函数叫做复制构造函数;
(参数必须是引用:否则,在调用复制构造函数之前,需要调用同一个复制构造函数来初始化它自己的参数,造成无限循环调用)

2.如果我们没有定义复制构造函数,编译器会为我们合成一个。合成的复制构造函数执行逐个成员初始化,将新对象初始化为原对象的副本(复制数组时,将复制数组的每一个元素;如果类中有指针成员,那么一般需要自己定义复制构造函数);

3.有些类禁止复制(如iostream类)。为防止复制,类必须【显式】声明其复制构造函数为private(如果不定义复制构造函数,编译器会合成一个,这并不能防止复制);
如果想要连友元和成员中的复制也禁止,则可以声明一个private复制构造函数但不对其定义(声明但不定义是合法的,但是任何对它的使用将导致链接失败);

4.重载赋值:当操作符为成员函数时,它的第一个操作数隐式绑定到this指针;

class Sales_item
{
public:
    Sales_item& operator = (const Sales_item &)
}

复制操作符也会自动合成,如果我们没定义的话;
它的作用跟复制构造函数差不多;

5.撤销类对象时会自动调用析构函数;容器中的元素总是按逆序撤销;

6.三法则:如果类需要析构函数,则它也需要赋值操作符和复制构造函数;

7.无论我们有没有编写自己的析构函数,编译器总会为我们合成一个(即使我们编写了自己的析构函数,合成析构函数仍然运行!),它按对象创建时的逆序撤销每个非static成员(注意,合成析构函数并不删除指针成员所指向的对象);

8.析构函数没有参数,所以不能重载;

9.右值引用:这是C++11的新特性,它可以绑定到一个右值上,但是不能绑定到左值上,右值引用使用&&;(左值是指表达式结束后依然存在的持久对象,右值是指表达式结束时就不再存在的临时对象–>a++是右值,因为返回的是自增前的自身拷贝,是一个临时对象,++a是左值,它返回自身)

int i = 42;
int &r = i;             // ok: r refers to i
int &&rr = i;           // error: cannot bind an rvalue reference to an lvalue
int &r2 = i * 42;       // error: i * 42 is an rvalue
const int &r3 = i * 42; // ok: we can bind a reference to const to an rvalue
int &&rr2 = i * 42;     // ok: bind rr2 to the result of the multiplication

由于变量是左值,所以以下情况需要注意:

int &&rr1 = 42;    // ok: literals are rvalues
int &&rr2 = rr1;   // error: the expression rr1 is an lvalue!

//使用std::move显式将左值转换为右值
int &&rr3 = std::move(rr1);   // ok
//We can destroy a moved-from object and can assign a new value to it, but
//we cannot use the value of a moved-from object.
//即我们可以给rr1赋一个新值,或者销毁它,但是不可以使用它的值了!

相关知识还有move构造函数,move赋值等,此处暂不展开。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值