C++友谊与传承
我知道友谊不是遗传的。我问自己:为什么?为什么C++设计者决定不让友谊被继承?你觉得友谊传承有用吗?我自己的答案是肯定的:就像 B 是 A 的朋友一样,我想让整个类家族成为 A 的朋友(B 及其衍生物)。也许,人们应该能够说:让仅 B 成为 A 的友元,或者让 B 及其派生类成为 A 的友元
。 我不知道为什么你们很多人认为我是在要求自动延长友谊。我更感兴趣的是程序员是否可以使用某种机制(不是自动的)将友谊扩展到整个家庭。
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 friendship. I was interested more in the possibility for the programmer to extend friendship to a whole family using some mechanism (not automatically).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
friend
声明在Friendly和Trusting之间创建了牢固的关系:因此,确保清楚地确定确切的范围似乎是一种很好的做法,这是继承无法实现的:会出现泄漏。
但事实是,继承甚至不是必需的。实际上有两种选择,具体取决于友谊想要实现的目标。它们涵盖了我遇到过的任何场景。
Friendly 作为代理
在您的示例中,
Friendly
的派生体可以简单地访问Trusting
通过Friendly
,从而让您可以在一组有限的位置控制Trusting
上发生的操作。modifyTrusting
的实现可能意味着虚拟调用(挂钩)来自定义行为,但无论这些挂钩如何,都需要Friendly
来确保类不变量不会被破坏。并非如此Trusting
在这种情况下,
Trusting
通过锁定的方法仅打开其界面的一部分,并将密钥授予友好。
Friendly
也可以将密钥授予它信任的类,但这并不重要......在任何情况下Trusting
确保其不变量不会被破坏,而关键只是一种减少方法暴露的机制。我必须承认,我确实偏爱后一种方法并经常使用它,因为它限制了
Friendly
对Trusting
实现细节的暴露。它还清楚地记录了信任
我们亲爱的友好
访问的哪些部分。A
friend
declaration creates a strong relationship between the Friendly and 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 intoTrusting
throughFriendly
, thus letting you control the operations that occur onTrusting
in a limited set of places.The implementation of
modifyTrusting
might imply virtual calls (hooks) to customize the behavior, but regardless of those hooks it is up toFriendly
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 toFriendly
.Friendly
might alternatively grant the key to the classes in which it trusts, but it does not really matter... In any caseTrusting
ensures itself that its invariants are not broken, and the key is just a mechanism to reduce the exposure of the method.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 ofTrusting
. It also clearly documents which parts ofTrusting
our dearFriendly
access.昨天我看到一个有趣的保险杠贴纸:“我的岳母是一名旅行社......为了罪恶感旅行”。在人际关系中,友谊在某种程度上是遗传的。虽然这确实会引发有关 SO 朋友和家人的有趣笑话,但重要的是要记住,痛苦和痛苦是许多笑话的基础。
在 C++ 中,友谊不是继承的,因为开发人员预见到了这会造成多少痛苦和痛苦。
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).