1

ここで何が起こっているのかわかりません。説明してください。コード...

import std.stdio;

void main(string[] args)
{
    ClassObject ss1 = new ClassObject("First Class");
    writeln(ss1.produce());
    ClassObject ss2 = new ClassObject("Some Class");
    ClassObject* ss3 = &ss2;
    voidclass(ss3);
    ClassObject ss4 = new ClassObject("Final Class");
    passinterface(ss4);
    ClassObject* ss5 = &ss4;
    writeln(ss5.produce());
    voidinterface(ss5);
}

public void voidclass(void* arg)
{
    ClassObject* ss = cast(ClassObject*) arg;
    writeln(ss.produce());
    writeln(ss.produce);
    ClassObject ssnp = *ss;
    writeln(ssnp.produce());
    writeln(ssnp.produce);
}

public void voidinterface(void* arg)
{
    IObject* bob = cast(IObject*) arg;
    writeln(bob.produce());
}

public void passinterface(IObject arg)
{
    writeln(arg.produce());
}

interface IObject
{
    string produce();
}

class ClassObject : IObject
{
    protected string _value;

    this(string value)
    {
        this._value = value;
    }

    public string produce()
    {
        return this._value;
    }
}

出力...

First Class
Some Class
Some Class
Some Class
Some Class
Final Class
Final Class
main.ClassObject

その最終出力で何が起こっているのですか?ポインターを期待する関数にクラス インスタンスを渡します。次に、それをインターフェイスとしてキャストすると、インターフェイスのメソッドが尊重されません。しかし、私が渡したクラスのインスタンスをどのように伝えることができますか?

悲しいことに、私は C ライブラリにバインドしているので、引数の型として void* を使用する必要があります。したがって、使用しないことを提案しないでください。

編集:コンパイラ情報...

$ dmd -v
DMD64 D Compiler v2.062
Copyright (c) 1999-2012 by Digital Mars written by Walter Bright
Documentation: http://dlang.org/
4

1 に答える 1

5

D のポインターはポリモーフィックではありません。クラス参照のみです。ポインターを操作するとすぐに、ポリモーフィズムが失われます。

また、&ss2クラスへのポインタにはなりません。クラスへの参照へのポインタになります。D ではクラス オブジェクトへのポインターを使用できず、クラス オブジェクトへの参照のみを使用できます。型システムは、クラス参照とそれが参照するオブジェクトを実際には区別しません。これがstd.typecons.Rebindable、const クラス オブジェクトへの非 const 参照が必要な場合に必要な理由です。

ただし、何らかの理由で本当に使用する必要がある場合は、クラス参照をキャストすることができますが、一般的には避けるべきです。使用すると、型情報が失われ、コンパイラはあなたを保護できません。ときどき (特に C と対話する場合に) 便利ですが、Dで使用する理由はあまりありません。void*void*void*void*

于 2013-04-10T01:30:57.250 に答える