D中是否有元类或类引用?

时间:2013-03-08 20:14:11

标签: d metaclass class-reference

D中是否有任何classe参考系统?为了更准确,我寻找相当于Delphi

TMyClassRef = class of TMyClass;

这将用于工厂(就像在Object中但不使用类名):

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

目前我这样做:

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

但问题是typeof()总是返回TBaseClass而永远不会返回TBaseClass的子类(当子类作为参数传递时)。这显然是在Delphi中使用类引用的情况,但D语言似乎没有这样的系统。

2 个答案:

答案 0 :(得分:2)

就我所理解的Delphi概念而言,D没有Delphi方式的类引用。如果您需要对对象构造做出运行时决定,object.TypeInfo可能对您有帮助。

您可以通过TypeInfo construct:

检索变量的typeid
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();
}

此代码示例是否与您想要的类似?

D通常在运行时操作和编译时操作之间有非常明显的区别。 typeof适用于编译时,因此在层次结构的情况下无法查询“真实”类类型。

答案 1 :(得分:2)

也许我完全错过了Delphi中的想法,但这似乎是模板的用途:

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
}

这样,您传入要实例化的类型而不是该类型的实例化对象。如果C不是add()中P的子节点,则应该生成编译错误。

修改

如果您想更具体地添加,可以这样做:

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

为了让事情变得更好,请使用out参数更加惯用:

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