12

I recently came across a c++ piece of code where a class is made friend to itself. As I have read on different forums a class is already a friend to itself. So I was wondering if there is a specific reason why one would want to make a class friend to itself explicitly.

Another question would be, what's the reason in making a class a friend of itself?

Maybe someone with a lot of experience can clarify this topic.

Here is the code example, to illustrate my question:

template < typename T>
class Foo: public T
{
protected:
   template < typename U>
   friend class Foo;
}
Deduplicator
  • 44,692
  • 7
  • 66
  • 118
AleC
  • 579
  • 3
  • 7
  • 15
  • Can you show us the code? I can see no purpose (class can already access its own private/protected members, no need for frending self). – firda Aug 07 '14 at 12:28
  • The class being friend to itself is pointless, it would allow the access of private fields which are accessible by the class anyway. – cerkiewny Aug 07 '14 at 12:29
  • possible duplicate of [Access private elements of object of same class](http://stackoverflow.com/questions/3832613/access-private-elements-of-object-of-same-class) – MatthiasB Aug 07 '14 at 12:30
  • possible duplicate of [Making a class friend itself](http://stackoverflow.com/questions/8686342/making-a-class-friend-itself) – cerkiewny Aug 07 '14 at 12:30
  • Might have left after refactoring – Ivan Lebediev Aug 07 '14 at 12:33
  • 1
    The only reasons I can think of are 1) you don't want to spend time on a special case in a code generator, so it will show up in the generated code, or 2) stale code left over from a refactoring, where nobody noticed because the compiler doesn't complain. – molbdnilo Aug 07 '14 at 12:35
  • @molbdnilo I bet it fall in either. You cannot be that incompetent. – UmNyobe Aug 07 '14 at 12:36
  • 1
    "I have read on different forums a class is already a friend to itself." This is false. – John Dibling Aug 07 '14 at 12:37
  • 4
    It is not a friend of itself. Any template instantiation of `Foo` will be a friend of any other one. The crucial detail is that a class template is not a type. – juanchopanza Aug 07 '14 at 12:42
  • @JohnDibling, can you explain why it is false? – AleC Aug 07 '14 at 12:49
  • 3
    @AlexandraC: Because it simply isn't true that a class is a friend of itself. These forums you've been reading might be trying to conflate a friendship relationship with access to the class' `private` members, and while it's true that establishing a friendship relationship does grant this access, that doesn't mean that a class is a friend of itself. – John Dibling Aug 07 '14 at 13:14
  • @JohnDibling, that sounds perfectly logic. +1 – AleC Aug 07 '14 at 13:21

2 Answers2

23

There's no point indeed to make a class a friend to itself, except if it is a template class. For example the following code makes sense:

template <class T>
class A
{
    template<class U>
    friend class A;
}

An STL example is the std::_Ptr_base which is the base class for std::shared_ptr and std::weak_ptr.

rashmatash
  • 1,699
  • 13
  • 23
  • 1
    Templates are a nice observation, since templated classes are different types themselves. However I can't think of a scenario where one template has access to something another template does not. – webuster Aug 07 '14 at 12:42
  • 2
    `std::_Ptr_base` is an implementation detail, not part of the standard. And none of those three have anything to do with the STL. – chris Aug 07 '14 at 13:16
  • @chris, I'm not sure what you mean. STL stands for Standard Template Library and the smart pointers are, as far as I know, part of the STL for C++11. Correct me if I'm wrong, though. – rashmatash Aug 07 '14 at 13:34
  • 2
    @rashmatash, You might read [this](http://stackoverflow.com/questions/5205491/whats-this-stl-vs-c-standard-library-fight-all-about) – chris Aug 07 '14 at 13:36
  • OK thanks. I was reading Stroustrup's book the other day where it implied that the smart pointers where part of standard library. Anyway, I don't see how it would matter for the example at hand. – rashmatash Aug 07 '14 at 14:12
  • @rashmatash, Well, smart pointers are certainly part of the standard library, but the standard library is part of standard C++, and it includes both things like smart pointers and the sections heavily influenced by the STL like containers. The STL existed before C++ was even standardized. Thinking the STL is a subset of the standard library isn't quite correct and won't always work, but it's pretty close. – chris Aug 07 '14 at 14:16
  • @chris, I wasn't quite aware of this distinction. Thanks for pointing that out. – rashmatash Aug 07 '14 at 14:28
  • I'm working on a matrix lib and `matrix` needs friend access to `matrix` in `matrix::operator==` – Nick Jan 21 '17 at 18:27
5

It is not making the class a friend of itself, it is making all classes of that template a friend to all others. So A<Foo> is a friend of A<Bar> which is a different class.

I am surprised the syntax is as you print it and not template<typename U> friend class A<U>; but that is what it actually means.

CashCow
  • 30,981
  • 5
  • 61
  • 92
  • `template friend class A;` because it is incorrect, see https://stackoverflow.com/questions/3313354/template-self-friendship – Liu Hao Dec 04 '17 at 12:14
  • Yes that is the syntax and it's how you create a class but how would it work if my template takes 2 parameters and I want to use one of them in the friendship, so I have class Foo< A, B > and I want to make class Foo< A, anything_else > a friend not Foo types that have a different first template parameter – CashCow Dec 13 '17 at 12:19