Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ interview inheritance puzzle [duplicate]

Possible Duplicate:
C++ virtual function from constructor
Calling virtual functions inside constructors

This question was asked in interview .

I guess I had answered the 1st part correctly but not sure about the 2nd part. In fact I have no clue about 2nd part.

  1. What output does the following code generate? Why?
  2. What output does it generate if you make A::Foo() a pure virtual function?

When I tried running same question on my compiler with virtual void foo() = 0; it throws error "undefined reference to `A::Foo()'"

#include <iostream>

using namespace std;

class A     
{    
public:       
    A()             
    {
        this->Foo();
    }
    virtual void Foo() 
    {
        cout << "A::Foo()" << endl;
    }
};

class B : public A      
{     
public:     
    B()      
    {
        this->Foo();      
    }
    virtual void Foo() 
    {
        cout << "B::Foo()" << endl;
    }
};

int main(int, char**)
{
    B   objectB;
    return 0;
}
like image 332
samantha Avatar asked Sep 17 '25 23:09

samantha


2 Answers

When you instantiate a B object, the following happens:

  1. B's constructor is called.

  2. First thing, B's constructor calls the base constructor A().

  3. Inside A's constructor, the function call is dispatched to A::foo(), since this has static and dynamic type A* (nothing else makes sense if you think about it); now the A subobject is complete.

  4. Now B's constructor body runs. Here the function call is dispatched to B::foo(). Now the entire B object is complete.

If A::foo() is pure-virtual, step (3) causes undefined behaviour; cf. 10.6/4 in the standard.

(In your case possibly manifesting as a linker error, since the compiler optimizes to resolve the call statically, and the symbol A::foo is not found.)

like image 163
Kerrek SB Avatar answered Sep 19 '25 15:09

Kerrek SB


In the second case you have undefined behavior (calling a pure virtual of class T in a class T constructor), so the output could be anything – if it even compiles.

The main thing to understand is that in C++, the dynamic type of an object is T when an object's T constructor executes.

This makes it safe to call virtual functions from a C++ constructor. You don't get a call down into an uninitialized derived class sub-object. In contrast, in Java and C# (and similar languages) you can easily get that kind of bug, and it's common.

like image 38
Cheers and hth. - Alf Avatar answered Sep 19 '25 15:09

Cheers and hth. - Alf