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

时间:2019-06-14 21:15:02

标签: c++ c++11 destructor

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

  

decl-specifier-seq -朋友,内联,虚拟或无(无返回类型)

     

...

     

在命名空间范围内或在不同类中的 friend 声明中...

朋友破坏者的概念对我来说绝对没有意义,而且我在实践中从未见过。我希望有人能解决这个问题,并解释为什么析构函数将拥有朋友说明符,以及它的外观。

3 个答案:

答案 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 ({如果有)应为friendinline,或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方便使用的原因。