views:

148

answers:

4

I have a few classes with a few named constructors. When I inherit from them, how should I inherit the constructors? The problem is that they return objects of base class and not of the child class.

Side question: can I use C++0x "using" to reduce the amount of boilerplate code?

+1  A: 

Neither do you not inherit "classic" constructors, nor you inherit "named" constructors. You should create specific constructors for each derived class.

Here's an example, how named constructor can be used with inheritance:

class SpiralPoint: public Point{
  private: SpiralPoint(float t, float r)
     :Point(Point::polar(r*t, t))  { };
};
Pavel Shved
+3  A: 
struct Foo {
    template<typename T> static T one () { return T(1); }
};

struct A { int x; A(int i) : x(i) {}};
struct B : A { B(int i) : A(i) {}};

Which allows you to do things like

A a = Foo::one<A> (); 
B b = Foo::one<B> ();
ezpz
An improvement:struct A { template <typename T> static T one () { return T(1); }
Łukasz Lew
Good point, edited to include your suggestion
ezpz
+1  A: 

Named ctor is an idiom, they are not real constructors. Strictly speaking, named ctors depend on static functions. Inheritance requires virtual functions. Now, non-members cannot be virtual, hence the idea of having static virtual functions is ruled out.

Side question: can I use C++0x "using" to reduce the amount of boilerplate code?

The using declaration asks the compiler to inherit all-or-none of the base class ctors. So, yes in a way they can simplify your code. However, do all your compilers support C++0x?

dirkgently
A: 

I found (almost) perfect solution!

template <class T>
class Color {

 public:

  static T Red   () { return T (0); }
  static T Green () { return T (1); }
  static T Blue  () { return T (2); }

 protected:

  explicit Color (int raw) : raw (raw) {
  }

 private:

  int raw;

};

class MoreColor : public Color <MoreColor> {

 public:

  static MoreColor Octarina() { return MoreColor(8); }

 private:

  friend class Color <MoreColor>;
  explicit MoreColor (int raw) : Color <MoreColor> (raw) {}
};

void Test() {
  MoreColor o = MoreColor::Octarina();
  MoreColor r = MoreColor::Red();
}

And it compiles :D

Łukasz Lew