TITLE: polymorphic constructors PROBLEM: nghunyan@iscs.nus.sg (Ng Hun Yang) As far as I know (for a beginner in C++), C++ does not support polymorphic constructors. This can be ackward in some case, like in this example: [example snipped] Is there a way to simulate polymorphic constructors in C++, so that I can do the following: ask user for type of solid g_solid(solid wanted); I don't want to just dump the if() inside the base class constructor (the base class can know what its child classes are, right?), but via some other methods. RESPONSE: ahadsell@mtdiablo.com (P. Alan Hadsell) Use the "Factory Method" pattern from "Design Patterns -- Elements of Reusable Object-Oriented Software", written by Erich Gamma et al, published by Addison Wesley, ISBN 0-201-63361-2. The "parameterized factory method" seems to meet the specific need you describe the best. The effect is to take the if() statement out of the base class constructor, and put it into another class whose responsibility is just knowing what kind of solid to create under which circumstances. With a bit more effort, you can eliminate the if() statement altogether, replacing it with a registration mechanism. Whether this is useful depends on how many product classes you have, and whether their population changes often enough to make manual maintenance of the if() statement a problem. From: kanze@gabi-soft.fr (J. Kanze), 7 Mar 96 [...] The classical solution for this is to have some sort of a builder function/object for each derived type, and to register them in a map. While the FAQ #80 explains one way of implementing the builder functions, I tend to use either a static member function in each derived class (and `map< string , T* (*)() >' for the registry), or more often, a member class, thus: class Base // An abstract class, otherwise, it also needs an // implementation of Builder { protected : class BuilderBase { public : BuilderBase( string myTypeName ) ; virtual ~BuilderBase() ; virtual Base* operator() const = 0 ; } ; public : static map< string , BuilderBase const* > registry ; // ... } ; Base::BuilderBase::BuilderBase( string myTypeName ) { assert( registry.find( myTypeName ) == registry.end() ) ; registry.insert( pair( myTypeName , const_cast< BuilderBase const* >(this ) ) ) ; } Base::BuilderBase::~BuilderBase() { } class Derived : public Base { private : static class Builder :: public Base::BuilderBase { public : Builder() ; virtual Base* operator() const ; } myBuilder ; } ; Derived::Builder Derived::myBuilder ; Derived::Builder::Builder() : Base::BuilderBase( "Derived" ) { } Base* Derived::Builder::operator() const { return new Derived() ; } The client will then use the expression: string typename( "Derived" ) ; Base* p = Base::registry[ typename ]() ; to create the objects. (I hope this code is correct. I don't have STL up and running on my machine yet. I've done this often with my own AssocArray class, however. It's actually a bit easier with my class, since my AssocArray was designed explicitly for this application.) One warning: the above will only work if your compiler initializes the static variables *before* main. If you place the implementation, or the part of it which contains the definition of Derived::myBuilder in a DLL which is only loaded on an as needed basis, it is likely that the above will not work. (Officially, it is not guaranteed to work according to the current version of the draft. In fact, with the exception of DLL's, it will work on all implementations I've ever heard of, provided you do not attempt to use Base::registry when constructing static objects.) Also, some sort of error handling is necessary. I would probably do this by creating a new class for the registry, either derived from or implemented by map. This new class would ensure that the key was present in operator[] (map creates a new entry if it is not), either throwing an exception or returning a default builder (whose operator() returns a null pointer, for example) if it was not.