Calling a base class constructor from a derived class constructor

Here is the problem code:

#include<iostream>
using namespace std;

class baseClass
{
public:
    int objID;

    baseClass()
    {
        cout << "(1) Default constructor" << objID << endl;
    }

    baseClass(int ID)  // constructor
    {
        objID = ID;
        cout << "(2) Constructing base object with ID: " << objID << endl;
    }
};

class derivedClass : public baseClass
{
public:
    derivedClass(int ID)
    {
        baseClass(10);    // Line 1
        //baseClass(ID);  // Line 2
        cout << "(4) Constructing derived object with ID: " << objID << endl;
    }
};


int main(int argc, char** argv)
{
    derivedClass dcObj(1);

    return 0;
}

      

The problem I am facing is line 2 in the constructor of the derived class. This gives me the error that I am updating the formal parameter. I know this is because the compiler thinks I am declaring a variable named "ID" of type baseClass. And I know that I have to name it in the initializer list.

But my problem is why is line 1 working? The compiler interprets line 1 as an instance of a baseClass object with a value of 10. Then why is line 2 not working. I am passing int in both cases. How the compiler distinguishes the two.

+3


source to share


5 answers


There is an old rule inherited from C that does its best to drive programmers crazy:

if it can be an advertisement, treat it as an advertisement.

Combined with the fact that C ++ allows redundant parentheses to be inserted in many places - int (x);

is a valid variable declaration - this means that

baseClass(ID);

      

seen as

baseClass ID;  

      



(At this stage, there is no check to see if "identifier" means something, it's just a grammar.)
At a later stage, when the "ID" parameter is known, it becomes an override.

On the other hand,

baseClass 10; 

      

cannot be a declaration, so it means

 baseClass(10);

      

which builds an unnamed instance baseClass

and discards it immediately.

+1


source


Line 1 works because it baseClass

has a default constructor baseClass()

that is automatically called upon instantiation derivedClass

. Your call baseClass(10)

on line 1 creates a temporary object of the type baseClass

that is never used. This call was chosen because it is 10

not a valid variable name, so it is interpreted as a function argument.



+1


source


Line interpretation

baseClass(ID);

      

because the declaration can be classified as a standard. From C ++ Draft N3337 (emphasis mine):

6.8 Disambiguation

1 There is an ambiguity in grammar involving assertion expressions and declarations: expression-expression with function-style explicit type conversion (5.2.3) as its leftmost subexpression may be indistinguishable from the declaration where the first declarator begins with. ( ). In these cases, the statement is a declaration. [Note. To disambiguate, the entire query may have to be examined to determine if it is an expression or a declaration. This disambiguates many examples.

+1


source


The compiler doesn't recognize that you are calling derivatives, it just tries to make parameters, and for ID it tries to make a variable named ID, and from 10 it just makes an unnamed temporary object.

0


source


CASE_1: -

baseClass(ID);

      

This gives you an error as it is interpreted by the compiler as

baseClass ID; <<< You're redefining ID.

      

CASE_2: -

baseClass(10);

      

Since the interpretation baseClass 10

doesn't make sense, the compiler treats this as a constructor call.

0


source







All Articles