说我有这些课程:
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?
}
答案 0 :(得分: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& ) {}
}
正如你所看到的,这也意味着用一个名字抛出它并用其他作品捕捉它。
答案 1 :(得分:3)
Base::Foo
和Derived::Foo
确实是相同的类型,类只是复合类型(来自draft C++ standard部分3.9.2
)我们不希望从基类继承的类型成为派生类中的其他类型。例如,如果Base
包含:
typedef int newType1 ;
只要Derived
没有重新声明newType1
,我们就会希望Base::newType1
和Derived::newType1
成为相同的类型和嵌套类也不例外。如果我们引用标准草案部分草案9.2
类成员段 1 说(强调我的):
[...] 班级成员数据成员,成员函数(9.3),嵌套类型,以及 统计员。数据成员和成员函数是静态的或非静态的;见9.4。 嵌套类型 类中定义的类(9.1,9.7)和枚举(7.2),以及使用typedef声明(7.1.3)声明为成员的任意类型。
这证实直觉嵌套类只是类型(以及成员),为了完整起见,上面引用的部分9.7
是嵌套类部分和部分10
派生类段 1 我们看到:
[...]除非在派生类中重新声明,否则基类的成员也被视为派生类的成员。[...]
由于它们属于同一类型, catch 可以正常工作。