私有继承,返回引用基类的静态成员

时间:2017-09-29 10:14:55

标签: c++ private-inheritance

我有一个关于从私有继承基类的类继承的简单问题,即我们有

class Base {};
class Heir: private Base {};
class HeirsHeir : public Heir {};

了解HeirsHeir无法访问“其”基地的任何内容。特别是,它不能有一个方法返回'基地&'参考自己。但是为什么它不能返回对另一个 Base对象的引用?那么为什么以下代码无法编译:

class Base {};
class Kid : private Base {};
Base instance;
class Grandkid : public Kid
{
    const Base &GetInstance  () const
    { return instance; }
};

至少我的编译器(MinGW 5.3,即Windows的gcc)给出了

error 'class Base Base::Base' is inaccessible at {}; 
error: within this context const Base &getInstance () const

根据我的理解,这没有意义,因为我此时不调用Base的构造函数,而是返回一个引用(到Base实例)。

请注意,可以使用

修复错误
const ::Base &GetInstance  () const
{ return instance; }

肯定与C ++03§11.2/ 3有关(见[C++ private inheritance and static members/types

  

注意:私有基类的成员可能无法访问   继承成员名称,但可以直接访问。

但我不明白为什么这是必要的。有人可以解释一下吗?

由于

克里斯

2 个答案:

答案 0 :(得分:2)

名称查找查找注入到Base的注入类名Base(因此由GrandKid继承)。这是正确的,因为inject-class-name的范围比类的命名空间范围更接近。但是,GrandKid无法访问此注入类名称,因为它在Kid中是私有的。

在编译器的错误消息中,Base::Base不引用构造函数,而是引用注入Base的类名Base。请注意,当使用它的上下文强制将名称解释为类型时,您实际上可以合法地使用Base::Base,就像在此有效但 vile 代码中一样:

class Foo {};

std::vector<Foo::Foo::Foo::Foo> v;

[Live example]

但是,当使用Base::Base的上下文允许引用函数时,它将被解析为构造函数而不是类名(C ++ 11 [class.qual] 3.4)。 3.1 / 2)

答案 1 :(得分:0)

我认为编译器无法识别Base是一个类名,并将其识别为您想要访问Base成员。

这也编译:

class Base {};
class Kid : private Base {};
Base instance;
class Grandkid : public Kid
{
    const class Base &GetInstance  () const
    { return instance; }
};

错误的用法是使用这样的东西:

class Base {
public:
    struct BaseStruct { int a; };
};
class Kid : private Base {
public:
    struct KidStruct { int a; };
};
Base instance;
class Grandkid : public Kid
{
    const class Base &GetInstance  () const
    { return instance; }

    const Kid::KidStruct kidStruct;
    const Base::BaseStruct baseStruct;
};

kidStruct没有错误,因为继承是公开的,但baseStruct无法访问。