tags:

views:

1090

answers:

5

In C++, I have a class A which is friend with a class B.

I looks like inherited classes of B are not friend of class A.

I this a limitation of C++ or my mistake ?

Here is an example. When compiling, I get an error on line "return new Memento":

Memento::Memento : impossible to access private member declared in Memento.

class Originator;

class Memento
{
  friend class Originator;

  Memento() {};

  int m_Data;

public:
  ~Memento() {};
};

class Originator
{
public:
  virtual Memento* createMemento() = 0;
};

class FooOriginator : public Originator
{
public:
  Memento* createMemento()
  {
    return new Memento; // Impossible to access private member of Memento
  }
};

void main()
{
  FooOriginator MyOriginator;
  MyOriginator.createMemento();

}

I could of course add FooOriginator as friend of Memento, but then, this means I would have to add all Originator-inherited classes as friend of Memento, which is something I'd like to avoid.

Any idea ?

+6  A: 

Friendship is not inherited, you have to explicitly declare every friend relationship. (See also "friendship isn't inherited, transitive, or reciprocal")

sth
A: 

The friend directive was originally intended as some "loophole" to bypass the encapsulation mechanism.

With friend you have to specify exactly(!), which classes are your friend. The friendship is not inherited and so FooOriginator has no access to Memento in your example.

But ideally, before you're thinking how to solve your problem with the friend directive, I'd suggest to have a look at your design in general and try to get rid of the need to use friend as it could be seen to live in the same category as our loved goto :)

Kosi2801
I wouldn't say that friend is as bad as goto. It may even improve the encapsulation when you can use it to slim the public interface. However, such cases are seldom, and too many friends destroy your private life.
gimpf
friend is not bad. it's toenhance encapsulation within a logically group of two or more classes that belong together, but can't be made into a module because there are none (and no module level protection): instead you use friend in C++ instead of internal or package level protection in java.
Johannes Schaub - litb
but i think it's like goto too: goto isn't bad either. but before you do something else, and rape your code with endless of condition variables and clutter the scope with them, you just use one goto and keep your code clean. the same can be said in principle of friendship, i believe.
Johannes Schaub - litb
but i'm with you gimpf, friend - as goto - should be wisely used and carefully applied.
Johannes Schaub - litb
A: 

Friendship is not inherited, see http://www.cplusplus.com/doc/tutorial/inheritance.html, What is inherited from the base class?

Patrick
A: 

See: http://stackoverflow.com/questions/437250/friend-scope-in-c/437507
Voted exact duplicate.

I looks like inherited classes of B are not friend of class A.

Correct

I this a limitation of C++ or my mistake ?

It is the way C++ works. I don't see it as a limitation.

Martin York
I agree, it's a duplicate.
Jérôme
A: 

Friendship isn't transitive or inherited. After all, your friend's friend may not be your friend or your father's friends are not your friends in general.

Tanveer Badar