如果不想使用编译器默认生成的函数,请明确拒绝它!
点蓝色字关注“CurryCoder的程序人生”
1.问题引入
1#include <iostream>
2
3class House
4{
5 // ...
6};
7
8int main()
9{
10 House h1;
11 House h2;
12 House h3(h1); // 禁止执行默认的拷贝构造函数
13 h1 = h2; // 禁止执行默认的拷贝赋值运算符
14
15 return 0;
16}
解决方法:首先,因为编译器为类自动生成的函数都是共有(public)的,所以我们就可以把这些函数声明为私有(private),这样类生成的对象就无权限调用它们。其次,只声明不定义。因为如果有定义,本类和友元函数(friend functions)还是可以调用它们。如下例所示:
1#include <iostream>
2
3class House
4{
5public:
6 // ...
7private:
8 House (const House&); // 只声明,不定义拷贝构造函数。同时要设为private!由于根本就不会用到它们,所以可以不必写形参了
9 House& operator=(const House&); // 只声明,不定义拷贝赋值运算符。同时要设为private!由于根本就不会用到它们,所以可以不必写形参了
10};
因此,当你在代码中试图拷贝对象,编译器就会报错。然而,如果你不小心在该类的成员函数或者友元函数中调用了private权限自动生成的函数,由于找不到自动生成函数的定义,链接器则会出错。但是,将所有报错提前到编译器不是更好吗?这样就可以越早的检测出错误了。
昨天的文章中也提到了,当一个父类将拷贝构造函数和拷贝赋值运算符声明为私有时,编译器会拒绝为它的子类生成拷贝构造函数和拷贝赋值运算符。因此我们可以专门使用一个父类,在父类当中声明拷贝操作为私有(private),并让我们的类继承自它。这样,当成员函数或友元函数试图拷贝House对象时,所有关于拷贝的操作都会提前在编译阶段报错。如下例所示:
1#include <iostream>
2
3class Uncopyable{
4protected:
5 Uncopyable(){}
6 ~Uncopyable(){}
7private:
8 Uncopyable(const Uncopyable&);
9 Uncopyable& operator=(const Uncopyable&);
10};
11
12class House: public Uncopyable{
13// ...
14};
觉得好看,请点这里↓↓↓