views:

81

answers:

4

I'm deriving a class which is available from a C++ library, and the constructor of my subclass will only work properly when I execute some code before the base class constructor gets called. (Yes, I know, bad design, but I cannot influence how the library which I'm using works.)

If the base class constructor takes arguments, doing this is actually quite simple:

struct A {
    A(bool a) { printf("A::A()\n"); }
};

bool inject(bool a) { printf("inject()\n"); return a; }

struct B : public A {
    B(bool a) : A(inject(a)) { printf("B::B()\n"); }
};

Now, when I construct an instance of B, inject() gets called before A::A(). But is there a way to do this when the base class ctor has no arguments?

A: 

Why you can't add one more layer ?

struct A {
    A(bool a) { printf("A::A()\n"); }
    A();
};

struct A_Wrap : public A {
    A_Wrap(bool ) : A() { } ;
};

bool inject(bool a) { printf("inject()\n"); return a; }

struct B : public A_Wrap {
    B(bool a) : A_Wrap(inject(a)) { printf("B::B()\n"); }
};
Vardhan Varma
why are you constructing a unnamed object of type A, in the constructor of object A_Wrap?
YeenFei
oops .. A_Wrap should derive from A .. fixed.
Vardhan Varma
+5  A: 

You have a case of "Base from member initialization".

A solution is there.

Alexandre C.
+1 for recommending the Idioms... book.
LaszloG
+1  A: 

Hacky injection code aside, I think the reasonable way to do this is to do the "has a" instead of "is a" pattern: Simply have an instance of the library class inside of your own class. That way you can control allocation and deallocation order to your heart's content.

Reinderien
+1  A: 

Your solution for the one parameter constructor doesn;t really seem useful in the sense that it still cannot access the class being constructed (as it doesn't happen yet) and it is unclear how anything useful can be done with this hacky form (except perhaps setting global scope values which affect the base ctor).

Stephan's proposed solution would look something like this:

struct A {
    A() { printf("A::A()\n"); }
};

struct Injector {
  Injector() { printf("inject()\n"); } 
}

struct B : public A,private Injector {
    B() : Injector(), A() { printf("B::B()\n"); }
};

This is an okay solution but seems a little clumsy to me. Another possible solution is using static class function in place of the constructor for B which run the inject before returning an instantiated object created with a private constructor but it seems from your question that this don't suit your context.

Elemental