带私有析构函数的对象能否按值传递给函数?编译器行为解析
私有析构函数的类按值传递参数的编译器行为分析
问题场景
给定以下代码:
class A { ~A() {} }; // GCC和Clang编译通过,MSVC报错 void f(A) {}
GCC与Clang接受该代码,而MSVC报错:
(6): error C2248: 'A::~A': cannot access private member declared in class 'A'
标准规定与分析
根据C++标准,当自动存储期的对象(比如函数形参)生命周期结束时,必须调用其析构函数,且此时必须能够合法访问该析构函数。
在上述代码中:
- 函数
f的形参是A类型对象,函数执行完毕后形参会被销毁,这一步需要调用A的析构函数。 - 由于
A的析构函数是私有成员,而f既不是A的成员函数也不是友元,完全没有访问该私有析构函数的权限,这违反了C++的访问控制规则。
即使函数f从未被调用,C++标准要求函数定义必须满足语义合法性——形参的销毁逻辑是函数定义的固有部分,编译器需要检查该操作的可行性。
编译器行为结论
MSVC的报错行为符合C++标准的严格要求;而GCC和Clang在函数未被调用时未执行析构函数的访问权限检查,属于宽松实现,并不符合标准规范。
内容的提问来源于stack exchange,提问作者Fedor
相关产品推荐
相关产品推荐

