开发者

C++ Friendship and inheritance [closed]

开发者 https://www.devze.com 2023-04-05 07:20 出处:网络
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references,or expertise, but this question will likely solicit debate, a
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance. Closed 11 years ago.

I know that friendship is not inherited. I was asking myself: why? Why the C++ designers decided to not let friendship be inherited? Do you find that friendship inheritance would be a useful thing to have? My own answer is yes: in the same way that B is a friend of A, i would like to make a whole family of classes be friend of A (B and its derivatives). Maybe, one should be able to say: let only B be friend of A or let B and its derived classes be friend of A.

Ps. I don't know why many of you thought that i was asking for automatic extension of f开发者_开发百科riendship. I was interested more in the possibility for the programmer to extend friendship to a whole family using some mechanism (not automatically).


A friend declaration creates a strong relationship between the Friendly and the Trusting:

  • it ties down the Friendly to the representation of the Trusting since it's got full access to its internals
  • it means that the Friendly swears to uphold the class invariants of the Trusting

Therefore it seems good practice to make sure to clearly identify the exact scope, something that inheritance would not achieve: there would be a leak.

The truth is though, that inheritance should not even be necessary. There are actually two alternatives, depending on what friendship is trying to achieve. They cover any scenario I ever come across.

Friendly as a Proxy

In your example, derivates of Friendly can simply reach into Trusting through Friendly, thus letting you control the operations that occur on Trusting in a limited set of places.

class Trusting { friend class Friendly; };

class Friendly { protected: void modifyTrusting(); };

The implementation of modifyTrusting might imply virtual calls (hooks) to customize the behavior, but regardless of those hooks it is up to Friendly to ensure that the class invariants are not broken.

Not so Trusting

In this case, Trusting opens up only part of its interface, through a locked method, and grants the key to Friendly. Friendly might alternatively grant the key to the classes in which it trusts, but it does not really matter... In any case Trusting ensures itself that its invariants are not broken, and the key is just a mechanism to reduce the exposure of the method.

class Key { friend class Friendly; Key() {} ~Key() {} };

class Trusting { public: void doSomething(Key const&); };

class Friendly { protected: Key const& key() const; };

I must admit that I am really partial to this latter method and use it regularly, because it limits the exposure of Friendly to the implementation details of Trusting. It also clearly documents which parts of Trusting our dear Friendly access.


I saw an amusing bumper sticker yesterday: "My mother-in-law is a travel agent ... for guilt trips". Friendship is inherited to some extent in human relationships. While this does lead to interesting jokes about an SOs friends and family, it is important to remember that misery and suffering are the basis for many jokes.

Friendship is not inherited in C++ because the developers foresaw the amount of misery and suffering this would cause.


This is a terrible idea.

Friendship is not inherited because friendship causes a tight coupling between friends. If all the derived class were also automatically friends then this would cause a tight binding between the original object and all inherited classes.

Tight coupling is fine for classes that are created and maintained together. But for classes that are created by other users tight coupling would cause a maintenance nightmare and prevent you from ever changing the original object (because all your tightly coupled friends depend on your implementation).

0

精彩评论

暂无评论...
验证码 换一张
取 消