有了私有继承,什么时候可以上传?

时间:2018-03-10 10:47:26

标签: c++ inheritance

我对C ++的私有继承有疑问。 请参阅以下代码示例:

#include <iostream>

class Foo {
  public:
    virtual void doSomething(int value) {
      std::cout << value << std::endl;
    }

};

void foobar(Foo& foo, int value) {
  foo.doSomething(value);
}

class Bar : Foo {
  public:
    Bar() {
      foobar(*this, 42);  // <--- is OK despite private inheritance
    }
};

int main() {
  Bar b;
  foobar(b, 42); // <--- is NOT OK because of private inheritance
}

目前,我无法理解(或找到正确的C ++规范)为什么可以在foobar的{​​{1}}构造函数中调用函数Bar }} 尽管有私有继承。 如果我尝试在*this函数中使用foobar对象Bar调用b函数,则由于私有继承,编译器会按预期给出错误。

我忽略了mainfoobar(*this, 42)之间的区别是什么?

3 个答案:

答案 0 :(得分:2)

这一切都来自foobar收到Foo并且不知道Bar(私有地)继承自Foo的事实。这个特性由来电者处理:

  • Bar的内部构造函数中,为了使用foobar致电*this,需要进行转换;具体而言,类型*this的{​​{1}}需要转换为Bar,这是可能的,因为调用者知道两种类型之间的继承关系。< / LI>
  • Foo&范围之外的main()范围内,对class Bar foobar b类型Bar的调用也需要转换。但在这种情况下,BarFoo之间的关系是未知的,并且无法进行转换。

私有继承意味着只有派生类型知道此继承。在它的范围内,一切都好像是公共继承。但是在派生类型的范围之外,这种关系是未知的,并且一切都发生好像根本没有继承。

答案 1 :(得分:0)

当您私下继承时,您将为派生类将所有基类的公共成员和受保护成员设为私有。因此Bar可以使用自己的私有方法以及其私有基类的公共和受保护方法。但他们的私人仍然无法通过Bar的公共界面访问它们。

  

14.2 基类的可访问性和基类成员 [class.access.base]
  ...如果使用私有访问说明符将类声明为另一个类的基类,则基类的公共成员和受保护成员可作为派生类的私有成员访问。
  ...
  应该注意的是,它可以访问受控制的成员和基类,而不是它们的可见性。名称   成员仍然可见,并且当这些成员和基类不可访问时,仍会考虑对基类的隐式转换。建立对给定构造的解释而不考虑   访问控制。如果建立的解释使用了不可访问的成员名称或基类,则该构造是不正确的。

答案 2 :(得分:0)

问题归结为其他问题:私有继承是什么意思?。 这意味着,在简化单词时,除了继承类之外,没有人知道继承发生了。所以直到你的例子 - Bar 知道它是从Foo派生的,所以在构造函数中没有任何麻烦的向上转换。另一方面,main不是继承Bar的一部分,因此无法隐式地将Bar强制转换为Foo

相关问题