删除构造函数的访问控制是否重要?不同权限的显式删除构造函数行为有差异吗?
嘿,这个问题问到点子上了——很多人会忽略删除函数和访问控制的交互细节,我来给你掰扯清楚:
问题1:访问控制对已删除的构造函数是否有影响?
首先得明确一个核心点:已删除的构造函数仍然是类的成员函数,只是被标记为“禁止调用”。访问控制(public/protected/private)不会改变“它不能被调用”这个最终结果,但会影响编译器在不同作用域下的检查逻辑和报错信息。
简单说:访问控制不影响“删除”本身的效果,但会影响编译器什么时候告诉你“不能用”——是先拦在权限这一步,还是直接告诉你函数被删了。
问题2:显式删除的构造函数设为不同访问权限时,行为有差异吗?
有差异,但差异只体现在编译器报错的时机和错误内容上,最终结果都是“这个构造函数完全没法用”。我拿最常见的拷贝构造函数举例:
- 外部代码(非友元、非子类)调用时:
- 如果删除的构造函数是
private/protected:编译器会先触发访问权限检查失败,报错内容类似“无法访问类的私有成员”,根本不会提到“函数已删除”。 - 如果是
public:编译器直接报错“尝试调用已删除的函数”。
- 如果删除的构造函数是
- 子类内部调用时:
- 如果父类的删除构造函数是
protected:子类能通过访问权限检查,但随后会因为“函数已删除”报错。 - 如果是
private:子类连访问权限这关都过不了,直接报权限错误。
- 如果父类的删除构造函数是
- 友元调用时:
- 友元不受访问权限限制,所以不管是
private还是protected的删除构造函数,友元调用时都会直接报“尝试调用已删除的函数”,和public的情况一致。
- 友元不受访问权限限制,所以不管是
给你看个代码实例更直观:
// 私有删除拷贝构造 class PrivateDelete { private: PrivateDelete(const PrivateDelete&) = delete; }; // 公有删除拷贝构造 class PublicDelete { public: PublicDelete(const PublicDelete&) = delete; }; // 子类测试 class Derived : public PrivateDelete { public: void copyTest() { PrivateDelete obj; PrivateDelete obj2 = obj; // 报错:无法访问私有构造函数 } }; int main() { PrivateDelete p; PrivateDelete p2 = p; // 报错:无法访问私有成员 PublicDelete pub; PublicDelete pub2 = pub; // 报错:调用已删除的函数 return 0; }
总结一下
不管你把删除的构造函数设成什么访问权限,它都不可能被成功调用——这是核心。唯一的区别就是不同作用域下,编译器报错的原因描述不一样,但最终都是阻止你使用这个构造函数。
内容的提问来源于stack exchange,提问作者Danra
相关产品推荐
相关产品推荐

