Question

Are there any system of classe reference in D? To be more accurate I look for the equivalent of the Delphi

TMyClassRef = class of TMyClass;

This would be used for a factory (just like in the Object but without using the class name):

// ideally
void AddNew(*TBaseClass APtr, /*?class_ref_type?*/ AClassType)
{
    *APtr = new AClassType;
}

Currently I do this:

void AddNew(*TBaseClass APtr)
{
    *APtr = new typeof(*APtr);
}

But the problem is that typeof() returns always TBaseClass and never a sub class of TBaseClass (when a sub class is passed as parameter). This is clearly a case where class references would be used in Delphi but the D language doesn't seem to have such a system.

Was it helpful?

Solution

Maybe I'm completely missing the idea in Delphi, but this seems to be what a templates are for:

import std.stdio;

class Parent {
    string inherited() {
        return "Hello from parent";
    }

    override string toString() {
        return "Hello from parent";
    }
}

class Child : Parent {
    override string toString() {
        return "Hello from child";
    }
}

void add(C, P)(P* ptr) {
    *ptr = new C;
}

void main() {
    Parent t;
    writeln(t); // prints null

    add!Child(&t);
    writeln(t); // prints Hello from child
    writeln(t.inherited()); // prints Hello from parent
}

This way you pass in the type you want to instantiate instead of an instantiated object of that type. This should generate compile errors if C is not a child of P in add().

Edit:

If you want to be more specific with add, you could do this:

void add(T : Parent)(Parent* ptr) {
    *ptr = new T;
}

To make things nicer, use an out parameter to be more idiomatic:

void add(T : Parent)(out Parent ptr) {
    ptr = new T;
}
void main() {
    Parent p;
    add!Child(p);
}

OTHER TIPS

D has no class references in the Delphi way as far as I have understood Delphi concept. If you need to make a run-time decision about object construction, object.TypeInfo may help you.

You can retrieve TypeInfo for a variable via typeid construct:

import std.stdio;

class Base
{
    void f()
    {
        writeln("Base");
    }
}

class Descendant : Base
{
    override void f()
    {
        writeln("Descendant");
    }   
}

Base makeNew(Base other)
{
    // cast is needed because create() returns plain Object
    // we can be sure it is Base at least, though, because it was crated from Base
    return cast(Base)typeid(other).create();
}

void main()
{
    Descendant source = new Descendant;
    Base target = makeNew(source);
    // prints "Descendant"
    target.f();
}

Is this code sample similar to what you want?

D generally has a very clear differentiation between run-time actions and compile-time ones. typeof works on compile-time and thus can't query "real" class type in case of hierarchies.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top