This is a guide to moving your Visual C++ programs from Managed
Extensions for C++ to Visual C++ 2008. For a checklist summary of
syntactic changes, see
Managed Extensions for C++ Syntax Upgrade Checklist.
C++/CLI
extends a dynamic component programming paradigm to the ISO-C++
standard language. The new language offers a number of significant
improvements over Managed Extensions. This section provides an
enumerated listing of the Managed Extensions for C++ language
features and their mapping to Visual C++ 2008 where such a mapping
exists, and points out those constructs for which no mapping exists.
In
This Section
Outline of Changes
A high-level outline for quick reference, providing
a listing of the changes under five general categories.
Language Keywords
Discusses changes in language keywords, including
the removal of the double underscore and the
introduction of both contextual and spaced keywords.
The Managed Types
Looks at syntactic changes in the declaration of the
Common Type System (CTS) � this includes changes in the
declaration of classes, arrays (including the parameter
array), enums, and so on.
Member Declarations within a Class or Interface
Presents the changes involving class members such as
scalar properties, index properties, operators,
delegates, and events.
Value Types and Their Behaviors
Focuses on value types and the new family of
interior and pinning pointers. It also discusses a
number of significant semantics changes such as the
introduction of implicit boxing, immutability of boxed
value types, and the removal of support for default
constructors within value classes.
General Language Changes
Details semantic changes such as support for cast
notation, string literal behavior, and changes in the
semantics between ISO-C++ and C++/CLI.
Outline of Changes
This outline shows you examples of some of the changes in the
language from Managed Extensions for C++ to Visual C++ 2008. 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:
Copy Code
__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:
Copy Code
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
The Managed Types for more information.
Object
Declaration
Managed Extensions syntax:
Copy Code
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:
Copy Code
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:
Copy Code
Button* button1 = new Button; // managed heap
int *pi1 = new int; // native heap
Int32 *pi2 = new Int32; // managed heap
See
Declaration of a CLR Reference Class Object for more
information.
A Tracking Reference to No Object
Managed Extensions syntax:
Copy Code
// OK: we set obj to refer to no object
Object * obj = 0;
// Error: no implicit boxing
Object * obj2 = 1;
New syntax:
Copy Code
// 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:
Copy Code
void PrintValues( Object* myArr __gc[]);
void PrintValues( int myArr __gc[,,]);
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
Copy Code
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:
Copy Code
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:
Copy Code
public ref class Matrix {
array^ 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
Copy Code
public ref class Matrix {
array^ 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:
Copy Code
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:
Copy Code
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:
Copy Code
__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:
Copy Code
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:
Copy Code
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:
Copy Code
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:
Copy Code
__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
Copy Code
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:
Copy Code
__value enum e1 { fail, pass };
public __value enum e2 : unsigned short {
not_ok = 1024,
maybe, ok = 2048
};
New enum syntax:
Copy Code
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++ 2008.
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:
Copy Code
Object *o = __box( 1024 ); // explicit boxing
New boxing syntax:
Copy Code
Object ^o = 1024; // implicit boxing
See
A Tracking Handle to a Boxed Value for more information.
Pinning
Pointer
Managed Extensions pinning pointer syntax:
Copy Code
__gc struct H { int j; };
int main() {
H * h = new H;
int __pin * k = & h -> j;
};
New pinning pointer syntax:
Copy Code
ref struct H { int j; };
int main() {
H^ h = gcnew H;
pin_ptr k = &h->j;
}
Several language keywords changed from Managed Extensions for C++ to
Visual C++ 2008.
In the new Visual C++ 2008 syntax, the double
underscore is removed as a prefix from all keywords (with one
exception: __identifier is retained).
For example, a property is now declared as
property, not __property.
There were two primary reasons for using the double-underscore
prefix in Managed Extensions:
It is the conformant method of providing local extensions to
the ISO-C++ Standard. A primary goal of the Managed Extensions
design was to not introduce incompatibilities with the standard
language, such as new keywords and tokens. It was this reason,
in large part, which motivated the choice of pointer syntax for
the declaration of objects of managed reference types.
The use of the double underscore, apart from its conformant
aspect, is also a reasonable guarantee of being non-invasive
with the existing code base of the language users. This was a
second primary goal of the Managed Extensions design.
In spite of removing the double underscores, Microsoft remains
committed to being conformant. However, support for the CLR dynamic
object model represents a new and powerful programming paradigm.
Support of this new paradigm requires its own high-level keywords
and tokens. We have sought to provide a first-class expression of
this new paradigm while integrating it and supporting the standard
language. The new syntax design provides a first class programming
experience of these two disparate object models.
Similarly, we are concerned with maximizing the non-invasive
nature of these new language keywords. This has been accomplished
with the use of contextual and spaced keywords. Before we look at
the actual new language syntax, let�s try to make sense of these two
special keyword flavors.
A contextual keyword has a special meaning within specific
program contexts. Within the general program, for example,
sealed is treated as an ordinary
identifier. However, when it occurs within the declaration portion
of a managed reference class type, it is treated as a keyword within
the context of that class declaration. This minimizes the potential
invasive impact of introducing a new keyword in the language,
something that we feel is very important to users with an existing
code base. At the same time, it allows users of the new
functionality to have a first-class experience of the additional
language feature � something that wasn't possible with Managed
Extensions. For an example of how sealed
is used see
Declaration of a Managed Class Type.
A spaced keyword, such as value class,
is a special case of a contextual keyword. It pairs an existing
keyword with a contextual modifier separated by a space. The pair is
treated as a single unit rather than as two separate keywords.