在新编准发布以前,类是通过将其拷贝构造函数和拷贝赋值运算符声明为private来阻止的。

例如,在房产中介看来,每个房子都是独一无二的,所以不允许复制和拷贝。

那么可能会想,如果不希望class支持某一个特定机能,只要不申明对应函数就行,但是这个策略对copy构造函数和copy assignment操作符却不起作用,因为对于这几类函数,如果你不申明他们,当调用的时候,编译器会默认的为你们申明他们,那么怎么办呢??

答案的关键是,所有编译器产出的函数都是public,为阻止这些函数被创建出来,你得自行申明他们,所以可以将其申明为private。这样明确申明了一个成员函数,你阻止了编译器暗自创建其专属版本,而令这些函数为private,使你得以成功阻止人们调用它。

但是呢?这样还是不安全的,因为因为member函数和friend函数还是可以调用你的private函数,不去定义他们,如果有人不慎调用,就会得到连接错误,将成员函数声明为private而且故意不实现他们为大家所接受

将连接错误移至编译器使可能的(越早侦测出错误越好),只要将copy构造函数和copy assignment操作符申明为private就可以办到,但不是在Homesale本身,而是在一个专门为了阻止coping动作而设计的base class内,这个base class非常简单:

条款06:若不想使用编译器自动生成的函数,就该明确拒绝,以及C++11在这方面的新标准

这行得通,因为只要任何人—甚至是menber函数和friend函数尝试拷贝HomeForSale对象,编译器便试着生成一个copy构造函数和一个copy assignment操作符,这时候,编译器会尝试调用base class的对应函数,但是申明为private,所以禁止

所以总结
为驳回编译器自动(暗自)提供的机能,可将相应的成员函数申明为private并且不予实现,使用Uncopyable这样的base class也是一种做法。

但是C++11新标准出来以后,就有新的方法我们可以通过将拷贝构造函数和复制构造函数申明为删除的函数(deleted function)来阻止拷贝,删除的函数是这样一种函数:我们虽然申明了他们,但不能以任何方式使用他们,在函数的参数列表后面加上=delete来指出我们希望将其定义为删除的.

这样HomeForSale可以定义成这样
条款06:若不想使用编译器自动生成的函数,就该明确拒绝,以及C++11在这方面的新标准

但是要注意的是
析构函数不能是删除的成员

我们不能删除析构函数,如果析构函数被删除,就无法销毁此类型的对象了。对于一个删除了析构函数的类型,编译器将不允定义该类型的变量或创建该类的临时对象。而且,如果一个类有某个成员的类型删除了析构函数,我们也不能定义该类的变量或临时变量。如果一个成员的析构函数是删除的,则该成员无法被销毁,而如果一个成员无法被销毁,则对象整体也就无法被销毁了。

对于删除了析构函数的类型,虽然我们不能定义这种类型的变量或者成员,但可以动态分配这种类型的对象,但是,不能释放这些对象。
条款06:若不想使用编译器自动生成的函数,就该明确拒绝,以及C++11在这方面的新标准

合成的拷贝控制成员可能是删除的

有一些规则,但是总结起来:
如果一个类有数据成员不能默认构造、拷贝、复制、或者销毁、则对应的成员函数将被定义为删除的/font>

相关文章: