I've got a question on something that I'm not quite clear on. Maybe somebody can help me!
If I derrive a class from another class like so:
// Plant class...
class CPlant {
public:
CPlant(int par_leaves):leaves(par_leaves) {};
int leaves;
};
// Tulip class with different signature on constructor...
class CTulip : public CPlant {
public:
CTulip(bool par_hasBloomed):hasBloomed(par_hasBloomed) {};
bool hasBloomed;
};
Whenever you instantiate a derrived class, the parent class constructor is called first... so when you derrive a class and write a constructor, it's just the same as overriding by overload, any base-class method. Thus I should be overriding the original constructor in the derrived type, or at least, if I always expect it to be called, invoke it in the new constructor in the derrived class like so:
// Call the base class constructor I hid by writing a new constructor for Tulip.
CTulip(bool par_hasBloomed, int par_leaves) {
CPlant::CPlant(par_leaves);
hasBloomed = par_hasBloomed;
}
Is what I said right I think it is, but I'm not sure... I expect that to be the case, but I'd like to know if I'm wrong... ![]()
Thanks!
Gus

Constructor Overrides
kunallen
Will not compile because there is no default constructor for the base class.
Notation must be:
CTulip(bool par_hasBloomed, int par_leaves)
: CPlant::CPlant(par_leaves)
{
hasBloomed = par_hasBloomed;
}
Or can be a special static value
CTulip(bool par_hasBloomed)
: CPlant::CPlant(6)
{
hasBloomed = par_hasBloomed;
}
HTH
Kevin Packard
The correct syntax would be
CTulip(bool par_hasBloomed, int par_leaves)
: CPlant(par_leaves)
, hasBloomed ( par_hasBloomed )
{
}
which also shows the better way to initialize members. Your alternative created a temporary
object, unrelated to 'this', which would be destroyed immediately.
Ryan K
The last question(s) then is this:
//This is the base constructor call for this object...
CPlant(par_leaves);
hasBloomed = par_hasBloomed;
}
The CPlant constructor is called as a peer-level method right
Is the CPlant constructor then inherited along with everything else in Plant
If I instantiate an object of the CTulip class, with the above constructor, how many times will the CPlant constructor be called (I assume only once...)
weoili
It's just like writing a class with NO constructors at all, the compiler will always write a default ctor for you. And if a base class needs to be created in order to instantiate a derrived class, and I didn't provide a default constructor, (CPlant(); right ), the compiler will create and call an empty one for me.
Richter, Salters, thanks guys...
celeon
Thanks for your example. I see now that I can control the construction of the base-class by setting up the default value (which I haven't messed with since I first started using C++! Any parameters that have a default value assigned should occur in the parameter list after parameters that have to be passed into right )
Thanks again.
P.S. One of my problems with this whole thing is principal. If I define a class with ONE constructor that has a list of parameters that I consider to be 'non-negotiable' (data must be passed in), how can I enforce that signature Can I Or do I always have to take special care in the way that I design my data-models or sub-components of a program
Bidmaron
You have two objects, and two constructors are called.
Of course, since it's a temporary, its destructor is called before the assignment to hasBloomed .
This is needed to satisfy the two OO invariants: the number of objects you ever had is total to the number of constructors called, and the number of objects you have left is the number of ctors called minus the number of dtors called.
(Actually, an object is not created if a ctor fails with an exception, but that's of course an exception to the rule)
You still don't inherit constructors.
B-me
Default parameters help you the save constrcutors and coding.
Any parametrs with a default value must after all parameters without one.
If you define a constructor for a class that needs a parameter, and this constructor ist the only one, than nobody can construct an object without using this constructor!
Note: a default constructor is only created when you do not define a default constructor. Same for the copy constructor.
Abdul Abu
Using the constructor this way, will call the defualt constructor of CPlant first. Than it will call the special constructor CPlant(int par_leaves) again.
Eindhoven
1. Yes any parameters that have a deafualt value will always come after the compulsory parameters.
2. If you don't specify default values for the parameters of that one constructor, then the signature is enforced by the compiler. In any violation, its a compile time error. e.g.
class CMyClass {
CMyClass ( int a, int b, int c) {
/* Do something. */
}
};
Now consider the following calls
CMyClass myclass = CMyClass ( ); /* Error */
CMyClass myclass = CMyClass (1); /* Error */
And everything else will be error excepty for something like this
CMyClass myclass = CMyClass (1, 2, 3); /* This will compile.*/
Hence this will compile and will be the only allowed way to create an object of CMyClass.
I hope this helps
Regards
VBRookie
Well its not really like that. The compiler will surely provide a parameter-less for you until you define a constructor of your own. However consider the following code.
// Plant class...
class CPlant {
public:
CPlant(int par_leaves):leaves(par_leaves) {};
int leaves;
};
However, as soon as you provide a constructor of your own (doesn't matter if it is paramaterized or parameter-less), the compiler stops providing a default constructor of its own. In the above case, there is no default constructor for the class CPlant. You can achieve the behaviour of default constructor using the default value.
// Plant class...
class CPlant {
public:
CPlant(int par_leaves = 0):leaves(par_leaves) {};
int leaves;
};
Now if you will pass a value to the constructor, it will consider the value passed by you. Otherwise it will use the default value which happens to be zero in this case.
Now coming back to the question of derived class. As mentioned by msalters, the base class is initialized before the execution enters the constructor of the derived class.
Now based on the above facts, class CTulip can have following two constructors
CTulip(bool par_hasBloomed, int par_leaves)
: CPlant(par_leaves)
, hasBloomed ( par_hasBloomed )
{
} // mentioned by lsmasters
or the simpler one
// Notice this requires only 1 paramater
CTulip(bool par_hasBloomed) : hasBloomed ( par_hasBloomed )
{
/* This will always initialzie the leaves member of base class to 0. It is not flexible and not recommended
*/
}
We can use the same default paramters for the CTulip class to make it more flexible and it goes on. The real thing that matters is your requirement and then your preference, perhaps
Regards