Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I am able to call a method w/o passing the required arguments in c++. How come?

Tags:

c++

c++11

Here is the code...

#include "stdafx.h"
#include<iostream>
using namespace std;

class Base
{
public:
    virtual void Display(bool b = false)
    {
        cout<<"Base"<<"\t"<<b<<endl;
    }
};

class Derived : public Base
{
public:
    virtual void Display(bool b) override
    {
        cout<<"Derived"<<"\t"<<b<<endl;
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    Base* bp = new Base();
    Derived* dp = new Derived();
    bp->Display();
    dp->Display(true);
    bp = new Derived();
    bp->Display();
    cout<<"Done"<<endl;
    return 0;
}

When the Display() method called second time using bp, surprisingly it hit the method in Derived class. in Derived class I didn't specify default argument. But it took the default base class argument. How?

like image 933
Suneel VLN Avatar asked Sep 27 '13 05:09

Suneel VLN


People also ask

How do you declare a passing argument in C?

Passing arguments by value When an argument is passed by value, the C function receives a copy of the actual value of the argument. To specify that the argument should always be passed by value, use the keyword ByVal preceding the parameter declaration for that argument in the Declare statement for the C function.

How do we define the arguments to be passed in to a method?

Arguments are the actual values that are passed in when the method is invoked. When you invoke a method, the arguments used must match the declaration's parameters in type and order.

How can we pass arguments in function calling?

The call by value method of passing arguments to a function copies the actual value of an argument into the formal parameter of the function. In this case, changes made to the parameter inside the function have no effect on the argument. By default, C programming uses call by value to pass arguments.


1 Answers

This surprises quite a few people, but the default argument is (or arguments are, if you've specified more than one) based on the static type (the type the pointer is declared to point at) not the dynamic type (the type of object to which it currently happens to point).

As such, since you're using Base *bp, the default arguments declared in Base are used, regardless of whether bp happens to be pointing to a Base or a Derived.

In case you care about why this is: at least in the typical implementation default arguments are actually handled entirely at compile time. The compiler sees that you've called a Display without supplying an argument, and that Display has one argument with a default value. Therefore, when it's generating code for that call, the code is generated to pass the default value that was specified. At that time, it has no way of even guessing whether the pointer may point at some derived type when the call takes place, so all it can do is generate code based on the static type. Though it isn't the case here, when it generates the code to do the call, it's even possible that it could be operating on a derived class that hasn't been designed or written yet, so using a value specified in that derived class wouldn't be possible.

like image 117
Jerry Coffin Avatar answered Oct 26 '22 07:10

Jerry Coffin