如果不想使用编译器默认生成的函数,请明确拒绝它!

简介: 如果不想使用编译器默认生成的函数,请明确拒绝它!

1.问题引入


试想如下情形,某个房地产商所拥有的房子都是不同的。同时,你在为这个公司设计程序,而你不想将一座房子的信息拷贝给另一座房子,这就需要禁止使用拷贝构造函数和拷贝赋值运算符(copy assignment operator)。如下例所示:


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}


如果是其他功能,不想使用的话不声明即可。但是对于以上这两个功能,像昨天的文章C++类中默认生成的函数所说的。即使你不声明不定义,编译器还是会为该类自动生成的。


2.解决方法


解决方法:首先,因为编译器为类自动生成的函数都是共有(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权限自动生成的函数,由于找不到自动生成函数的定义,链接器则会出错。但是,将所有报错提前到编译器不是更好吗?这样就可以越早的检测出错误了。


3.更好的解决方法


昨天的文章C++类中默认生成的函数中也提到了,当一个父类将拷贝构造函数和拷贝赋值运算符声明为私有时,编译器会拒绝为它的子类生成拷贝构造函数和拷贝赋值运算符因此我们可以专门使用一个父类,在父类当中声明拷贝操作为私有(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};


4.总结


(1).当不想让编译器为类自动生成某些函数时,把这些不想要的函数声明在此类的私有成员中并不予以定义。或者,更好的方法使用像上例中定义一个Uncopyable父类,并让我们的House类公有继承自它。

相关文章
|
3月前
|
Dart
Dart之函数(递归、匿名、自执行、可选参数、默认参数、命名参数)
Dart之函数(递归、匿名、自执行、可选参数、默认参数、命名参数)
默认移动构造、默认移动赋值自动生成的条件
默认移动构造、默认移动赋值自动生成的条件
137 0
|
4月前
|
存储 C#
C# 方法详解:定义、调用、参数、默认值、返回值、命名参数、方法重载全解析
方法是一段代码,只有在调用时才会运行。 您可以将数据(称为参数)传递给方法。 方法用于执行某些操作,也被称为函数。 为什么使用方法?为了重用代码:定义一次代码,然后多次使用。
67 0
|
编译器
vc++ 设置64位编译器
vc++ 设置64位编译器
189 0
on方法多次绑定会多次执行的解决方法
on方法多次绑定会多次执行的解决方法
115 0
|
开发者 Python
函数的缺省函数| 学习笔记
快速学习函数的缺省函数
关于 屏蔽Qt未使用变量报警错误 的解决方法
关于 屏蔽Qt未使用变量报警错误 的解决方法
关于 屏蔽Qt未使用变量报警错误 的解决方法
C++中转换构造函数与默认函数的优先级
C++中转换构造函数与默认函数的优先级
在请求中传入不定长参数实现不同的逻辑处理的解决办法
在请求中传入不定长参数实现不同的逻辑处理的解决办法
|
Python
PyQt5 技巧篇-增加一个类级变量,类级变量的设置方法,类级“常量“设置方法
PyQt5 技巧篇-增加一个类级变量,类级变量的设置方法,类级“常量“设置方法
318 0