Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling the constructor of the base class after some other instructions in C++

Tags:

As far as I know it is not possible to call the constructor of the base class. The only way I know is this:

MyClass::MyClass(/* args */) : Base(/* args */) {    // ... } 

but this would invoke the constructor at the beginning. Is there any way to call it somewhere else in the constructor? Something like this:

MyClass::MyClass(/* args */) {    // ... instructions    Base::Base(/* args */);    // ... other_instructions } 

According to this What are the rules for calling the superclass constructor? question I understand there is no way but I read here and I guessed it was possible, but if I try I get:

error: invalid use of 'class Base'. 

Am I doing something wrong? Is it possible to do this some way or is there any other possible solution to this need?

Thanks!

EDIT: I understand I forgot a key point: the base class is part of a framework, and therefore it would be good not to have to modify it, if possible.

like image 388
Luca Carlon Avatar asked May 05 '11 08:05

Luca Carlon


People also ask

How do you call a base class constructor?

You can call the base class constructor from the child class by using the super() which will execute the constructor of the base class.

Do you have to call base class constructor?

No. You never need to explicitly call a destructor (except with placement new). A derived class's destructor (whether or not you explicitly define one) automagically invokes the destructors for base class subobjects. Base classes are destructed after member objects.

Does base class constructor get called automatically?

Whenever the derived class's default constructor is called, the base class's default constructor is called automatically.

Is base class constructor called first?

The compiler knows that when an object of a child class is created, the base class constructor is called first.


1 Answers

If the base class constructor takes at least one argument, you could use a helper function like this:

int DoStuffBeforeCtorAndForwardInt(int arg, Foo foo) {     DoStuff(arg, foo);     return arg; }  MyClass::MyClass(int arg, Foo foo)     : Base(DoStuffBeforeCtorAndForwardInt(arg, foo)) {    // ... } 

If you want to default-initialize the base class, you could use the copy-ctor to copy a default initialized base class instance:

Base DoStuffBeforeCtorAndReturnDefaultBase(int arg, Foo foo) {     DoStuff(arg, foo);     return Base(); }  MyClass::MyClass(int arg, Foo foo)     : Base(DoStuffBeforeCtorAndReturnDefaultBase(arg, foo)) {    // ... } 

Or, if Base doesn't have to be the first base class, you could derive MyClass from a helper class:

MyClass::MyClass(/* ... */)     : DoStuffHelperClass(/* ... */),     Base(/* ... */) {    // ... } 

All of the above require that the "stuff" you do does not depend on the object that's about to be initialized (i.e. the functions can't safely be member functions and you cannot safely pass this as an argument to them either).

That means you can do some logging or similar, but then again you could also do that after the base class has been initialized.

(EDIT except with the DoStuffHelperClass solution, you can of course have members in DoStuffHelperClass, access them and what not)


Although I have to say that I can't recall ever using/needing/wanting something like that. It's quite probable that there is another (preferable) solution for what you're trying to do.

like image 174
Paul Groke Avatar answered Nov 12 '22 23:11

Paul Groke