The syntax for declaring, instantiating, and initializing a managed array has changed from Managed Extensions for C++ to Visual C++ 2005.
The declaration of a CLR array object in Managed Extensions was a slightly non-intuitive extension of the standard array declaration in which a __gc keyword was placed between the name of the array object and its possibly comma-filled dimension, as in the following pair of examples:
В | Copy Code |
---|---|
void PrintValues( Object* myArr __gc[]); void PrintValues( int myArr __gc[,,]); |
This has been simplified in the new syntax, in which we use a template-like declaration that suggests the STL vector
declaration. The first parameter indicates the element type. The second parameter specifies the array dimension (with a default value of 1, so only multiple dimensions require a second argument). The array object itself is a tracking handle and so must be given a hat. If the element type is also a reference type, that, too, then must be so marked. For example, the above example, when expressed in the new syntax, looks as follows:
В | Copy Code |
---|---|
void PrintValues( array<Object^>^ myArr ); void PrintValues( array<int,3>^ myArr ); |
Because a reference type is a tracking handle rather than an object, it is possible to specify a CLR array as the return type of a function. (It is not possible to specify the native array as the return type of a function.) The syntax for doing this in Managed Extensions was somewhat non-intuitive. For example:
В | Copy Code |
---|---|
Int32 f() []; int GetArray() __gc[]; |
In Visual C++ 2005, the declaration is much simpler for the human reader to parse. For example,
В | Copy Code |
---|---|
array<Int32>^ f(); array<int>^ GetArray(); |
The shorthand initialization of a local managed array is supported in both versions of the language. For example:
В | Copy Code |
---|---|
int GetArray() __gc[] { int a1 __gc[] = { 1, 2, 3, 4, 5 }; Object* myObjArray __gc[] = { __box(26), __box(27), __box(28), __box(29), __box(30) }; return a1; } |
is considerably simplified in the new syntax (note that because boxing is implicit in the new syntax, the __box operator has been eliminated – see Value Types and Their Behaviors for a discussion):
В | Copy Code |
---|---|
array<int>^ GetArray() { array<int>^ a1 = {1,2,3,4,5}; array<Object^>^ myObjArray = {26,27,28,29,30}; return a1; } |
Because an array is a CLR reference type, the declaration of each array object is a tracking handle. Therefore, it must be allocated on the CLR heap. (The shorthand notation hides the managed heap allocation.) Here is the explicit form of an array object initialization under Managed Extensions:
В | Copy Code |
---|---|
Object* myArray[] = new Object*[2]; String* myMat[,] = new String*[4,4]; |
Under the new syntax, the new expression, recall, is replaced with gcnew. The dimension sizes are passed as parameters to the gcnew expression, as follows:
В | Copy Code |
---|---|
array<Object^>^ myArray = gcnew array<Object^>(2); array<String^,2>^ myMat = gcnew array<String^,2>(4,4); |
In the new syntax, an explicit initialization list can follow the gcnew expression; this was not supported in Managed Extensions. For example:
В | Copy Code |
---|---|
// explicit initialization list following gcnew // was not supported in Managed Extensions array<Object^>^ myArray = gcnew array<Object^>(4){ 1, 1, 2, 3 }; |