什么是友元说明符的析构函数?
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-seq 对 id-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
很方便的原因。
我在浏览 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-seq 对 id-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
, orvirtual
.
(注意:在 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
很方便的原因。