Reputation: 172
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
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
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
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
, orvirtual
.
(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