Search

11.6b — Hiding inherited functionality

Changing an inherited member’s access level

C++ gives us the ability to change an inherited member’s access specifier in the derived class. This is done by using a using declaration to identify the (scoped) base class member that is having its access changed in the derived class, under the new access specifier.

For example, consider the following Base:

Because Base::printValue() has been declared as protected, it can only be called by Base or its derived classes. The public can not access it.

Let’s define a Derived class that changes the access specifier of printValue() to public:

This means that this code will now work:

Two notes:

First, you can only change the access specifiers of base members the derived class would normally be able to access. Therefore, you can never change the access specifier of a base member from private to protected or public, because derived classes do not have access to private members of the base class.

Second, as of C++11, using-declarations are the preferred way of changing access levels. However, you can also change access levels by using an “access declaration”. This works identically to the using declaration method, but omits the “using” keyword. This access declaration way of redefining access is now considered deprecated, but you will likely see older code using this pattern, so it’s worth knowing about.

Hiding functionality

In C++, it is not possible to remove or restrict functionality from a base class other than by modifying the source code. However, in a derived class, it is possible to hide functionality that exists in the base class, so that it can not be accessed through the derived class. This can be done simply by changing the relevant access specifier.

For example, we can make a public member private:

Note that this allowed us to take a poorly designed base class and encapsulate its data in our derived class. Alternatively, instead of inheriting Base’s members publicly and making m_value private by overriding its access specifier, we could have inherited Base privately, which would have caused all of Base’s member to be inherited privately in the first place.

You can also mark member functions as deleted in the derived class, which ensures they can’t be called at all through a derived object:

In the above example, we’ve marked the getValue() function as deleted. This means that the compiler will complain when we try to call the derived version of the function. Note that the Base version of getValue() is still accessible though.

11.7 -- Multiple inheritance
Index
11.6a -- Calling inherited functions and overriding behavior

9 comments to 11.6b — Hiding inherited functionality

  • Moj

    Alex I read somewhere else about derived class hiding its base too, but there it was explained in a way that was so much like the “redefining functionality” case in your tutorial. Its reasoning was that when you redefine a new functionality for that inherited stuff, it “hides” the one from base. Can we view it from this angle? Is this only a matter of language used?
    (Thanks for your awesomeness and by the way, you’re helmet is so cute.)

    • Alex

      Sounds like a matter of language used. Generally when we say “hide”, we mean “make inaccessible”, not “change the meaning”.

  • Sivasankar

    Hi Alex,

    Thanks for the tutorial. I have a small doubt.

    At the line no 25 in 2nd example of "Hiding functionality" section,
    Is "int getValue() = delete;" equivalent to placing the line "using Base::getValue;" under private in derived class ? So that public cann’t call getValue using derived object

  • Dinesh

    Hi,
    Does hiding a base class member or function affect their base class in general or does it only take effect when the derived class is used?
    For example:
    Base
    {
    Public:
    Int m_bPublic;
    Base(int bValue=0): m_bPublic(bValue)
    {}

    }
    Derived: Public Base
    {
    Private:
    Base:: m_bPublic;
    Public:
    Derived(int value): Base(value)
    {}

    }
    Int Main
    {
    Derived derClass(5);
    // Made d member variable of base as private
    Base baseClass(3);
    //Is the below line allowed?
    baseClass.m_bPublic=6;
    }

    On a different note, I would like to appreciate your efforts for creating such an excellent tutorial. Thank You and Cheers 🙂

  • Xhevo

    Hi, Alex.
    It is not quite clear to me the last paragraph of 11.6 - Adding, changing, and hiding members in a derived class:… you can only change the access specifiers of base members…, and then: …you can never change the access specifiers of base members from private to protected or public,…
    [
    One word of caution: you can only change the access specifiers of base members the class would normally be able to access. Therefore, you can never change the access specifier of a base member from private to protected or public, because derived classes do not have access to private members of the base class.
    ]      My best wishes for your excellent job.

    • Alex

      A derived class can’t change the access specifier for a private base class member variable because it doesn’t have access to do so.
      However, a derived class can change the access specifier for a public (or derived) base class member variable because it does have access to do so.

Leave a Comment

Put C++ code inside [code][/code] tags to use the syntax highlighter