什么是友元说明符的析构函数?

What is a destructor with the friend specifier?

我在浏览 cppreference page about destructors,发现有两个地方似乎表明存在友元析构函数。

decl-specifier-seq - friend, inline, virtual, or nothing (no return type)

...

At a namespace scope or in a friend declaration within a different class...

朋友析构函数的概念对我来说完全没有意义,而且我在实践中从未见过。我希望有人能解决这个问题并解释为什么析构函数会有友元说明符,甚至会是什么样子。

您应该查看下面 decl-specifier-seqid-expression 的描述。你可以为另一个 class 作为朋友声明一个析构函数。

class AClass;

class classB {
public:
    AClass *a;
    ~classB();
};

class AClass {
    friend classB::~classB();
    ~AClass();
};

classB::~classB() {
     delete a;
}

在这个人为的例子中,如果没有 friend 声明,classB 将无法销毁包含的 AClass 对象。

友谊的所有常见好处 - 例如能够访问 class 的私有成员和受保护成员 - 也适用,因此这将允许 classB 的析构函数访问任何私有成员或 AClass.

的受保护成员

根据标准([class.dtor]/1),在声明析构函数时允许使用关键字friend

Each decl-specifier of the decl-specifier-seq of a destructor declaration (if any) shall be friend, inline, or virtual.

(注意:在 C++20 中,您还可以声明析构函数 constexpr。)

但是,您不能只在其 class 中采用普通的析构函数声明并添加 friend,例如

struct S {
    friend ~S();
};

这是行不通的,因为(我相信,但现在找不到标准的引用来支持它)当你声明一个函数为友元时,编译器将在包含的命名空间中查找名称并且,如果在那里找不到它,将使该函数成为该命名空间的成员。

然而,这样的事情是完全有效的:

struct S { ~S(); };
struct T {
    // ...
    friend S::~S();  // this is also a declaration of S's destructor
};

这允许 S 的析构函数访问 T 的私有成员,如您所料。

添加已经从设计角度给出的答案:

任何时候您希望其他 class 在您的 class' 对象 (A) 的生命周期中成为 responsible,或防止破坏对象,dtor 必须是私有的。

私有 dtor 会阻止除 responsible class 之外的任何人删除它。负责 class 的 deleter 方法或 dtor 现在必须是 class A 的好友才能访问私有 dtor

用例是引用计数或管理与数据库的连接。因此 responsible class 将向 delete/disconnect 您的对象提出请求并做出相应决定。

这就是 friend dtor 很方便的原因。