1

I created base class pointer and assigned new derived class to it.

 class Base
{ 
public: 
    virtual void f( int ); 
    virtual void f( double ); 
    virtual void g( int i = 10 ); 
}; 

void Base::f( int )
{ 
    cout << "Base::f(int)" << endl;
} 

void Base::f( double )
{ 
    cout << "Base::f(double)" << endl;
} 

void Base::g( int i )
{
    cout << i << endl;
} 

class Derived: public Base
{ 
public: 
    void f( complex<double> ); 
    void g( int i = 20 ); 
};

void Derived::f( complex<double> )
{ 
    cout << "Derived::f(complex)" << endl;
} 

void Derived::g( int i )
{ 
    cout << "Derived::g() " << i << endl;
} 

void main()
{ 
    Base b; 
    Derived d; 
    Base* pb = new Derived; 
    b.f(1.0); 
    d.f(1.0); 
    pb->f(1.0); 
    b->g();
    d->g();
    pb->g(); 
    delete pb; 
}

Result is:

Base::f(double) 
Derived::f(complex) 
Base::f(double) 
10 
Derived::g() 20 
Derived::g() 10

Results for b and d are expected. pb->f(1.0) calls Base function f(double), but pb->g() seems to call Derived class function g but using parameter i=10 from Base class. Why?

2
  • 2
    Why? Because you're using the Base interface statically, the dispatch to Derived::pb happens only at runtime. Commented Mar 12, 2017 at 21:22
  • delete pb; causes undefined behaviour, since Base does not have a virtual destructor Commented Mar 13, 2017 at 2:18

1 Answer 1

2

Kerrek SB said it all in the comment, I will detail it a bit.

As in this answer, the mechanism of resolving default function parameters occurs at compile time. When the compiler sees pb->g();, knowing that pb is a pointer of type Base*, it consults the declaration of Base::g, that is

virtual void g( int i = 10);

It concludes:

1- The missing parameter i should be set to 10. This is a compile-time decision.

2- The method is declared virtual, which means that the actually invoked method depends on what pb will be pointing-to at run time. The compiler sets the mechanism to dispatch the call to g at runtime (usually through an indirection via the vtable). Since at runtime it happens that pb is actually pointing to an object of type Derived, the method Derived::g is called.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.