用于实现不可拷贝/不可移动类型的最小继承类是什么?
如何实现不可拷贝、不可移动的资源管理类(符合0/3/5规则)
你找对路子了!要创建管理不可拷贝/移动资源的类,继承你定义的NOCOPYNOMOVE基类是非常简洁且符合0/3/5规则的最优方案之一,而且这确实是最小化的实现方式——我们只需要精准禁用掉拷贝和移动相关的四个特殊成员函数就足够了。
你的实现思路完全正确
先拆解下你的代码逻辑:
- 基类
NOCOPYNOMOVE通过= delete显式禁用了拷贝构造函数、移动构造函数、拷贝赋值运算符、移动赋值运算符这四个核心函数,从根源上阻断了拷贝/移动的可能。 - 子类
Foo以private方式继承该基类,这样外部代码无法直接访问基类的这些成员,同时因为基类的拷贝/移动函数被禁用,编译器也不会为Foo自动生成这些函数——完美避免了意外的拷贝或移动操作。
可以做的小优化(更严谨的设计)
如果你想让基类的设计更严谨,防止被意外直接实例化,可以把基类的构造和析构函数设为protected:
class NOCOPYNOMOVE { protected: // 只允许子类调用构造/析构 NOCOPYNOMOVE() = default; ~NOCOPYNOMOVE() = default; public: NOCOPYNOMOVE(NOCOPYNOMOVE &v) = delete; NOCOPYNOMOVE(NOCOPYNOMOVE &&v) = delete; NOCOPYNOMOVE& operator=(NOCOPYNOMOVE &r) = delete; NOCOPYNOMOVE& operator=(NOCOPYNOMOVE &&r) = delete; };
这样NOCOPYNOMOVE只能作为基类被继承,不能直接创建对象,更贴合它作为"禁止拷贝移动标记"的设计意图。
为什么这符合0/3/5规则?
0/3/5规则的核心是:如果显式定义了析构、拷贝构造、拷贝赋值中的任意一个(3个),或者C++11后新增的移动构造、移动赋值中的任意一个(总共5个),编译器就不会自动生成其他未显式定义的特殊成员函数。
你的实现直接禁用了拷贝/移动相关的四个函数,相当于明确告诉编译器:这个类不需要拷贝和移动语义。子类如果没有自己定义这些函数,编译器也会因为基类的限制而无法为子类生成——完全符合规则要求,从根本上避免了因编译器自动生成函数而导致的资源错误拷贝/移动问题。
最终结论
你给出的Foo类实现是完全可行的,继承NOCOPYNOMOVE后,Foo的对象既不能被拷贝,也不能被移动,完全满足管理不可拷贝移动资源的需求。
内容的提问来源于stack exchange,提问作者Josu Goñi
相关产品推荐
相关产品推荐

