14

假设我有这些课程:

class Base
{
    public:

        class Foo { ... };

        ...
};

然后另一个类从基础派生:

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

这是否意味着我们现在有一个不同的Derived::Foo,或者是Derived::Foo完全相同的Base::Foo

这是这种情况的一个转折点:如果有人抛出一个实例Derived::Foo怎么办?在这种情况下是否会被捕获:

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

2 回答 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& ) {}
}

正如你所看到的,这也意味着用一个名字扔它并用其他作品来捕捉它。

活生生的例子

于 2013-10-22T22:13:40.473 回答
3

Base::Foo并且Derived::Foo确实是相同的类型,类只是复合类型(来自C++ 标准部分草案3.9.2),我们不会期望从基类继承的类型在派生类中是不同的类型。例如,如果包含:Base

typedef int newType1 ;

只要Derived没有重新声明newType1那么我们就会期望Base::newType1Derived::newType1是同一个类型和一个嵌套类没有什么不同。如果我们参考草案标准部分9.2 Class members1段说(强调我的):

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

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

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

由于它们是相同的类型,因此捕获可以正常工作。

于 2013-10-23T03:05:23.227 回答