Say I have these classes:
class Base
{
public:
class Foo { ... };
...
};
Then another class derives from the base:
class Derived : public Base
{
// no mention or redefinition of nested class "Foo" anywhere in "Derived"
};
Does this mean we now have a distinct Derived::Foo
, or is Derived::Foo
the exact same as Base::Foo
?
Here is a twist on this scenario: what if someone throws an instance of Derived::Foo
? Would it be caught in this scenario:
catch ( const Base::Foo &ex )
{
// would this also catch an instance of Derived::Foo?
}
A nested class may inherit from private members of its enclosing class. The following example demonstrates this: class A { private: class B { }; B *z; class C : private B { private: B y; // A::B y2; C *x; // A::C *x2; }; }; The nested class A::C inherits from A::B .
Thus, a nested class can be declared public , package (no access modifier), protected and private (see access modifiers for more info). Therefore nested classes in Java can also be inherited by subclasses as explained in my tutorial about Java inheritance.
Inheritance enables you to create new classes that reuse, extend, and modify the behavior defined in other classes. The class whose members are inherited is called the base class, and the class that inherits those members is called the derived class. A derived class can have only one direct base class.
Multiple Inheritance - When a subclass inherits properties from multiple base classes, it is known as multiple inheritance. In multiple Inheritance , there is only one derived class and several base classes.
Derived::Foo
is just accessing Base::Foo
, therefore these are just two ways to refer to the same type. You can easily check it with 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& ) {}
}
As you can see, this also means throwing it by one name and catching it by the other works as well.
Live example
Base::Foo
and Derived::Foo
are indeed the same type, a class is just a compound type(from the draft C++ standard section 3.9.2
) and we would not expect a type inherited from a base class to be a different type in the derived class. For example if Base
contained:
typedef int newType1 ;
as long as Derived
did not redeclare newType1
then we would expect Base::newType1
and Derived::newType1
to be the same type and a nested class is no different. If we refer to the draft standard section 9.2
Class members paragraph 1 says(emphasis mine):
[...]Members of a class are data members, member functions (9.3), nested types, and enumerators. Data members and member functions are static or non-static; see 9.4. Nested types are classes (9.1, 9.7) and enumerations (7.2) defined in the class, and arbitrary types declared as members by use of a typedef declaration (7.1.3).
That confirms that intuition nested classes are just types(and also members), for completeness sake section 9.7
referenced above is the nested class section and from section 10
Derived classes paragraph 1 we see:
[...]Unless redeclared in the derived class, members of a base class are also considered to be members of the derived class.[...]
Since they are the same type the catch will work fine.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With