17.8 — 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:

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.

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. This means that a Derived object can still access getValue() by upcasting the Derived object to a Base first:

17.9 -- Multiple inheritance
17.7 -- Calling inherited functions and overriding behavior

48 comments to 17.8 — Hiding inherited functionality

  • Mymoon


    Did the line below have to be Public? If so, why?
    What if we had written it under Private?

    int getValue() = delete; // mark this function as inaccessible

  • TimCook

    >>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.
    I am a bit confused. Do you mean the code #1 is deprecated and the code #2 is used now?

    • nascardriver

      Yes that's when the paragraph meant. Access declarations are gone since many years and no longer relevant, I've removed the paragraph.

      • Nick

        At the end of the first section of this lesson, the following text appears:

        "Two notes:

        First, you can only change..."

        No second note is given. I am guessing that the second note was the one you removed in response to TimCook's comment here. So the remaining text should probably be updated to something like:

        "Note that you can only change..."

  • Lopenguin

    Thanks for a great lesson, this has been really interesting. All this deleting and overriding of inherited class functions is strangely reminiscent of the way we deal with constructors and destructors. Deleting a function in a subclass is like deleting a constructor or destructor, and overriding constructors seems similar. Makes me wonder if there is some superclass above all the classes that contains a default constructor and destructor.

    Obviously it's not exactly the same because there is that

    functionality, and overriding constructors/destructors can hide the default one, but I thought the similarities were interesting and worth noting.

  • OleksijPlotnyckyj

    "In C++, it is not possible to remove or restrict functionality from a base class other than by modifying the source code."

    In other languages you can? What can be an example of such a thing?

    • nascardriver

      Languages that aren't strictly typed should be able to do this, for example in JS (Using experimental field declarations) we can simply override the entire class

  • Vikrant

    Difference between following codes:


    My Question is I can make a member function changes its access specifier without using the keyword ->"using Base::", Why should I ever use that method then?

  • Enes

    Hi Alex,

    I think webpage has some problems about showing the codes. I just want to let you know.

    Thanks for this wonderful information bank !!

  • Winchester Zohn

    Hi Alex and NascarDriver,

    Looks like the using-declaration is very powerful to change the access level of members, I wonder why we need public/private/protected inheritance types anyway...

    The following code works in microsoft visual studio. I realized that the using-declaration can not only change the access level from protected to public, but also use DIFFERENT base class in the inheritance chain... This is way powerful than inheritance types... Any thoughts/Comments?


    #include <iostream>

    class Base
        int m_value;

        Base(int value)
            : m_value(value)

        void printValue() { std::cout << m_value; }
        void printValue2() { std::cout << "Another Print: " << m_value; }

    class Derived : public Base
        Derived(int value)
            : Base(value)

        using Base::printValue;
        using Base::printValue2;

    class Derived2 : public Derived
        Derived2(int value)
            : Derived(value)

        using Base::printValue;
        using Derived::printValue2;

    int main()
        Derived2 derived2(7);
        return 0;

  • Gopi

    It's worth noting that an inherited member function which is deleted in the derived class can still be accessible using static_cast<> as long as public can access it from base class.

    • Alex

      I added a note to the lesson. Thanks!

      • hellmet

        On the same note, a warning that this isn't a safe way to store private data

  • somoe

    Hi, i tried something weird and it confused me so much. Consider this example:

    First, based on the tutorial, the Derived class above should have 2 parts, its own part and the Base2 part. So i shouldn't be able to do something like that in line 16. But the program just run fine. I assume Derived consist of 2 parts which are its own part and Base2 part which consists of 2 parts (its own part and Base part) and Derived can access x through access specifier of Base part, thus in general, a child class can access a member through access specifier of one of its parent classes no matter how far up the hierarchy ( assumed that parent class has the member).Am i right?
    Second, if i change the inheritance way at line 9 to private, it results in a compile error:
    "error C2247: 'Base::x' not accessible because 'Base2' uses 'private' to inherit from 'Base'"
    What is the difference here since line 10 and 11 just have same effect?

    • Alex

      Your derived will have 3 parts: Base, Base2, and Derived. Base 2 and Derived both make Base's x private -- but it's still treated as public when accessed through Base.

      It looks like this is a bug in Visual Studio, as when I try to compile this example using g++ it gives an error indicating that Base::x is not accessible from Derived, which is what I'd expect.

      • somoe

        Thank you. I have never thought about that, i should use 2 compilers from now on.
        Thanks for the tutorial too, it's very detailed.

      • Atas

        There's something fishy going on. I'm also on VS and I recreated the example omitting the Base2, the behavior is still the same. The member variable d.x is private as intended and d.Base::x is public. It appears that VS compiler implicitly casts d to the base class before accessing its member, something like this

        In fact, if I derive from Base privately, the compiler gives me an error the moment I type d.Base::x, and the error is "Conversion to inaccessible base class "Base" is not allowed". It gives exactly the same error if I try to explicitly static_cast<Base>(d).

      • Atas

        In the end the situation seems to be as follows:
        if you do the

        thing, then d.x is physically the same variable as d.Base::x (they have the same address), however the compiler is trying to be smart and says
        - if you type in d.x, I'll give you the Derived version of the x which is Base::x but with private modifier;
        - if you type in d.Base::x, I'll give you the x in the Base part of the Derived object d. Since you derived publicly and x is declared as public in Base, it is accessible after the implicit cast.

  • Slava Gusev

    Could you please confirm if I got the point correctly.

    Previously you wrote that the object is comprised of portions, which means we have Base and Derived portions.
    So when we use Base::m_value; we basically create in Derived portion reference to a variable m_value from Base portion.
    We put reference into Derived portion private section, but in Base portion the variable m_value stays as it was in public domain.

    Is it right?

    Sorry for bad variables names.


    • Alex

      Yes. Because you've prefixed pub_b_var_ with Base::, it will be accessed through the Base portion of der_o (even though der_o is a Der). And that works because pub_b_var is public in Base.

      If you tried it without the prefix (or with a Der prefix) it wouldn't work because pub_b_var_ has been redefined as private through Der.

  • Benjamin Kambs


    If I intend to make a function of my base class public by means of the using statement, I do not put the paranthesis as you pointed out. What if this function was overloaded in the base class and I like to use just one of the function's versions? How do I accomplish this?

    • Alex

      > If I intend to make a function of my base class public by means of the using statement, I do not put the paranthesis as you pointed out

      I am not sure what you mean by this. Can you clarify?

      > What if this function was overloaded in the base class and I like to use just one of the function’s versions?

      Also not sure I understand what you're asking. Functions are overloaded in the derived class, not the base class. But I'll assume you mean some function that exists in both the base and derived class. If you want to call a specific version of a function, you can use scoping prefixes: e.g. Base::someFunction() vs Derived::someFunction()

      • Benjamin


        I am sorry for my blurry question. I better explain with an example. First, my question referred to your introduction of the "using declaration":

        You are mentioning that this statement is used without parenthesis. Now consider my example:

        The function print() defined in class Base is overloaded in the sense of lesson 7.6: it acts differently for the input types double and int. Also, it is protected, thus cannot be accessed from the outside. Class Derived wants to make print() public. For this I used the "using declaration". However, because I cannot write eg.

        I am forced to make all overloaded versions of print() available to the public. I confess this situation is somewhat constructed. Still, I am curious whether there is a workaround.

        One way I thought of myself is to force print(int) to call print(double) like

        Is there a better way?

        • Benjamin

          Well, ok. I didn't consider just to delete the unwanted int-version:

          Calling print() with an integer is now not possible (error: use of deleted function). Depending on what I want, I either delete the int-version or explicitly cast the integer to a double as I suggested in the last post. I guess that settles it.

          • Alex

            I don't think it's possible (as of C++17) to selectively set access to specific overloaded member functions with the using declaration method. If that's the desire, it's probably better to use the deprecated "access declaration" method. I don't see why not though, so maybe this is something they'll address in a future version of C++.

  • Marryam

    How we can  differentiate the working of "using" and "delete" ?

  • James

    what is the way forward if derived object want to change the override function from 2 different based class it inherited from.
    the both Base have protected access specifier to a function call good(), which sure derived have access to it, now derived want to change the access for it own obj under it own public access area

    using first_class::good;
    using second_class::good;

    now how will the derived obj handle case like this?

    • Alex

      The class will compile, but when you try to call function good() on the derived object, you'll get a naming conflict because it can't disambiguate which function you want. I don't know of any way to call first_class::good() or second_class::good() directly through the derived object, but using the derived classes access specifier.

  • 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.)

  • 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

    • Alex

      From the public's view, it has the same effect. But a private function can still be called by friends, whereas a deleted function can't, so it's not actually equivalent.

  • Dinesh

    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:
    Int m_bPublic;
    Base(int bValue=0): m_bPublic(bValue)

    Derived: Public Base
    Base:: m_bPublic;
    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?

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

    • Alex

      Yes, Base::m_bPublic can be accessed by any Base object, and Derived::m_bPublic can be accessed by any Derived object.

      • Mehmet Uluskan

        Hi Alex, you said "Derived::m_bPublic can be accessed by any Derived object"

        m_bPublic seems as private in Derived class, so I think Derived objects don’t have access to m_bPublic which is private for Derived.

        • Alex

          Objects always have access to their own private members, so Derived does have access to m_bPublic, which is private to Derived. You can confirm this by modifying m_bPublic in the Derived constructor.

  • 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: 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 all code inside code tags: [code]your code here[/code]