An intriguing C++ quiz that might challenge you more than you think

The author of the blog “banterly.net” was recently looking through his university days archive and came across this following problem that he created for himself trying to understand how C++ inheritance works. It was not obvious to him back then and he remember that even for TAs and some developers it was not very clear what was the deal, with some getting the answer right but not the why.He still find it intriguing today so I decided to share it, hoping that it may also be intriguing for others.

He will first show the problem. Try to answer it for yourself and post the solution in the comments if you want. Afterwards you can scroll down for a complete explanation and see if you were right.

The problem

Assume that we have the following two very simple classes:

class Parent {
  public:
  virtual void print(){ 
    std::cout<<"I am the parent class"<<std::endl; 
  }
};

class Derived : public Parent {
  public:
  virtual void print(int x){ 
    std::cout<<"I am the derived class"<<std::endl;
  }     
};

What will each of the following two small pieces of code do and why?

int main(){
  Derived *derived=new Derived;
  derived->print();
  return 0;
}  

int main(){
  Parent *derived = new Derived;
  derived->print();
  return 0;
}  

That is it. He know that maybe for some of you this is completely obvious so then just consider it a validation of your knowledge. For the others try to answer and then go to the next section to see if you got it right.

The solution

  • The first case fails
  • The second case will print: “I am the parent class”

The first example has to do with the dominance(or name hiding) mechanism. What that means is that a declaration of a function in a derived class will hide all ancestral functions, regardless of their signature. This surprises some, but the reason for this is that name lookup precedes overload resolution and they are independent steps in the compilation process. So in our case even though there is a function in the Parent class that matches the signature of the function we are calling in main(), the compiler never considers it. In the end we get error: no matching function for call to 'Derived::print()'.

Now the question comes…why didn’t the second one also fail, since we are still using a Derived object to call print()?

The key here is that name lookup does not start with the actual type of the object, but with the declared type of the object. In other words it starts with the type of the variable which references/points to the actual object. In our second case we have a Derived object being stored(yeah I know, its address) in a Parent pointer variable, so our compiler will look in the Parent class for the print() function. It does find it and compilation succeeds correctly and at runtime we get the corresponding output.

Source www.banterly.net

2 thoughts on “An intriguing C++ quiz that might challenge you more than you think

  1. I was wondering what could have been the case if in the derived class Derived did not modify the print() function with the virtual modifier. My suggestion is, with derive::print(), the output would be
    “I am the derived class”
    Why that instead of resulting in a failed compilation?

    Like

    • having removed the virtual modifier in the Derived class, we still got the override ot the virtual function print()

      the word virtual in the Derived serves as a reminder to a programmer that this function overrides functions with the same signature in the base class

      If you need to call a print() function of the base class, then we need to specify this explicitly:

      int main()
      {
      Parent *derived = new Derived;
      derived->Parent::print(); // <=
      return 0;
      }

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s