@Author:CSU张扬
@Email:csuzhangyang@gmail.com or csuzhangyang@qq.com
@我的网站: https://www.cppbug.com
条款06-若不想使用编译器自动生成的函数,应该明确拒绝
独一无二的对象
“世界上没有两片相同的叶子”,我们定义一个类表示叶子 class Leaf { ... }。显然任何拷贝动作都是不合逻辑的:
Leaf l1;
Leaf l2;
Leaf l3(l1); // 编译不通过
l1 = l2; // 编译不通过
如果我们不声明 拷贝构造函数 和 拷贝赋值运算符,那么编译器会为我们生成一个。所以我们要声明这两个函数,但是我们却不能用。因此我们可以把这两个函数声明为 private。
注意: C++11支持将构造函数声明为 删除的:
Leaf(const Leaf&) = delete;
Leaf& operator=(const Leaf&) = delete;
在编译期间发现错误
上节将拷贝构造函数 和 拷贝赋值运算符声明为 private,但是我们的成员函数和友元函数仍可以调用,这时会产生连接错误。我们要将连接期错误转移到编译期间,我们可以专门为阻止拷贝动作设计一个基类。
class Uncopytable {
protected:
Uncopytable() { }
~Uncopytable() { }
private:
Uncopytable(const Uncopytable&);
Uncopytable& operator=(const Uncopytable&);
};
class Leaf : private Uncopytable {
... ...;
};
此时,以任何形式来拷贝 Leaf 对象,编译器就算给 Leaf 生成了拷贝构造函数,那么这个拷贝动作会调用基类的拷贝构造函数,这会被编译器拒绝。
此代码还有几个微妙的地方:
Uncopytable作为基类,析构函数是non-vitural的。- 继承方式是
private。
总结
- 避免编译器暗自生成的拷贝功能,可以将相应的成员函数声明为
private的。注意:在C++11新标准下,可以直接声明为 删除的。 - 继承像
Uncopytable的基类也是可行的。
本文详细介绍了如何在C++中避免编译器自动生成拷贝构造函数和拷贝赋值运算符,通过声明为private或使用C++11的删除特性,以及设计一个基类Uncopytable来确保在编译期间就能捕获到非法拷贝尝试。
1001

被折叠的 条评论
为什么被折叠?



