为什么C ++不允许继承友谊? [英] Why does C++ not allow inherited friendship?

查看:186
本文介绍了为什么C ++不允许继承友谊?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么友谊至少在C ++中是可以继承的?我明白传递性和反身性被明显的原因禁止(我说这只是为了摆脱简单的常见问题报价答案),但缺乏一些沿着虚线朋友类Foo; 困惑我。有没有人知道这个决定背后的历史背景?

Why is friendship not at least optionally inheritable in C++? I understand transitivity and reflexivity being forbidden for obvious reasons (I say this only to head off simple FAQ quote answers), but the lack of something along the lines of virtual friend class Foo; puzzles me. Does anyone know the historical background behind this decision? Was friendship really just a limited hack that has since found its way into a few obscure respectable uses?

编辑澄清:我在说话关于以下场景,不是,其中A的孩子暴露于B或B和它的孩子。我也可以想象可选地允许访问朋友函数的覆盖等。

Edit for clarification: I'm talking about the following scenario, not where children of A are exposed to either B or to both B and its children. I can also imagine optionally granting access to overrides of friend functions, etc.

class A {
  int x;
  friend class B;
};

class B {
  // OK as per friend declaration above.
  void foo(A& a, int n) { a.x = n; }
};

class D : public B { /* can't get in A w/o 'friend class D' declaration. */ };

接受的回答 Loki状态,效果可以通过在受欢迎的基类中创建受保护的代理函数,因此没有严格的需要用于将友谊授予类或虚拟方法父类。我不喜欢样板代理(有兴趣的基础有效地成为)的需要,但我认为这被认为比一个更可能在大多数时间被滥用的语言机制更可取。我认为这可能是我购买和阅读Stroupstrup的 C ++的设计和发展 ,我已经看到足够的人在这里推荐,以获得更好的洞察这些类型的问题...

Accepted answer: as Loki states, the effect can be simulated more or less by making protected proxy functions in friended base classes, so there is no strict need for granting friendship to a class or virtual method heirarchy. I dislike the need for boilerplate proxies (which the friended base effectively becomes), but I suppose that this was deemed preferable over a language mechanism that would more likely be misused most of the time. I think it's probably time I bought and read Stroupstrup's The Design and Evolution of C++, which I've seen enough people here recommend, to get better insight to these types of questions ...

推荐答案

因为我可能写Foo和它的朋友Bar(因此有一个信任关系)。

Because I may write Foo and its friend Bar (thus there is a trust relationship).

但我相信写的是从Bar派生的类的人。

不是真的。因此,它们不应继承友谊。

But do I trust the people who write classes that are derived from Bar.
Not really. So they should not inherit friendship.

对类的内部表示进行任何更改都需要对依赖于该表示的任何内容进行修改。因此,类的所有成员以及类的所有朋友将需要修改。

Any change in the internal representation of a class will require a modification to anything that is dependant on that representation. Thus all members of a class and also all friends of the class will require modification.

因此,如果Foo的内部表示被修改,那么Bar也必须被修改(因为友谊牢牢地绑定了Bar too foo)。如果友谊继承,那么从Bar派生的所有类也将紧紧绑定到Foo,因此如果Foo的内部表示改变,则需要修改。但我不知道派生类型(也不应该我们。他们甚至可以由不同的公司开发等)。因此,我将无法更改Foo,因为这样做会将破坏性的更改引入代码库(因为我不能修改从Bar派生的所有类)。

Therefore if the internal representation of Foo is modified then Bar must also be modified (because friendship tightly binds Bar too foo). If friendship was inherited then all class derived from Bar would also be tightly bound to Foo and thus require modification if Foo's internal representation is changed. But I have no knowledge of derived types (nor should I. They may even be developed by different companies etc). Thus I would be unable to change Foo as doing so would introduce breaking changes into the code base (as I could not modify all class derived from Bar).

是继承的,你无意中引入了对修改类的能力的限制。这是不可取的,因为你基本上没有公开的API的概念。

Thus if friendship was inherited you are inadvertently introducing a restriction on the ability to modify a class. This is undesirable as you basically render usless the concept of a public API.

注意:Bar的孩子可以通过使用Bar访问Foo。只是使方法在Bar保护。那么Bar的孩子可以通过调用父类来访问Foo。

Note: A child of Bar can access Foo by using Bar. just make the method in Bar protected. Then the child of Bar can accesses a Foo by calling through its parent class.

这是你想要的吗?

class A
{
    int x;
    friend class B;
};

class B
{
    protected:
       // Now children of B can access foo
       void foo(A& a, int n) { a.x = n; }
};

class D : public B
{
    public:
        foo(A& a, int n)
        {
            B::foo(a, n + 5);
        }
};

这篇关于为什么C ++不允许继承友谊?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