Base class constructor calling

Ah hello.

If I have the following class definitions:

class Shape
      Shape() { cout << "Constructing Shape object" << endl; }
      Shape(int n): name(n) { cout << "Constructing Shape object with parameter" << endl;}
      ~Shape() {cout << "Destroying Shape object " << endl; }
      int name;

class Rectangle : public Shape
      Rectangle() { cout << "Constructing Rectangle object" << endl; }
      Rectangle(int n): name(n) { cout << "Constructing Rectangle object with parameter" << endl; } ***
      ~Rectangle() {cout << "Destroying Rectangle object " << endl; }

Now, I am getting a complier error regarding the line marked ***.

'error C2614: 'Rectangle' : illegal member initialization: 'name' is not a base or member'

Yet if I change the marked line to

Rectangle(int n) { name = n; cout << "Constructing Rectangle object with parameter" << endl; }

there is no complaint.

I am confused by this behaviour.  Linked to this question is a second:

Do I always have to *explicitly* call the base class constructor in circumstances like the above ?  Say I leave the constructor for Rectangle as this:

(1) Rectangle(int n) { name = n; cout << "Constructing Rectangle object with parameter" << endl; }

Now this is clearly initialising the inherited variable, name, right ?  Or should I be saying

(2) Rectangle(int n) : Shape(n) { cout << "Constructing Rectangle object with parameter" << endl; }

I have a gut feeling that the latter is probably considered better form, and would be the *only* option if 'name' was private in the Shape class, as Rectangle would not be able to access it via name = n.  But am I right ?  Is it a better idea to initialise inherited variables via the base class constructor call(2), or do so in the derived class constructor's body (1) and hence rely on the base class object to be constructed via its own default constructor ?

I know I have asked two questions here, but they are related, hence the points on offer are 20 for each question.

Thanks a lot !

LVL 19
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

The MSDN says:
"Only a member or base class can be in the initialization list for a class or structure."

You can think what happens if you had Shape defined as:
class Shape {
Shape() : name(n) {...}

If the derived class would also try to initialize the "name" variable, the compiler would be confused - same variable can't be initialized twice.

I think the decision about which is better - (1) or (2) depends on the design, and I would say (2) or BOTH:

In case You're not sure the base class will initialize the name variable as I wand, you can write
Rectangle(int n) : Shape(n) {name = n; ...}

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial

Answer to first question:
If you try to debug the above code(the correct one), you will observe
that compiler after encountering
Rectangle objRectangle(9);
will go to
Rectangle(int n)
compiler will not enter into this body,but from there it goes to Base class
and execute the base class constructor completly and come to the body of Rectangle constructor and execute it. that means at initializer list of Rectangle class, the base class object has not yet created and hence you can't refer any of its member.

2nd question: I guess the  last solution in this case is correct and a better solution. it make sense to force fully call the base class' s constructor.

1.  You do not always have to call the base class constructor explicitly, but there are times when it's appropriate.

2.  Yes (almost), doing name = n inside the body of the Rectangle constructor is setting the value of the inherited member variable "name."   However, it is an assignment, not an initialization.  The initialization took place when the base class constructor was called, which happens before the body of the derived class constructor is executed.  

3.  I agree that in general it is better form to pass the parameter to the base class constructor.  However, since the intent of an int variable entitled "name" isn't at clear to me, it may not matter much in this case.  In many cases, it doesn't matter all that much.

OWASP Proactive Controls

Learn the most important control and control categories that every architect and developer should include in their projects.

A general design principle is to make all member variables private by default. Occassionally they may be declared as protected. This would eliminate most of the questions you have asked.

Another best practice is to use an initialisation list, rather than to initialise (/assign) variables within the constructor body itself. For built-in [fundamental] types there would be no performance hit, but for a custom class initialisation and subsequent reassignment could be costly.
This is what your function Rectangle(int) should look like:

Rectangle(int n)
: Shape(n)
  cout << "Constructing Rectangle object with parameter" << endl;
mrwad99Author Commented:
I am surprised at the feedback that this question generated !

Thanks to everyone for the advice; it seems that migoEX gave advice that completely answered the stated question and was clearly first to do so.  For that reason I have accepted his answer.

Overall cheers though to everyone who participated !
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.