Syntactic Sugar for Virtual Constructors?

Christopher Wright dhasenan at gmail.com
Thu Feb 28 18:15:27 PST 2008


Janice Caron wrote:
> On 28/02/2008, BCS <BCS at pathlink.com> wrote:
>>         AbstractBaseClass this(string s, int i)
>>         {
>>                 switch(s)
>>                 {
>>                         case "Foo": return new DerivedClass(i);
>>                         ...
>>                         default: return null;
>>                                 // check code causes exception
>>                 }
>>         }
> 
> The switch is the one thing that you /must not have/. The factory
> cannot possibly know all possible (present and future) derived
> classes. Putting that switch statement there prevents anyone without
> access to the source code from making new derived classes, making the
> mechanism completely unworkable for a library. Also, this mechanism
> needs to import all of the module(s) where the derived class(es)
> is/are defined, which is also bad. Also, the function above would
> cause "executable bloat", whereby every possible derived class will
> end up in every executable which calls that function, whether needed
> or not.
> 
> The good way to implement a factory function is to call the function
> object.Factory(). That way, the factory function needs /no knowledge/
> of the derived class, beyond it's class name, extendability is
> retained, and executable bloat is avoided.

A better way:
abstract class AbstractBaseClass
{
    // that type is probably wrong; I can't comprehend how to name
    // delegate types
    static AbstractBaseClass delegate ()[string] builders;
    static AbstractBaseClass factory(string str)
    {
       return builders[str]();
    }
}

class Derived : AbstractBaseClass
{
    static this ()
    {
       AbstractBaseClass.builders["something"] =
          { return new Derived(); }
    }
}



More information about the Digitalmars-d mailing list