Tag Archives: Inheritance

Typedef super

A useful addition to a derived class is a typedef aliasing the base class as super:

class Derived : public Base
{
private:
    typedef Base super;
};

This allows you to use super to call the base class constructor from the derived class:

    Derived(int i, int j)
        : super(i), j_(j)
    {
    }

You can also use super to call the base class version of a virtual function in a derived class override:

 virtual void Show()
{
    super::Show();
    std::cout << "Derived Show()\n";
}

It means that if you need to add another layer of inheritance, you only need to change the inheritance part of the class declaration and this typedef.

class Derived : public Intermediate
{
private:
    typedef Intermediate super;
};

You should make the typedef private, to prevent it from being inherited and accidentally used from derived classes that do not declare it.

Visual C++ has a non-standard extension __super: __super.

It is available in Java: Using the Keyword super.

Nowadays you should probably use using:

class Derived : public Base
{
private:
    using super = Base;
};

So it should probably be called the "using super =" idiom.

Calling the base class constructor in C++

The default base class constructor will automatically be called by a derived class default constructor.
If you need to call another base class constructor, you need to put the call to it in the derived class initializer list:


class Base
{
public:
    Base(int i)
        i_(i)
    {
    }
private:
    int i_;
};

class Derived : public Base
{
public:
    Derived(int i, j)
        : Base(i), j_(j)
    {
    }
private:
    int j_;
};

See Typedef super for a handy idiom for referring to the base class.

Public, protected, and private inheritance

In public, protected, and private inheritance, the accessibility of inherited members is analogous to the accessibility of members declared public, protected and private in the derived class.
private members in the base class are never accessible from the derived class, while public and protected members are accessible.
The accessibility of public and protected members will be reduced to the accessibility level of the inheritance if it is lower.

In public inheritance, the accessibility of inherited members remains the same as in the base class; public inherited members are accessible to everyone, protected inherited members are only accessible to the class and its subclasses

In protected inheritance, only the derived class and its subclasses have access to inherited members; public inherited members become protected and so are only available to the class and its subclasses, not anyone outside

In private inheritance, only the derived class has access to inherited members. public and protected inherited members become private.

class Base
{
public:
    int i1;
protected:
    int i2;
private:
    int i3;
};

class P1 : public Base
{
    // i1 is public
    // i2 is protected
    // i3 is not accessible
};

class P2 : protected Base
{
    // i1 is protected
    // i2 is protected
    // i3 is not accessible
};

class P3 : private Base
{
    // i1 is private
    // i2 is private
    // i3 is not accessible
};