views:

174

answers:

4

I have a large set classes which I need to "wrap" in a very thin subclass. The functionality of the base classes doesn't change, and their interface remains intact.

The problem is, that in order to use the base classes's constructors (and most of them have more than one), I need to decalre an identical constructor in each of the subclasses, and simply pass the parameters over to the constructor of the base class (99% of the time I have nothing else to do upon construction). That's a lot of pointless work.

What's the easiest way to do this?

Edit: Even if it's not natively supported in the language, maybe there's some tool that can auto-generate that code?

+1  A: 

I think you're out of luck unless you can use C++0x. Read this article:

http://stackoverflow.com/questions/1444837/automatic-creation-of-constructor-based-on-parent-class-constructor-c

Jeremy Friesner
A: 

Wishful thinking leads me to suggest

class BaseClass {
public:
    BaseClass(foo, bar, baz);
};

template <class T>
class BaseInheritor : public BaseClass {
public:
    T(foor, bar, baz);
};

class Child : public BaseInheritor<Child> {
    // Other stuff
};

I don't think C++ templates can quite do what I've just written, unfortunately. There's a pretty straightforward answer with macros, but I feel dirty suggesting it:

#define CHILD_CLASS_DEFAULT(name) \
class name : public BaseClass { \
    public: name(foo, bar, baz) : BaseClass(foo, bar, baz) { } \
    private:


#define CHILD_CLASS_OVERRIDE(name) \
class name : public BaseClass { \
Novelocrat
That won't do, because there are many base classes, each have a different set of constructors (taking different parameters).
sold
That leads me to think of tricks involving 2 or 3 macro definitions per base class, and some token pasting. It would be very ugly.
Novelocrat
A: 

I'd go for a script-based solution, maybe based on gccxml or something similar.
With that you could write a simple script (i.e. generate-derivate <input-file> <base-name> <derivative-name> <output-file>) that generates you the wrapper. You'd only have to make changes manually if you are adding/changing functionality.

edit: vague outline:

write derivative-name + " : public " + base-name + " {\npublic:\n"
foreach <Constructor> where attribute name == base-name
    write "\tderivate-name("
    foreach <Argument>
       resolve by attribute type (query FundamentalType, ReferenceType, ...)
       write argument type etc.
    write ");\n"
write "\n};\n"

It all depends on what script language and what xml tools you use. Trolltech has XQuerys in their example.

Georg Fritzsche
That seems like a solution. However I've never used gccxml. can you give an outline for such a script?
sold
I added it to the answer.
Georg Fritzsche
+2  A: 

You could add templated constructors for all possible parameters to your wrapper class:

template<class Base>
class wrapper : public Base {
public:
  wrapper() : Base() {}

  template<typename T1>
  wrapper(T1 a1) : Base(a1) {}

  template<typename T1, typename T2>
  wrapper(T1 a1, T2 a2) : Base(a1, a2) {}

  // ...
};

Since the templates will not be instantiated for constructors that aren't called it doesn't matter if these other constructors would be invalid. Only the constructors that are actually used need to exist in the base class:

class A {
public:
  A(int a) {};
};

int main() {
   wrapper<A> aw(1);
   return 0;
}

Probably there are some corner cases where this approach will lead to problems, but for simple cases it works.

sth