条款 06:若不想使用编译器自动生成的函数,就该明确拒绝
1、事情的起因
有些类的对象应该是独一无二的,不应该进行对象之间的赋值,也不应该使用复制构造函数在创建对象时进行初始化。但是,如果我们不写赋值符号函数、赋值构造函数的话,编译器就会为我们自动生成这样的函数。而我们如果写了这样的函数,又违背了类的本意。那么我们该如何处理这种情况呢?也就是如何明确的拒绝使用编译器自动生成的函数呢?
2、问题的解决方案
(1)将赋值符号函数或复制构造函数定义为private。
这样做的作用有两点:
- 由于自己手动写了这样的函数,因此编译器不再自动生成。
- 由于手动写的这两个函数为private 的,因此,可以阻止使用该类的人调用这两个函数。
如果定义了private的上述两个函数的话,仍然会有漏洞:
- member函数仍然可以访问这两个函数
- friend函数仍然可以访问这两个函数
解决上述漏洞的方法:
值声明这样的private函数,而不去定义他们。这样,如果有member函数或者friend函数访问它们时,编译器就会报链接错误。在声明的时候,由于我们知道不会调用这样的函数,因此甚至连形参的名字都可以省略不写。
上述的错误提示在连接期。
(2)解决方式二:
我们也可以将上述的错误提示提前到编译期(总之是提前发现了错误,而越早发现错误自然是越好的)。具体的做法就是:
为该类设计一个基类,在基类中将赋值运算符函数、复制构造函数声明为private的,并且不去实现它。
这样的做法,使得当调用复制构造和赋值符号函数时,会试图调用其基类的这两个函数,而基类的这两个函数是私有的,因此引发错误。