Syntactic Sugar for Virtual Constructors?

Steven Schveighoffer schveiguy at yahoo.com
Thu Feb 28 06:34:35 PST 2008


"Janice Caron" wrote
> Something Andrei said got me thinking.
>
> I have a need for so-called "virtual constructors", and of course D
> has Object.factory() which just does the job, given the classname.
> (/Much/ nicer than C++!). But, in my case, the discriminator string
> won't be the class name (which may be unknown to the user), but one of
> a number of IANA-registered strings, documented in some internet RFC
> somewhere. So to deal with that, I need a "factory". The usual way of
> doing this is, given
>
>    string s = whatever; // official name
>
> something like:
>
>    auto x = MyClassFactory.create(s);
>
> And that's OK, but it does mean that polymorphic creation is still
> "different" from normal creation. I got thinking, wouldn't it be nice
> if I could just do
>
>    auto x = new MyClass(s);
>
> and have it work. Now bear in mind that MyClass is an /abstract/
> class. It can never be constructed. Only subclasses can be
> constructed, and that, of course, is the job of a factory. What I'm
> suggesting, then, is just syntactic sugar. It won't give us anything
> we can't do already, but it will let us do it with a nicer syntax.
>
> To make it work, you'd have to allow a class to have a factory within
> itself, and so what I propose is the following syntax:
>
>    abstract class MyClass
>    {
>        static string opFactory(/*params*/)
>        {
>            /* returns a string */
>        }
>    }
>
> Notice that I typed the opFactory function to return a string. The idea is 
> that
>
>    auto x = new MyClass(s);
>
> would be rewritten by the compiler as
>
>    auto x = enforce(cast(MyClass)Object.factory(MyClass.opFactory(s)));
>
> whenever the class is abstract and static opFactoryis present. So what
> opNew needs to return is the string to pass to Object.factory. Observe
> the explicit cast in the rewritten line. That is there partly so that
> x gets the right type (at compile time), but also to ensure at runtime
> that the factory-created class is in fact a subclass of MyClass!
>
> (enforce is one of Andrei's new templates that throws an exception if
> the value is non-zero. I think it will also check for null, but if
> not, I'm sure it can be made to).
>
> I'm sure that better alternative names for opFactory can be thought
> up. Off the top of my head, I came up with opNew, opClass, opNewName,
> opClassName and opFactoryName.
>
> Thoughts?

what about static opCall?

class MyClass
{
       static MyClass opCall(string s)
       {
            // have to implement factoryString
            return cast(MyClass)Object.factory(factoryString(s));
       }
}

auto x = MyClass(s);

then you could also make the opCall method a mixin to avoid 
reimplementation.

-Steve 





More information about the Digitalmars-d mailing list