看过Effective C++的人都知道,为了防止一个class被copying,而且将错误提前到编译期,基本有两种方法:
1. 将这个类的copy构造函数和copy assignment操作符都声明为private而且没有定义。示例代码如下:
1 class SomeClass {
2 ...
3 private:
4 //只有声明
5 SomeClass(const SomeClass&);
6 SomeClass& operator=(const SomeClass&);
7 };
2. 专门设计一个为了阻止copying动作而设计的base class,这个base class相当简单:
1 Uncopyable {
2 protected: //允许derived对象构造和析构
3 Uncopyable() {}
4 ~Uncopyable() {}
5 private: //阻止copying
6 Uncopyable(const Uncopyable&);
7 Uncopyable& operator=(const Uncopyable&);
8 };
为了阻止某个对象如SomeClass被copying,我们唯一需要做的就是继承自Uncopyable:
1 SomeClass : private Uncopyable {
2 ...
3 };
第2种方案貌似很完美,在大多数情况下也工作的很好,甚至boost库也广泛采用了(boost库中的叫noncopyable)。当然了,因为Uncopyable不含任何数据,符合EBO(empty base class optimization,空白基类最优化)资格,但由于它总是扮演base class,因此有可能导致多重继承,而EBO一般只在单继承下才可行,编译器通常不会对有多个base class的derived classes施行EBO。
如果你不想导致多重继承,不管是从性能上还是书写代码上,比如SomeClass继承自某个base class,你可能会写如下代码:
1 class SomeClass : public BaseClass, private Uncopyable {
2 ...
3 };
这让人很不爽,要是你跟我一样懒,你肯定也不会愿意采用第一种方案,因为那意味着你会在每一个不想被copying的class里都加上那三行代码。
如果用Macro就很简单了,即灵活又方便:
1 #define CLASS_UNCOPYABLE(classname) \
2 private: \
3 classname(const classname&); \
4 classname& operator=(const classname&);
现在SomeClass只需写成这样:
1 class SomeClass {
2 CLASS_UNCOPYABLE(SomeClass)
3 ...
4 };
不仅省事而且灵活!!!