【问题标题】:You can 'promote' access specification through inheritance, can you ever 'demote' access specification?您可以通过继承“提升”访问规范,您可以“降级”访问规范吗?
【发布时间】:2011-07-29 01:56:02
【问题描述】:

“提升”是指使访问限制更严格,“降级”是指限制更少。

例如,当 class B 使用 : protected: privateclass A 派生时,A 的公共成员将分别提升为受保护和私有。

是否可以有一些class C 进来并从class B 派生出自己,同时将A 类的继承成员降级回其原始访问规范?

【问题讨论】:

  • 我觉得你对“promote”和“demote”的使用应该互换。
  • 你一定是个嬉皮士,认为减少限制是一种提升:)

标签: c++ inheritance


【解决方案1】:

如果您使用protected 派生,则C 类确实可以通过创建适当的包装器来访问受保护的成员:

class A {
public:
  void F();
};

class B : protected A { };

class C : public B {
public:
  using B::F;
};

这也可以用于数据成员:

class A {
public:
  int n;
};

class B : protected A { };

class C : public B {
public:
  using B::n;
  C() : n(this->B::n) { }
};

使用private 继承,这是不可能直接实现的,因为C 本身不能访问A 中的成员。但是,如果B 是使用private virtual 继承从A 派生的,则它再次成为可能:

class A {
public:
  void F();
};

class B : private virtual A { };

class C : public B, public virtual A { };

int main() {
  C x;
  x.F();
  return 0;
}

这是可行的,因为使用virtual 继承,C 可以直接从A相同实例派生为B,但使用不同的访问说明符。

【讨论】:

  • 好的,我正在努力理解您的精彩答案。对于受保护的情况,它有效!超级酷的包装纸。我什至将课程A 更改为class A { protected: void F(); };,然后您仍然可以拨打c.F(),但您不能拨打a.F(),我认为这非常有趣且很棒。将其设为私有会扼杀乐趣。你能得到同样的技巧来处理数据吗?我想您需要某种包装器,因此当您尝试获取该值时,您总是最终会调用一个函数并需要()?仍在努力理解答案的虚拟部分...
  • @Jimmy,添加数据成员示例
  • 那太好了。就像函数部分一样工作(并且 protected 在 A 类中保持受保护)。最糟糕的是,我想我完全明白了。就像C班对世界说“不,宝贝,不。我不是C班。我是B班。我保证我会温柔的。” ......或类似的东西......所以你能让它跳上两层吗?我对链式作用域解析运算符从来没有过好运气。
  • using A::F; 比编写包装函数或添加引用成员要简单得多。
【解决方案2】:

using 声明可以访问受保护基类的公共或受保护成员:

struct A {int x;};
struct B : protected A {};

struct C : B
{
    using A::x;  // publicly accessible
}

显然,C 无法使用私有成员和基类,因此您无法减少对它们的限制。

【讨论】:

    【解决方案3】:

    当然不是,如果我可以创建另一个派生类来消除中间类的访问限制并使所有内容都变为public,那么拥有privateprotected 继承又有什么意义?

    【讨论】:

    • 在问我的问题之前,我实际上考虑过这一点……起初我只是想通过将它们公开来把它们吹走,但后来我更深入地考虑将私人的东西重新保护起来。我认为那会很有趣。我猜对我来说太糟糕了。
    • 出于类似的原因,有些人更普遍地反对(也许我同意)受保护的方法。您始终可以制作一个包装器,以新名称公开相同的功能。
    【解决方案4】:

    。 因为,当class C 派生class B;它不知道class A 的原始访问说明符。它只是尊重class B 中的访问说明符。

    【讨论】:

      猜你喜欢
      • 2010-09-25
      • 2017-01-23
      • 1970-01-01
      • 2018-11-23
      • 1970-01-01
      • 2017-11-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-27
      相关资源
      最近更新 更多