-3
class Base{
public:
    void callF(){ F(); }
private:
    void F(){}
};
class Derived: public Base{
public:
    void F(){}
};
int main(){
    Derived d;
    d.callF();
}

Surprisingly for me,the Base F() is called. I don't understand why. F() was declared and defined in Base class as private,so the Derived object doesn't even know about the existence of such a function in Base. Derived class has its own F(), yet that function is ignored. The question is "Why is the Base class F() called? ".

Grig
  • 31
  • 7
  • 5
    "I know that if I declare F() in Base virtual, the problem will be solved, but what's going on in this example?" - you're not declaring it `virtual`. – Oliver Charlesworth Nov 27 '17 at 19:51
  • the main question is "why is the Base F() called?" – Grig Nov 27 '17 at 19:52
  • _@Grig_ [^^^^^^](http://coliru.stacked-crooked.com/a/9a2101793918f309) What @Oliver said. – user0042 Nov 27 '17 at 19:52
  • @user0042 did you understand my question? "why is the Base F() called?" – Grig Nov 27 '17 at 19:55
  • @Grig Because you're not overriding `Base::F()` in your derived class as a `virtual` function. – user0042 Nov 27 '17 at 19:56
  • Base::F() is called because callF() is in the base class and therefore only knows about the non-virtual base::F() when it was compiled. If you call d.F() you get Derived::F(). – Justin Finnerty Nov 27 '17 at 19:58
  • @user0042 the callF() function has access to the both of F() functions. Why does it give priority to the one that is private therefore not even inherited by the Derived class? – Grig Nov 27 '17 at 19:58
  • @Grig. callF() does not have access to both F() functions. That requires late binding, which in C++ is done using virtual functions. When callF() is compiled it only has access to Base::F(). – Justin Finnerty Nov 27 '17 at 20:04
  • "Why does it give priority to the one that is private therefore not even inherited by the Derived class?" A child type doesn't pick and choose bits of its parent to inherit based on access modifier. Both `callF` functions are very much a part of `Derived`, and the base function will always be called because that's just how C++ works, it will search from base to top until it finds a non virtual function or has reached the top. – George Nov 27 '17 at 20:04
  • @George this comment seems more meaningful than your previous one,which you have already deleted. Yet,what do you mean by " Both callF functions" ? – Grig Nov 27 '17 at 20:11
  • @Grig Typo, I meant `void F(void)` functions :) – George Nov 27 '17 at 20:12

2 Answers2

3

It goes like this.

  1. The Base::callF function is called. It is public so there's no problem in calling it forom main.
  2. The Base::callF function wants to call a function named F. The only F visible to Base::callF is Base::F. It is private, but callF is a member of Base so it gets to see and use all other members, including the private ones.
  3. The Derived::F function has nothing to do with any of this. It's just another function, unrelated to Base::F, which happens to have a similar name.
n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
0

I'm not sure if that answers your question

The question is "Why is the Base class F() called? ".

That's because only virtual functions can be overridden in derived classes (Dynamic Polymorphism1), unless you use a CRTP (Static Polymorphism1):

template<class Derived>
class Base{
public:
    void callF(){ static_cast<Derived*>(this)->F(); }
private:
    void F(){}
};
class Derived: public Base<Derived>{
public:
    void F(){}
};

Otherwise

    void callF(){ F(); }

is equivalent to

    void callF(){ Base::F(); }

1)See also What is the difference between compile time polymorphism and static binding?

user0042
  • 7,917
  • 3
  • 24
  • 39