Ian
Ian

Reputation: 172

What is a destructor with the friend specifier?

I was browsing the cppreference page about destructors, and noticed two places which seem to indicate the existence of a friend destructor.

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

...

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

The concept of a friend destructor makes absolutely no sense to me, and I have never seen this in practice. I was hoping somebody could clear this up and explain why a destructor would ever have the friend specifier, and what that would even look like.

Upvotes: 3

Views: 804

Answers (3)

1201ProgramAlarm
1201ProgramAlarm

Reputation: 32742

You should look at the description for id-expression below decl-specifier-seq. You can declare a destructor for another class as a friend.

class AClass;

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

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

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

In this contrived example, without the friend declaration, classB would not be able to destroy the contained AClass object.

All of the usual benefits of friendship - like being able to access private and protected members of the class - would also apply, so this would allow the destructor for classB to access any private or protected member of AClass.

Upvotes: 5

Oblivion
Oblivion

Reputation: 7374

To add the answers already given from design perspective:

Any time you want some other class to be responsible for the life cycle of your class' objects (A), or to prevent the destruction of an object, the dtor must be private.

A private dtor would prevent anybody else from deleting it except for the responsible class. The deleter method or dtor of responsible class now has to be friend of class A to have access to that private dtor.

use cases are reference counting or managing connection to a data base. so the responsible class will take a request to delete/disconnect your object and will decide accordingly.

This is why a friend dtor is handy.

Upvotes: 0

Brian Bi
Brian Bi

Reputation: 119239

According to the standard ([class.dtor]/1), you are allowed to use the keyword friend when declaring a destructor:

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

(Note: in C++20, you will also be able to declare destructors constexpr.)

However, you can't just take an ordinary destructor declaration in its class and add friend, e.g.,

struct S {
    friend ~S();
};

This doesn't work because (I believe, but can't find the standard quote to back it up right now) when you declare a function a friend, the compiler will look up the name in the containing namespace and, if it doesn't find it there, will make the function a member of that namespace.

However, something like this is perfectly valid:

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

This allows S's destructor to access private members of T, as you would expect.

Upvotes: 0

Related Questions