Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is a derived class considered a member of the base class?

Tags:

c++

I was reading about the NVI Idiom and most examples follow this form

#include <iostream>

class Base {
public:
    virtual ~Base() = default;

    void do_something() {
        do_something_impl();
    }

private:
    virtual void do_something_impl() = 0;
};

class Derived : public Base {
private:
    void do_something_impl() override {
        std::cout << "Hello, world!\n";
    }
};

void foo(Base& b) {
    b.do_something();
}

int main() {
    Derived d;
    foo(d);
}

I have always had it in my head that "A private member of a class is only accessible to the members and friends of that class" (from cppreference), When do_something_impl is implemented in Derived, is the access specifier not taken into consideration? Or is Derived a member of Base? Does implementing a virtual function not count as "accessing"? I'm not sure which part of the language allows this.

like image 240
Brady Dean Avatar asked May 02 '20 00:05

Brady Dean


2 Answers

From this [emphasis added]:

If some member function vf is declared as virtual in a class Base, and some class Derived, which is derived, directly or indirectly, from Base, has a declaration for member function with the same

  • name
  • parameter type list (but not the return type)
  • cv-qualifiers
  • ref-qualifiers

Then this function in the class Derived is also virtual (whether or not the keyword virtual is used in its declaration) and overrides Base::vf (whether or not the word override is used in its declaration).

Base::vf does not need to be accessible or visible to be overridden. (Base::vf can be declared private, or Base can be inherited using private inheritance. Any members with the same name in a base class of Derived which inherits Base do not matter for override determination, even if they would hide Base::vf during name lookup.)

class B {
    virtual void do_f(); // private member
 public:
    void f() { do_f(); } // public interface
};
struct D : public B {
    void do_f() override; // overrides B::do_f
};

int main()
{
    D d;
    B* bp = &d;
    bp->f(); // internally calls D::do_f();
}
like image 116
H.S. Avatar answered Oct 05 '22 01:10

H.S.


Overriding the virtual function does not count as accessing. However if you need to call the base implementation, that would be impossible to do from Derived.

class Base {
public:
    virtual ~Base() = default;

    void do_something() {
        do_something_impl();
    }

private:
    virtual void do_something_impl() { /*Default implementation*/ }
};

class Derived : public Base {
private:
    void do_something_impl() override {
        //Base::do_something_impl() is not accessible from here:
        //Base::do_something_impl();
        std::cout << "Hello, world!\n";
    }
};
like image 32
Dmitry Kuzminov Avatar answered Oct 05 '22 00:10

Dmitry Kuzminov