通常你不希望class支持某一特定机能,只要不声明对应函数就可以达到目的。可是这个策略对copy构造函数和copy assignment操作符却不起作用,因为如果你不为某个class声明这两个函数,即你不想这个class的对象有这两个功能(如下面的代码所示),
class HomeForSale {...}; //一个类你不希望它的一个对象可以copy构造另一个对象或赋值给另一个对象
HomeForSale h1; //在这个类中没有声明copy构造函数和copy assignment操作符函数
HomeForSale h2;
HomeForSale h3(h1); //企图拷贝h1---不该通过编译
h1 = h2; //企图拷贝h2---也不该通过编译
可是当你的程序使用这个类的copy构造函数或copy assignment操作符,编译器会自动生成相应的代码(见上次笔记)。这个不是我们希望看到的。有两个办法可以达到通知编译器的不自动生成这些代码的作用:
1,你自己声明copy构造函数和copy assignment操作符函数,而不用给出它们的定义式,同时把它们声明为private。
这样有两个目的:1) 你的编译器不会自动给你生成相应的函数,因为你已经声明了。 2) 因为它们是私有的,所以类的对象不能调用它们。这样达到了我们的目的。如果类的member函数和friend函数调用了上面的函数,编译器会给出一个连接错误(linkage error),这个方法被C++ iostream程序库使用。即标准程序库中ios_base,basic_ios等类中的copy构造函数和copy assignment操作符函数被声明为private。
例子如下:
class HomeForSale{
public:
....
private:
....
HomeForSale(const HomeForSale&); //只有声明 并且为private
HomeForSale& operator=(const HomeForSale&); //只有声明 并且为private
};
2,设计一个禁止copy操作的基类,把上面的声明移到这个基类中。其它的类继承这个类就可以了
好处:可以把上面提到的连接错误转移到编译期(这个是好事,毕竟愈早侦测出错误愈好)
基类代码:
class Uncopyable {
protected:
Uncopyable() {}
~Uncopyable() {} //允许derived对象构造和析构
private:
Uncopyable(const Uncopyable&); //只声明不实现
Uncopyable& operator=(const Uncopyable&);
};
这防止HomeForSale对象被拷贝,唯一要做的就是继承这个类
class HomeForSale : private Uncopyable { .... }; //这个类中不用再声明copy构造函数和copy assignment操作符函数
总结:
为驳回编译器自动提供的机能,可将相应的成员函数声明为private并且不予实现,也可以使用像Uncopyable这样的base class。
Effective C++读书笔记之若不想使用编译器自动生成的函数,就该明确拒绝
最新推荐文章于 2023-05-25 14:21:24 发布