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

C++ 私有继承,返回对基类静态成员的引用,c++,name-lookup,private-inheritance,C++,Name Lookup,Private Inheritance,我有一个简单的问题,关于从一个私有继承基类的类继承,即 class Base {}; class Heir: private Base {}; class HeirsHeir : public Heir {}; 请理解,HeirsHeir无法访问任何“其”Base。特别是,它不能有一个方法返回对自身的Base&引用。但是为什么它不能返回对另一个基本对象的引用呢?那么,为什么不编译以下代码: class Base {}; class Kid : private Base {}; Base ins

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

class Base {};
class Heir: private Base {};
class HeirsHeir : public Heir {};
请理解,
HeirsHeir
无法访问任何“其”
Base
。特别是,它不能有一个方法返回对自身的
Base&
引用。但是为什么它不能返回对另一个基本对象的引用呢?那么,为什么不编译以下代码:

class Base {};
class Kid : private Base {};
Base instance;
class Grandkid : public Kid
{
    const Base &GetInstance  () const
    { return instance; }
};
至少我的编译器(mingw5.3,即gcc for Windows)给出了

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

请注意,可以使用

const ::Base &GetInstance  () const
{ return instance; }
这肯定与C++03§11.2/3有关(见[)

注意:私有基类的成员可能无法作为 继承了成员名,但可直接访问


但我不明白为什么有必要这样做。有人能解释一下吗?

我认为编译器无法识别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
是不可访问的。

名称查找会找到注入的类名
Base
,该类名被注入
Base
(因此被
GrandKid
继承)。这是正确的,因为注入的类名的作用域比类的命名空间作用域名更近。但是,
GrandKid
无法访问此注入的类名,因为它在
Kid
中是私有的

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

class Foo{};
std::向量v;


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

你知道那一行是如何解析的吗?编译器在该语句中对
Base
赋予了什么意义?好吧,现在我很困惑。为什么它不理解它是类?我可以(多少)理解它不能访问类的定义(然后包括所有方法),但它有助于解释“嘿,这是一个类”?它实际上解析为类名,但解析为注入(且不可访问)的类名。为什么返回中的类确保将其解析为全局作用域?好的(ish),但为什么class Base::Base?@ChrisN询问GCC警告编写者;-)但我猜这意味着
class Base
是问题的类型,
Base::Base
是找到它的名称。好的。最后一个问题。为什么class Base代替von::Base也起作用(见JMA的答案)?这是告诉编译器使用全局作用域还是这只是一个副作用?这两种样式中哪一种更好?@ChrisN从我对标准的阅读来看,
class Base
解决这个问题实际上是GCC中的一个bug。它规定了
class X
查找
X
与查找pl的方式相同ain
X
,但只考虑类型。我同意clang的观点。谢谢你提供的信息!然后我继续使用::Base:-)很抱歉从Base、继承人、继承人切换到父、子、孙,然后再切换回来。。。
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;
};
class Foo {};

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