侧边栏壁纸
博主头像
如此肤浅

但行好事,莫问前程!

  • 累计撰写 52 篇文章
  • 累计创建 6 个标签
  • 累计收到 6 条评论

目 录CONTENT

文章目录

条款06 若不想使用编译器自动生成的函数,就该明确拒绝

如此肤浅
2022-05-14 / 0 评论 / 0 点赞 / 43 阅读 / 980 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-05-15,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

1. 为驳回编译器自动(暗自)提供的机能,可将相应的成员函数声明为 private 并且不予实现。使用像 Uncopyable 这样的 base class 也是一种做法。

问题: 现有一个类,它不希望对它的对象采用拷贝构造拷贝赋值的操作。但如果不声明拷贝构造和拷贝赋值函数,而某些人尝试调用它们,编译器会自动声明它们。如何解决该问题呢?

粗糙地解决: 所有编译器产出的函数都是 public。为阻止这些函数被创建出来,你得自行声明它们,但这里并没有什么需求使你必须将它们声明为public。因此你可以将 copy 构造函数或 copy assignment 操作符声明为private。由此,你阻止了编译器暗自创建其专属版本;而令这些函数为 private,使你得以成功阻止人们调用它。

class HomeForSale {
public:
	...
private:
	...
    HomeForSale(const HomeForSale&);	//只有声明
    HomeForSale& operator=(const HomeForSale&);
}

但若不慎在 member 函数或 friend 函数中调用它们,则会在编译期出错,将问题的发现提前到编译期也是一种好事。

最佳的解决: 继承一个类。

class Uncopyable {
protected:
	Uncopyable() {}	// 允许derived对象构造和析构
    ~Uncopyable() {}
private:
	Uncopyable(const Uncopyable&);	// 但阻止copying
    Uncopyable& operator=(const Uncopyable&);
}

为阻止 HomeForSale 对象被拷贝,我们只需要继承 Uncopyable:

// 该类不再声明copy构造函数和copy assign操作符
class HomeForSale: private Uncopyable {
	...
};

这行得通,因为只要任何人——甚至是 member 函数或 friend 函数——尝试拷贝 HomeForSale 对象,编译器便试着生成一个 copy 构造函数和一个 copy assignment 操作符,而正如条款12所说,这些函数的“编译器生成版”会尝试调用其 base class 的对应兄弟,那些调用会被编译器拒绝,因为其 base class 的拷贝函数是 private。

0

评论区