Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When inheriting from a base class, what happens with nested classes?

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?
}
like image 456
Stéphane Avatar asked Oct 22 '13 22:10

Stéphane


People also ask

Does a nested class inherit?

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 .

Can nested class be inherited in Java?

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.

What can be inherited by a class from a base class?

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.

When a sub class inherits from multiple base classes is called?

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.


2 Answers

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

like image 128
Daniel Frey Avatar answered Oct 01 '22 20:10

Daniel Frey


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.

like image 25
Shafik Yaghmour Avatar answered Oct 01 '22 18:10

Shafik Yaghmour