2012-02-12 17 views
7

W jaki sposób wywołuje się konstruktory przy przydzielaniu tablicy nowymi?Używanie konstruktorów z tablicami w D

Na przykład w poniższym kodzie jak wywołać konstruktora dla każdego wystąpienia A, inicjalizując b do 5 dla wszystkich 10 elementów?

void main() { 
    A[] a = new A[10]; 
} 

class A { 
    int b; 
    this(int init) { 
     b = init; 
    } 
} 

Zgaduję, że nie jest to możliwe, ale mam nadzieję, ...

Odpowiedz

11

prosta pętla powinna zrobić (i jest to najbardziej czytelny)

foreach(ref el;a){ 
    el=new A(5); 
} 

lub można użyć Inicjator tablicowy:

A[] a=[new A(5),new A(5),new A(5),new A(5),new A(5), 
     new A(5),new A(5),new A(5),new A(5),new A(5)]; 
4

Jeśli masz do czynienia z typem wartości, możesz użyć std.array.replicate.

auto a = replicate([5], 50); 

spowodowałoby int[] o długości 50, gdzie każdy element jest 5. Użytkownik może zrobić to samo z typem odniesienia, ale wszystkie elementy będą odnosić się do tego samego obiektu.

auto a = replicate([new A(5)], 50); 

zadzwoni tylko konstruktor A jest raz, a będziesz skończyć z A[] gdzie wszystkie elementy odnoszą się do tego samego obiektu. Jeśli chcesz, aby odnieść się do poszczególnych obiektów, jesteś albo będzie musiał ustawić każdy element osobno

auto a = new A[](50); 
foreach(ref e; a) 
    e = new A(5); 

lub zainicjować cały szereg z dosłownym

auto a = [new A(5), new A(5), new A(5)]; 

Ale to oczywiście będzie tylko praca dla stosunkowo małych tablic.

1

Jeśli naprawdę chcesz zrobić to w jednym wierszu, możesz napisać makro, aby zrobić to za Ciebie. Pożyczyłem kod dla rzeczywistej inicjalizacji od innych odpowiedzi.

template allocate(T) { 
    T[] allocate(int size, int arg) { 
     T[] result = new T[size]; 
     foreach(ref el; result) 
      el=new T(arg); 
     return result; 
    } 
} 

Następnie można przeznaczyć całą tablicę 10 elementów na raz:

A[] a = allocate!(A)(10, 5); 

to oczywiście ma ustalonej argumenty konstruktora, ale prawdopodobnie można by było zrobić coś ze zmiennej liczbie argumentów argumentów do szablonu, a niektóre mixins, aby wygenerować poprawne wywołanie konstruktora.