2016-06-04 16 views
3

In D, kann ich direkt auf Deklaration initialisieren und erwarten, dass die Initialisierungsausdrücke Teil des Konstruktors sind? Ich kam von C# und da ist das der Fall. Aber mit DMD 2.071.0 bekomme ich anderes Verhalten.Sind Initialisiererausdrücke Teil des Konstruktors in D?

class Other { } 

class Test { Other nonStaticMember = new Other; } 

void test() 
{ 
    auto t1 = new Test; 
    auto t2 = new Test; 
    // Assert is failing, the two Test instances are 
    // being initialized to the same reference 
    // instead of execute the Other constructor twice. 
    assert(t1.nonStaticMember !is t2.nonStaticMember); 
} 

Wenn dies das intented Verhalten hier dokumentiert werden sollen: https://dlang.org/spec/class.html richtig?

Antwort

5

Dieser Code tut nicht in D, was es in C# tun würde.

In Ihrem Beispiel wird Other instanziiert während Kompilierung.

I.e. Other wird einmal während der Kompilierung instanziiert und in das Datensegment des Programms eingefügt. Dann zeigt der Anfangswert nonStaticMember standardmäßig auf die Instanz Other für alle Test Instanzen.

So funktioniert alles genauso wie geplant, auch wenn es aus anderen Sprachen überraschend sein mag.

Wenn dies das beabsichtigte Verhalten ist, sollte es hier dokumentiert werden: https://dlang.org/spec/class.html richtig?

Vielleicht, aber beachten Sie, dass dieses Verhalten für Klassen überhaupt nicht spezifisch ist. Ein Zeiger auf einen Wert, der auf dem Heap als Anfangswert einer globalen oder lokalen statischen Variable zugewiesen ist, verhält sich gleich. Wenn der Wert eines Ausdrucks während der Kompilierung angefordert wird (und Initialisierer für globale/statische Variablen enthält), versucht D, ihn zur Kompilierungszeit auszuwerten. Vor einigen Jahren wurde dies auf die Zuweisung von Werten auf dem "Heap" erweitert, die dann in das ursprüngliche Datensegment des Programms gelangen.

Verwandte Themen