C++/CLI Keywords gcnew Allocates instances of reference types on the garbage-collected managed heap R^ r = gcnew R; generic Declares a parameterized type generic that is recognized by th
Trang 1■ ■ ■
A P P E N D I X
Quick Reference
This appendix covers the new keywords introduced in C++/CLI, specifies which are also reserved
words, and defines and lists contextual keywords and whitespaced keywords This appendix
includes a reference table for features available in native, mixed, pure, and safe modes You’ll
also find a summary of the syntax introduced in C++/CLI
Keywords and Contextual Keywords
Some new keywords were introduced in the C++/CLI bindings Many new keywords introduced
in C++/CLI are sensitive to the context in which they are used, so as to avoid creating new reserved
words in order not to interfere with existing identifiers When used in the proper syntactic position,
contextual keywords are interpreted with the keyword meaning When used in any other
posi-tion, they may be used as identifiers This enables your code to continue to use a variable that
happens to collide with a C++/CLI contextual keyword without any special marking or
modifi-cation This also enables C++/CLI to use keywords that otherwise would be common variable
names There are several new keywords that are not contextual, as described in Table A-1: gcnew,
generic, and nullptr Table A-2 shows the new contextual keywords
Table A-1 C++/CLI Keywords
gcnew Allocates instances of reference
types on the garbage-collected (managed) heap
R^ r = gcnew R();
generic Declares a parameterized type
(generic) that is recognized by the runtime
generic <typename T> ref class G { /* */ };
nullptr Evaluates to the null value for
a pointer, indicating an unassigned pointer
R^ r = nullptr;
Trang 2Whitespaced Keywords
Some of the keywords in C++/CLI are two words containing whitespace, which are referred to
as whitespaced keywords For example, ref class is a whitespaced keyword Spaces and tabs may be used between the two words, but comments (despite technically being whitespace after preprocessing) may not be used Table A-3 lists the whitespaced keywords of C++/CLI
Table A-2 C++/CLI Contextual Keywords
Contextual
Keyword
abstract Declares a class that has some
unimplemented methods, used as a base class Objects cannot be instan-tiated from this class When used on
a method, declares that the method will not be implemented
ref class Base abstract { /* */ };
delegate Declares an object that represents
a type-safe function pointer
delegate void MyDelegate(int);
event Declares an event, an occurrence
that triggers method calls
event EventHandler ClickEvent;
finally Captures program flow after a
try/catch block
finally { /* */ }
in Used in the for each statement for each (R^ r in collection)
{ /* */ }initonly Specifies a field that can only be
modified in a constructor
initonly int i;
internal Specifies that access to a member
is restricted to within an assembly
public ref class R { internal: void f(); }literal Specifies a value that is a
literal constant
literal int SIZE = 150;
override Indicates that a function is intended
to be a virtual override of the base class function of the same name
virtual int f(int a, int b) override;
property Declares a field-like member
on a type
property int P;
sealed Indicates a type that cannot be used
as a base class or a method cannot
be overridden
virtual int f(int a, int b) sealed;
where Used in the declaration of generics
to specify constraints on the types that may be used as type arguments for a generic type or function
generic <typename T> where T : R ref class G { /* */};
Trang 3Keywords As Identifiers
You can specify identifier to use a keyword as an identifier Use it when you migrate
existing code to C++/CLI that uses one of the new keywords: gcnew, generic, or nullptr, or if
you are dealing with another code from another language that has an identifier that matches a
C++/CLI keyword, as in Listing A-1
Listing A-1 Using identifier
enum class Declares an enumeration
with all members public
enum class Color { Red, Green, Blue};
enum struct Declares an enumeration
with all members public
enum struct Color { Red, Green, Blue };
for each Used to iterate over
collection classes
for each (R^ r in collection) { /* */ }
interface class Declares an interface with
all members public
interface class I { /* */ };
interface struct Declares an interface with
all members public
interface struct I { /* */ };
ref class Declares a managed type
with private default accessibility
ref class R { /* */ };
ref struct Declares a managed
struct with public default accessibility
ref struct S { /* */ };
value class Declares a value type
with private default accessibility
value class V { /* */ };
value struct Declares a value type
with public default accessibility
value struct S { /* */ };
Trang 4Listing A-2 demonstrates how to detect CLR compilation.
Listing A-2 Detecting CLR Compilation
Microsoft (R) C/C++ Optimizing Compiler Version 14.00.50727.42
for Microsoft (R) NET Framework version 2.00.50727.42
Copyright (C) Microsoft Corporation All rights reserved
Trang 5Microsoft (R) Incremental Linker Version 8.00.50727.42
Copyright (C) Microsoft Corporation All rights reserved
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.42 for 80x86
Copyright (C) Microsoft Corporation All rights reserved
detecting_clr.cpp
Microsoft (R) Incremental Linker Version 8.00.50727.42
Copyright (C) Microsoft Corporation All rights reserved
XML files may be generated from code comments written in the CLR XML doc format by writing
comments in the format in code and compiling with the /doc compiler option You can use
these XML files to generate formatted documentation The tool xdcmake.exe is used to generate
the XML files from doc comments Table A-4 lists the XML tags available
Table A-4 XML Doc Comment Reference
<example>example section</example> Defines a section containing text
description and an optional code example
<exception cref="member">description</exception> Specifies exceptions that may
be generated
<include file="filename" path="tagpath"> Includes XML comments from a file
or table
Trang 6Listing A-3 illustrates the use of the XML comment format and the generation of XML documentation from the comments.
Listing A-3 Using XML Documentation
// xml_comments.cpp
// compile with: /LD /clr /doc
// then run: xdcmake xml_comments.xdc
using namespace System;
/// Ref class R demonstrates XML Documentation Comments
/// <summary> A class demonstrating documentation comments </summary>
/// <remarks> A detailed description of R goes into the remarks block
/// </remarks>
public ref class R
{
public:
/// <summary>F is a method in the R class
/// <para>You can break the comments into paragraphs
/// <see cref="R::G"/> for related information.</para>
/// <seealso cref="R::G"/>
/// </summary>
void F(int i) {}
<param>description</param> Describes a function parameter
<paramref name="name"> Specifies a hyperlink to
the parameter
<permission cref="member"> Specifies access (e.g., public)
<remarks>description</remarks> Specifies the detailed description
<returns>description</returns> Specifies the return
value information
<see cref="member"> Specifies a cross-reference
<seealso cref="member"> Lists additional references
<summary>text</summary> Specifies text that gives a
brief synopsis
<value>description</value> Specifies a property description
Table A-4 XML Doc Comment Reference (Continued)
Trang 7/// The method G is a method in the R class.
/// <summary>Counts the number of characters in two strings.</summary>
/// <param name="s1"> Description for s1</param>
/// <param name="s2"> Description for s2</param>
/// <returns>The sum of the length of two strings.</returns>
int G(String^ s1, String^ s2){ return s1->Length + s2->Length; }
The method G is a method in the R class
<summary>Counts the number of characters in two strings
</summary>
<param name="s1"> Description for s1</param>
<param name="s2"> Description for s2</param>
<returns>The sum of the length of two strings.</returns>
</member>
<member name="M:R.F(System.Int32)">
<summary>F is a method in the R class
<para>You can break the comments into paragraphs
Ref class R demonstrates XML Documentation Comments
<summary> A class demonstrating documentation comments </summary>
<remarks> A detailed description of R goes into the remarks block
</remarks>
</member>
</members>
</doc>
Trang 8It is up to you to then render this in the desired user-friendly documentation format For example, you could generate documentation in various formats using a tool such as Sandcastle, available from the Microsoft download center (http://www.microsoft.com/downloads).
Summary of Compilation Modes
This book has covered many aspects of the various modes, but not all Table A-5 summarizes the features available in each compilation mode
Table A-5 Features Available in Various Compilation Modes
Build 32-/64-bit
agnostic assemblies
on header
No
Trang 9* Inline asm, most compiler intrinsics
** Including downcasts with static_cast and all uses of reinterpret cast
† Not detected by Visual C++ 2005 compiler
†† Not in the same function as managed or C++ exception handling
Syntax Summary
In these examples, assume R is a reference type (ref class) and V is a value type (value class),
I is an interface (interface class), and P is a property (property int P) Also assume r is a
handle to R and v is an instance of V Assume i, j, and k are integer fields or local variables, s is
a handle to String, and ai is a one-dimensional managed array of integers Assume Base and
Derived are reference classes in an inheritance relationship Assume d is typed as a handle to
Derived and b has type handle to Base, but could be an actual instance of a Base or Derived
i = r1->P; // Access a member using the -> operator
For conversions
Table A-5 Features Available in Various Compilation Modes
Trang 10Tracking Reference
// Declare a tracking reference and initialize to dereferenced handle.R% rref = *r;
i = rref.P; // Access a member using the operator
The gcnew Keyword
R^ r = gcnew R; // gcnew using default constructor
r = gcnew R(); // gcnew using default constructor
r = gcnew R(100, "xyz"); // gcnew with args
The nullptr Keyword
r = nullptr; // Set handle to null
The main Method
int main(array<String^>^ args)
{
/* body of main method */
return i; // optional return statement
// Declare and create 1D array of integers with size
// determined by given initial values
array<int>^ ai = gcnew array<int> { 0, 1, 2, 3 };
// Declare and create 1D array of integers with given size
array<int>^ ai = gcnew array<int>(4);
// array with two dimensions, four by two
array<int, 2>^ ai2d = gcnew array<int, 2>(4, 2)
{ { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7} };
The for each Statement
// for each statement for array of integers
for each (int i in ai) { /* body */ }
// for each statement for collection of ref objects
for each (R^ r in rCollection) { /* body */ }
Trang 11Reference Classes
ref class R { /* body */ };
// public abstract ref class inheriting from Base
[ SomeAttribute ]
public ref class R abstract : Base { /* class body */ };
Value Classes
value class V { /* class body */ };
// value class inheriting from interface I
[ SomeAttribute ]
public value class V : I { /* class body */ };
Enum Classes
// enum with some values
enum class MyEnum { Zero, One, Two, Three = 3, Ten = 10 };
// enum with char as underlying type
enum class MyEnum : char { Zero, One, Two };
Interface Classes
interface class I { /* class body */ };
public interface class I : IBase { /* class body */ };
Trang 12public ref class R { };
private ref class R { };
Trang 13Stack Semantics Declaration
literal int SIZE = 100;
literal String^ NAME = "Test";
Trang 14ref struct R
{
property int P1; // trivial property
// nontrivial property with int backing store
int value;
property int P2
{
int get() { return value; }
void set(int i) { value = i; }
}
// indexed property
array<String^>^ names; // backing store
property String^ P[ int ]
{
String^ get(int index) { return names[index]; }
void set(int index, String^ s) { names[index] = s; }
}
// default indexed property
property String^ default[ int ]
{
String^ get(int index) { return names[index]; }
void set(int index, String^ s) { names[index] = s; }
}
};
Delegates
// Declare delegate type
delegate void MyDelegate(int, String^);
void f()
{
// Create delegate to method F on object r
MyDelegate^ del = gcnew MyDelegate( r, &R::F);
del += gcnew MyDelegate(r, &R::G); // Add target function del -= gcnew MyDelegate(r, &R::G); // Remove target function del += gcnew MyDelegate(&R::StaticMethod); // Add static method del(100, "xyz"); // Invoke delegate
del->Invoke(200, "abc"); // Invoke delegate
}
Trang 16Virtual Functions
ref struct Base
{
virtual int f(int i) { /* */ }
virtual void g(String^ s) { /* */ }
ref struct Base
{ virtual void F(int i) { /* method body */} };
ref class Derived sealed : Base
ref struct Base { virtual void F(int i) { /* body */ } };
ref struct Derived : Base { virtual void F() sealed { /* body */ } };
Trang 17virtual int F(int i, String^ s) { /* implement I::F */ }
virtual void g() { /* implement I::g */ }
Trang 18// attribute applied to return value (target syntax)
[ returnvalue : SomeAttribute() ] R^ f(int i);
Type Identification
Type^ type = R::typeid; // Get static type from class.Type^ type = r->GetType(); // Get dynamic type from object
Managed Template Classes
template <typename T> // or template < class T>
public ref class R
Trang 19generic < typename T, typename U >
where T : R, gcnew() // multiple constraints on one type parameter
where U : value class // constraints on multiple type parameters
public ref class G abstract
{
/* body of generic abstract class */
T t; // reference type handle
U u; // value type object
Trang 20The auto_handle Template
#include <msclr\auto_handle.h>
using namespace msclr;
auto_handle<R> auto_r = R::ReturnHandleToNewR();
The lock Class
/* sensitive code using r */
} // stack semantics, lock released
The gcroot Template
Trang 21The auto_gcroot Template
#include <msclr\auto_gcroot.h>
using namespace msclr;
class N{ auto_gcroot<R^> r;
void f() {
r = gcnew R();
r->F(); // Call method F on r
}}; // r's destructor is called when containing object is deleted