Syntactic Sugar for Virtual Constructors?

Janice Caron caron800 at googlemail.com
Thu Feb 28 04:35:14 PST 2008


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?



More information about the Digitalmars-d mailing list