How do you call constructors when allocating an array with new?
For example, in the following code how would I call the constructor for each instantiation of A, initialising b to 5 for all 10 elements?
void main() {
A[] a = new A[10];
}
class A {
int b;
this(int init) {
b = init;
}
}
I'm guessing it's not possible, but I can hope...
An array constructor can be used to define only an ordinary array with elements that are not a row type. An array constructor cannot be used to define an associative array or an ordinary array with elements that are a row type.
Array constructor with a single parameterArrays can be created using a constructor with a single number parameter. An array with its length property set to that number and the array elements are empty slots.
One way to initialize the array of objects is by using the constructors. When you create actual objects, you can assign initial values to each of the objects by passing values to the constructor. You can also have a separate member method in a class that will assign data to the objects.
When you create an array, it's always initially populated with the default value for the type - which for a class is always a null reference.
a simple loop should do (and it's the most readable)
foreach(ref el;a){
el=new A(5);
}
or you can use the array initializer:
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)];
If you're dealing with a value type, you can use std.array.replicate.
auto a = replicate([5], 50);
would create an int[]
of length 50 where each element is 5. You can do the same with a reference type, but all of the elements are going to refer to the same object.
auto a = replicate([new A(5)], 50);
will only call A
's constructor once, and you'll end up with an A[]
where all of the elements refer to the same object. If you want them to refer to separate objects, you're either going to have to set each element individually
auto a = new A[](50);
foreach(ref e; a)
e = new A(5);
or initialize the whole array with a literal
auto a = [new A(5), new A(5), new A(5)];
But that clearly will only work for relatively small arrays.
If you really want to do it in one line, you could write a macro to do it for you. I've borrowed code for the actual initialisation from the other answers.
template allocate(T) {
T[] allocate(int size, int arg) {
T[] result = new T[size];
foreach(ref el; result)
el=new T(arg);
return result;
}
}
Then you can allocate an entire array of 10 elements at once with:
A[] a = allocate!(A)(10, 5);
Of course this has fixed constructor arguments, but you could probably do something with variadic arguments to the template and some mixins to generate the correct constructor call.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With