0

Dにクラス参照のシステムはありますか? より正確に言うと、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 言語にはそのようなシステムがないようです。

4

2 に答える 2

2

Delphiの概念を理解している限り、DにはDelphiの方法でクラス参照はありません。オブジェクトの構築について実行時の決定を下す必要がある場合は、object.TypeInfoが役立つ場合があります。

コンストラクトTypeInfoを介して変数を取得できます。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コンパイル時に動作するため、階層の場合は「実際の」クラス タイプを照会できません。

于 2013-03-08T20:55:18.357 に答える
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
}

このようにして、そのタイプのインスタンス化されたオブジェクトの代わりに、インスタンス化するタイプを渡します。add() で C が P の子でない場合、これはコンパイル エラーを生成するはずです。

編集:

add をより具体的にしたい場合は、次のようにすることができます。

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);
}
于 2013-03-09T10:31:06.473 に答える