我正在浏览cppreference page about destructors,发现有两个地方似乎表明存在一个朋友析构函数。
decl-specifier-seq -朋友,内联,虚拟或无(无返回类型)
...
在命名空间范围内或在不同类中的 friend 声明中...
朋友破坏者的概念对我来说绝对没有意义,而且我在实践中从未见过。我希望有人能解决这个问题,并解释为什么析构函数将拥有朋友说明符,以及它的外观。
答案 0 :(得分:5)
您应查看 decl-specifier-seq 下对 id-expression 的描述。您可以将另一个类的析构函数声明为好友。
<a href="https://docs.google.com/spreadsheets/d/e/2PACX-1vSRapguCiGP6brs8FkzMYbIE8Q6sZRUlzDyqb7uzfDZcDP-6DQYzyiHvViRmn51YPd-sB0s9F3VY8mu/pub?output=tsv" download="static/ExampleAuthorList.tsv"><button type="button" >Download</button></a><br><br>
在这个人为的示例中,如果没有class AClass;
class classB {
public:
AClass *a;
~classB();
};
class AClass {
friend classB::~classB();
~AClass();
};
classB::~classB() {
delete a;
}
声明,friend
将无法销毁所包含的classB
对象。
友谊的所有通常的好处(例如能够访问班级的私有成员和受保护的成员)也将适用,因此这将允许AClass
的析构函数访问{{ 1}}。
答案 1 :(得分:0)
根据标准([class.dtor] / 1),在声明析构函数时,可以使用关键字friend
:
析构函数声明的 decl-specifier-seq 的每个 decl-specifier ({如果有)应为friend
,inline
,或virtual
。
(注意:在C ++ 20中,您还可以声明析构函数constexpr
。)
但是,您不能只在其类中使用普通的析构函数声明并添加friend
,例如
struct S {
friend ~S();
};
这是行不通的,因为(我相信,但是现在找不到标准的引号来备份它)当您将一个函数声明为朋友时,编译器将在包含名称空间中查找名称,如果它在那里找不到它,它将使该函数成为该命名空间的成员。
但是,这样的事情是完全有效的:
struct S { ~S(); };
struct T {
// ...
friend S::~S(); // this is also a declaration of S's destructor
};
这使S
的析构函数可以访问T
的私有成员。
答案 2 :(得分:0)
要添加从设计角度已经给出的答案:
每当您希望某个其他类在您的类的对象(responsible
)的生命周期内成为A
或为了防止对象被破坏时,dtor
必须保密。
私有dtor
会阻止除responsible
类之外的其他任何人删除它。负责任的类的deleter
方法或dtor
现在必须成为类A
的朋友才能访问该私有的dtor
。
用例是引用计数或管理与数据库的连接。因此responsible
类将向您的对象delete
/ disconnect
发出请求并做出相应决定。
这就是friend dtor
方便使用的原因。