Why must C++ constructor use dynamic allocation for array?
In my course notes these two examples开发者_如何学运维 are given. Apparently the first one is not allowed, is there a technical reason why I can't allocate on stack? Or is this the C++ standard?
// Constructor may force dynamic allocation when initializating an array of objects.
Complex ac[10]; // complex array initialized to 0.0
for ( int i = 0; i < 10; i += 1 ) {
ac[i] = (Complex){ i, 2.0 } // disallowed
}
// MUST USE DYNAMIC ALLOCATION
Complex *ap[10]; // array of complex pointers
for ( int i = 0; i < 10; i += 1 ) {
ap[i] = new Complex( i, 2.0 ); // allowed
}
The first one is not valid syntax. But assuming your Complex
class has a public copy-assignment operator (the implicit one should probably be fine), then the following should be fine:
Complex ac[10]; // complex array initialized to 0.0
for ( int i = 0; i < 10; i += 1 ) {
ac[i] = Complex( i, 2.0 );
}
Apparently the first one is not allowed
True, but only because it uses a wrong syntax. The following works:
ac[i] = Complex(i, 2.0);
So the claim is in fact wrong (assuming that Complex
can be assigned to, which it by default can) – no dynamic allocation is needed.
The following is perfectly allowed -- you just had the wrong syntax. You can't cast initializer lists, but you can call constructors as though they are functions.
Complex ac[10]; // calls default constructor for each element
for ( int i = 0; i < 10; i += 1 ) {
ac[i] = Complex(i, 2.0); // constructs a temporary,
// then uses the assignment operator
}
You may of course provide all the values in an initializer-list, like
Complex ac[] = { Complex(0, 2.0), Complex(1, 2.0), /* and so on */ };
but this gets very unwieldy very quickly as the size increases. So it's natural to want to use a loop.
While it's not impossible to independently initialize elements in an automatic (which usually equates to "on stack") buffer, it's not at all easy.
The problem is that defining an array causes the constructor to be called immediately. You'd have to define a char
array (which has no constructor), and then construct and destroy the elements manually (using placement new and explicit destructor calls). This isn't so hard unless you want exception safety, in which case the corner cases are very difficult to handle.
If you're allowed to default-construct and then reassign the elements, it's easy, and covered by the other answers. If Complex
has a working assignment operator, you should do this.
There is no such rule that constructor must have dynamic allocation for array.
ac[i] = Complex( i, 2.0 );
is valid. In fact you should avoid dynamic arrays, as much as you can.
精彩评论