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

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

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类公有继承自它。

相关文章
|
7天前
如何处理构造函数中参数的默认值?
设置合理的默认值可以增加代码的灵活性和易用性,同时减少在调用构造函数时必须传递所有参数的要求。在处理默认值时,要确保其合理性和一致性,避免出现意外的行为或错误。你还想了解关于构造函数的其他方面吗?比如参数的验证等
15 1
默认移动构造、默认移动赋值自动生成的条件
默认移动构造、默认移动赋值自动生成的条件
168 0
|
前端开发 Java 程序员
实现nest中未定义参数的入参校验
实现nest中未定义参数的入参校验
实现nest中未定义参数的入参校验
|
编译器
vc++ 设置64位编译器
vc++ 设置64位编译器
203 0
关于 屏蔽Qt未使用变量报警错误 的解决方法
关于 屏蔽Qt未使用变量报警错误 的解决方法
关于 屏蔽Qt未使用变量报警错误 的解决方法
C++中转换构造函数与默认函数的优先级
C++中转换构造函数与默认函数的优先级
|
C++
vs调试的时候,指定的参数已超出有效值的范围。参数名:sit ,先仔细看看错误和我的一样不一样
https://www.cnblogs.com/pei123/p/7694947.html 指定的参数已超出有效值的范围。参数名:sit ,先仔细看看错误和我的一样不一样 更新了1709就这样了,的确修复了就可以了 控制面板>程序> 网名:浩秦; 邮箱:root#landv.pw; 只要我能控制一個國家的貨幣發行,我不在乎誰制定法律。
1123 0
|
Windows 开发工具
UWP项目生成错误: 未能使用“CompileXaml”任务的输入参数初始化该任务。“CompileXaml”任务不支持“PlatformXmlDir”参数。请确认该参数存在于此任务中,并且是可设置的公共实例属性。
项目属性: 目标版本 16299  最低版本 14393   解决方法:目标版本 15063 最低版本 14393   The issue is a bug in the Windows SDK that is causing an incompatible MSBuild tasks as...
1487 0