- 4
- 0
- 约3.13千字
- 约 3页
- 2018-04-17 发布于河南
- 举报
C 箴言:拒绝不想用的编译器产生的函数
C++箴言:拒绝不想用的编译器产生的函数
如果你不想使用编译器为你产生的函数,就明确拒绝
不动产代理商出售房屋,服务于这样的代理商的软件系统自然要有一个类来表示被出售
的房屋:
classHomeForSale {…… };
每一个不动产代理商都会很快指出,每一件财产都是独特的——没有两件是完全一样
的。在这种情况下,为 HomeForSale 对象做一个拷贝的想法就令人不解了。你怎么能拷贝
一个独一无二的东西呢?最好让这种类似企图拷贝 HomeForSale 对象的行为不能通过编
译:
HomeForSaleh1;
HomeForSaleh2;
HomeForSale h3(h1); // attempt to copy h1 -
should
// not compile!
h1 = h2; // attempt tocopyh2 - should
// not compile!
唉,防止这种编译的方法并非那么简单易懂。通常,如果你不希望一个 class 支持某种
功能,你可以简单地不声明赋予它这种功能的函数。这个策略对于拷贝赋值运算符不起作用,
因为,就象 Item5 中指出的,如果你不声明它们,而有人又想调用它们,编译器就会隐式
地声明它们。
这就限制了你。如果你不声明拷贝构造函数和拷贝赋值运算符,编译器也可以为你生成
它们。你的类还是会支持拷贝。另一方面,如果你声明了这些函数,你的类依然会支持拷贝。
我们在这里的目标就是防止拷贝。 解决这个问题的关键是所有的编译器生成的函数都是
public.为了防止生成这些函数,你必须自己声明它们,但是你没有理由把它们声明为 public.
相反,应该将拷贝构造函数和拷贝赋值运算符声明为 private.通过显式声明一个成员函数,
可以防止编译器生成它自己的版本,而且将这个函数声明为 private,可以防止别人调用它。
通常,这个方案并不十分保险,因为成员函数和友元函数还是能够调用 private 函数。
换句话说,除非你不定义它们。那么,当有人不小心地调用了它们,在连接的时候会出现错
误。这个窍门——定义一个 private 成员函数却故意不去实现它——确实不错,在 C++ 的
iostreams 库里,就有几个类用此方法防止拷贝。比如,看一下你用的标准库的实现中,
ios_base,basic_ios 和 sentry 的定义,你就会看到拷贝构造函数和拷贝赋值运算符被声明
为 private 而且没有定义的情况。
将这个窍门用到 HomeForSale 上,很简单:
classHomeForSale{
public:
..
private:
...
HomeForSale(const HomeForSale); // declarations
only
HomeForSale operator=(const HomeForSale);
};
你会注意到,我省略了函数参数的名字。这没有必要,只是一个普通的惯例。毕竟,函
数不会被定义,极少有机会被用到,有什么必要指定参数的名字呢?
对于上面的类定义,编译器将阻止客户拷贝 HomeForSale 对象的企图,如果你不小心
在成员函数或者友元函数中这样做了,连接程序会提出抗议。
将连接时错误提前到编译时间也是可行的(早发现错误毕竟比晚发现好),不要让
HomeForSale 自己去声明 private 的拷贝构造函数和拷贝赋值运算符,在一个特意设计的基
类中声明。这个基类本身非常简单:
classUncopyable {
protected:// allowconstruction
Uncopyable(){} // anddestruction
您可能关注的文档
最近下载
- (2026年)实施指南《GBT13265.1-1997纤维光学隔离器第1部分总规范》.pptx VIP
- 2026-2030中国沉香木行业市场深度调研及发展趋势与投资前景研究报告.docx
- 东北证券-博源化工-000683-稀缺天然碱领军企业阿碱项目稳步扩产.pdf VIP
- JB_T 8531-2013阀门手动装置 技术条件.pdf
- 武术套路单项比赛所需物品明细单.docx VIP
- 部编版小学语文教师:统编版语文1-6年级语文要素梳理.pdf VIP
- 2026年江苏城市职业学院单招职业技能考试必刷测试卷附答案.docx VIP
- 船上见习记录簿(样式).pdf
- (2026春新版)三年级下册道德与法治全册教案.docx
- (2025年)广东省公务员招录面试真题及答案.docx
原创力文档

文档评论(0)