我有一个关于从私有继承基类的类继承的简单问题,即我们有
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)
注意:私有基类的成员可能无法访问 继承成员名称,但可以直接访问。
但我不明白为什么这是必要的。有人可以解释一下吗?
由于
克里斯
答案 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;
但是,当使用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
无法访问。