Outline of Changes

This outline shows you examples of some of the changes in the language from Managed Extensions for C++ to Visual C++. Follow the link that accompanies each item for more information.

No Double Underscore Keywords

The double underscore in front of all keywords has been removed, with one exception. Thus, __value becomes value, and __interface becomes interface, and so on. To prevent name clashes between keywords and identifiers in user code, keywords are primarily treated as contextual.

See Language Keywords for more information.

Class Declarations

Managed Extensions syntax:

__gc class Block {};                           // reference class
__value class Vector {};                       // value class
__interface I {};                        // interface class
__gc __abstract class Shape {};                // abstract class
__gc __sealed class Shape2D : public Shape {}; // derived class

New syntax:

ref class Block {};                // reference class
value class Vector {};             // value class
interface class I {};        // interface class
ref class Shape abstract {};       // abstract class
ref class Shape2D sealed: Shape{}; // derived class

See Managed Types (C++/CL) for more information.

Object Declaration

Managed Extensions syntax:

public __gc class Form1 : public System::Windows::Forms::Form {
private:
   System::ComponentModel::Container __gc *components;
   System::Windows::Forms::Button   __gc *button1;
   System::Windows::Forms::DataGrid __gc *myDataGrid;   
   System::Data::DataSet  __gc *myDataSet;
};

New syntax:

public ref class Form1 : System::Windows::Forms::Form {
   System::ComponentModel::Container^ components;
   System::Windows::Forms::Button^ button1;
   System::Windows::Forms::DataGrid^ myDataGrid;
   System::Data::DataSet^ myDataSet;
};

See Declaration of a CLR Reference Class Object for more information.

Managed Heap Allocation

Managed Extensions syntax:

Button* button1 = new Button; // managed heap
int *pi1 = new int;           // native heap
Int32 *pi2 = new Int32;       // managed heap

New syntax:

Button^ button1 = gcnew Button;        // managed heap
int * pi1 = new int;                   // native heap
Int32^ pi2 = gcnew Int32;              // managed heap

See Declaration of a CLR Reference Class Object for more information.

A Tracking Reference to No Object

Managed Extensions syntax:

// OK: we set obj to refer to no object
Object * obj = 0;

// Error: no implicit boxing
Object * obj2 = 1;

New syntax:

// Incorrect Translation
// causes the implicit boxing of both 0 and 1
Object ^ obj = 0;
Object ^ obj2 = 1;

// Correct Translation
// OK: we set obj to refer to no object
Object ^ obj = nullptr;

// OK: we initialize obj2 to an Int32^
Object ^ obj2 = 1;

See Declaration of a CLR Reference Class Object for more information.

Array Declaration

The CLR array has been redesigned. It is similar to the stl vector template collection, but maps to the underlying System::Array class – that is, it is not a template implementation.

See Declaration of a CLR Array for more information.

Array as Parameter

Managed Extensions array syntax:

void PrintValues( Object* myArr __gc[]); 
void PrintValues( int myArr __gc[,,]); 

New array syntax:

void PrintValues( array<Object^>^ myArr );
void PrintValues( array<int,3>^ myArr );

Array as Return Type

Managed Extensions array syntax:

Int32 f() []; 
int GetArray() __gc[];

New array syntax:

array<Int32>^ f();
array<int>^ GetArray();

Shorthand Initialization of Local CLR Array

Managed Extensions array syntax:

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;
}

New array syntax:

array<int>^ GetArray() {
   array<int>^ a1 = {1,2,3,4,5};
   array<Object^>^ myObjArray = {26,27,28,29,30};

   return a1;
}

Explicit CLR Array Declaration

Managed Extensions array syntax:

Object* myArray[] = new Object*[2];
String* myMat[,] = new String*[4,4];

New array syntax:

array<Object^>^ myArray = gcnew array<Object^>(2);
array<String^,2>^ myMat = gcnew array<String^,2>(4,4);

New to language: explicit array initialization that follows gcnew

// explicit initialization list follow gcnew 
// is not supported in Managed Extensions
array<Object^>^ myArray = 
   gcnew array<Object^>(4){ 1, 1, 2, 3 };

Scalar Properties

Managed Extensions property syntax:

public __gc __sealed class Vector {
   double _x;

public:
   __property double get_x(){ return _x; }
   __property void set_x( double newx ){ _x = newx; }
};

New property syntax:

public ref class Vector sealed { 
   double _x;

public:
   property double x 
   {
      double get()             { return _x; }
      void   set( double newx ){ _x = newx; }
   } // Note: no semi-colon …
};

New to language: trivial properties

public ref class Vector sealed { 
public:
   // equivalent shorthand property syntax
   // backing store is not accessible
   property double x; 
};

See Property Declaration for more information.

Indexed Properties

Managed Extensions indexed property syntax:

public __gc class Matrix {
   float mat[,];

public: 
   __property void set_Item( int r, int c, float value) { mat[r,c] = value; }
   __property int get_Item( int r, int c ) { return mat[r,c]; }
};

New indexed property syntax:

public ref class Matrix {
   array<float, 2>^ mat;

public:
   property float Item [int,int] {
      float get( int r, int c ) { return mat[r,c]; }
      void set( int r, int c, float value ) { mat[r,c] = value; }
   }
};

