EffectiveC++详解:条款06-若不想使用编译器自动生成的函数,应该明确拒绝

文章目录

  • 条款06-若不想使用编译器自动生成的函数,应该明确拒绝
    • 独一无二的对象
    • 在编译期间发现错误
    • 总结

@Author:CSU张扬
@Email:[email protected] or [email protected]
@我的网站: 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 生成了拷贝构造函数,那么这个拷贝动作会调用基类的拷贝构造函数,这会被编译器拒绝。

此代码还有几个微妙的地方:

  1. Uncopytable 作为基类,析构函数是 non-vitural 的。
  2. 继承方式是 private

总结

  • 避免编译器暗自生成的拷贝功能,可以将相应的成员函数声明为 private 的。注意:在C++11新标准下,可以直接声明为 删除的。
  • 继承像 Uncopytable 的基类也是可行的。

你可能感兴趣的:(EffectiveC++详解)