当从一个基类继承时,嵌套类会发生什么?

14

假设我有以下这些类:

class Base
{
    public:

        class Foo { ... };

        ...
};

然后另一个类从基类派生出来:

class Derived : public Base
{
    // no mention or redefinition of nested class "Foo" anywhere in "Derived"
};

这是否意味着我们现在有了一个独立的Derived :: Foo,还是Derived :: FooBase :: Foo完全相同?

这种情况的另一个变化是:如果有人抛出Derived :: Foo的实例,那么它会在这种情况下被捕获吗?

catch ( const Base::Foo &ex )
{
    // would this also catch an instance of Derived::Foo?
}
2个回答

10

Derived::Foo只是访问Base::Foo,因此这只是引用同一类型的两种方式。您可以使用std::is_same轻松检查:

#include <type_traits>

struct Base
{
    class Foo {};
};

struct Derived : Base {};

static_assert( std::is_same< Base::Foo, Derived::Foo >::value, "Oops" );

int main()
{
    try {
        throw Derived::Foo();
    }
    catch( const Base::Foo& ) {}
}

如您所见,这也意味着用一个名称抛出并用另一个名称接住同样可行。

实时示例


3
Base::FooDerived::Foo实际上是同一种类型,一个类只是一个复合类型(来自于C++标准草案第3.9.2节),我们不希望从一个基类中继承的类型在派生类中成为另一种类型。例如,如果Base包含:
typedef int newType1 ;

只要Derived没有重新声明newType1,我们就期望Base::newType1Derived::newType1是相同的类型,而嵌套类也不例外。如果我们查看草案标准中的第 9.2类成员,第1段说(我强调)

[...] 类的成员包括数据成员、成员函数(9.3)、嵌套类型和枚举器。数据成员和成员函数可以是静态或非静态的,参见 9.4。 嵌套类型是在类中定义的类(9.1, 9.7)和枚举(7.2),以及通过 typedef 声明使用成员的任意类型 (7.1.3)

这证实了直觉嵌套类只是类型(也是成员),为了完整起见,上面引用的第9.7节是嵌套类部分,而从第10派生类1段中我们看到:

[...]除非在派生类中重新声明,否则基类的成员也被视为派生类的成员。[...]

由于它们是相同的类型,因此 catch 将正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接