New to language: class-level indexed property

public ref class Matrix {
   array<float, 2>^ mat;

public:
   // ok: class level indexer now
   //     Matrix mat;
   //     mat[ 0, 0 ] = 1; 
   //
   // invokes the set accessor of the default indexer

   property float default [int,int] {
      float get( int r, int c ) { return mat[r,c]; }
      void set( int r, int c, float value ) { mat[r,c] = value; }
   }
};

See Property Index Declaration for more information.

Overloaded Operators

Managed Extensions operator overload syntax:

public __gc __sealed class Vector {
public:
   Vector( double x, double y, double z );

   static bool    op_Equality( const Vector*, const Vector* );
   static Vector* op_Division( const Vector*, double );
};

int main() {
   Vector *pa = new Vector( 0.231, 2.4745, 0.023 );
   Vector *pb = new Vector( 1.475, 4.8916, -1.23 ); 

   Vector *pc = Vector::op_Division( pa, 4.8916 );

   if ( Vector::op_Equality( pa, pc ))
      ;
}

New operator overload syntax:

public ref class Vector sealed {
public:
   Vector( double x, double y, double z );

   static bool    operator ==( const Vector^, const Vector^ );
   static Vector^ operator /( const Vector^, double );
};

int main() {
   Vector^ pa = gcnew Vector( 0.231, 2.4745, 0.023 );
   Vector^ pb = gcnew Vector( 1.475, 4.8916, -1.23 );

   Vector^ pc = pa / 4.8916;
   if ( pc == pa )
      ;
}

See Overloaded Operators for more information.

Conversion Operators

Managed Extensions conversion operator syntax:

__gc struct MyDouble {
   static MyDouble* op_Implicit( int i ); 
   static int op_Explicit( MyDouble* val );
   static String* op_Explicit( MyDouble* val ); 
};

New conversion operator syntax:

ref struct MyDouble {
public:
   static operator MyDouble^ ( int i );
   static explicit operator int ( MyDouble^ val );
   static explicit operator String^ ( MyDouble^ val );
};

See Changes to Conversion Operators for more information.

Explicit Override of an Interface Member

Managed Extensions explicit override syntax:

public __gc class R : public ICloneable {
   // to be used through ICloneable
   Object* ICloneable::Clone();

   // to be used through an R
   R* Clone();
};

New explicit override syntax:

public ref class R : public ICloneable {
   // to be used through ICloneable
   virtual Object^ InterfaceClone() = ICloneable::Clone;

   // to be used through an R 
   virtual R^ Clone();
};

See Explicit Override of an Interface Member for more information.

Private Virtual Functions

Managed Extensions private virtual function syntax:

__gc class Base {
private:
   // inaccessible to a derived class
   virtual void g(); 
};

__gc class Derived : public Base {
public:
   // ok: g() overrides Base::g()
   virtual void g();
};

New private virtual function syntax

ref class Base {
private:
   // inaccessible to a derived class
   virtual void g(); 
};

ref class Derived : public Base {
public:
   // error: cannot override: Base::g() is inaccessible
   virtual void g() override;
};

See Private Virtual Functions for more information.

CLR Enum Type

Managed Extensions enum syntax:

__value enum e1 { fail, pass };
public __value enum e2 : unsigned short  { 
   not_ok = 1024, 
   maybe, ok = 2048 
};  

New enum syntax:

enum class e1 { fail, pass };
public enum class e2 : unsigned short { 
   not_ok = 1024,
   maybe, ok = 2048 
};

Apart from this small syntactic change, the behavior of the CLR enum type has been changed in a number of ways:

  • A forward declaration of a CLR enum is no longer supported.

  • The overload resolution between the built-in arithmetic types and the Object class hierarchy has reversed between Managed Extensions and Visual C++. As a side-effect, CLR enums are no longer implicitly converted to arithmetic types.

  • In the new syntax, a CLR enum maintains its own scope, which is not the case in Managed Extensions. Previously, enumerators were visible within the containing scope of the enum; now, enumerators are encapsulated within the scope of the enum.

See CLR Enum Type for more information.

Removal of __box Keyword

Managed Extensions boxing syntax:

Object *o = __box( 1024 ); // explicit boxing

New boxing syntax:

Object ^o = 1024; // implicit boxing

See A Tracking Handle to a Boxed Value for more information.

Pinning Pointer

Managed Extensions pinning pointer syntax:

__gc struct H { int j; };

int main() {
   H * h = new H;
   int __pin * k = & h -> j;
};

New pinning pointer syntax:

ref struct H { int j; };

int main() {
   H^ h = gcnew H;
   pin_ptr<int> k = &h->j;
}

See Value Type Semantics for more information.

__typeof Keyword becomes typeid

Managed Extensions typeof syntax:

Array* myIntArray = 
   Array::CreateInstance( __typeof(Int32), 5 );

New typeid syntax:

Array^ myIntArray = 
   Array::CreateInstance( Int32::typeid, 5 );

See typeof Goes to T::typeid for more information.

See Also

Concepts

C++/CLI Migration Primer

Component Extensions for Runtime Platforms

Other Resources

Managed Extensions for C++ Syntax Upgrade Checklist