C++/CLI

From Wikipedia, the free encyclopedia
Jump to navigation Jump to search

C++/CLI (C++ modified for Common Language Infrastructure) is a language specification created by Microsoft and intended to supersede Managed Extensions for C++. It is a complete revision that aims to simplify the older Managed C++ syntax, which is now deprecated.[1] C++/CLI was standardized by Ecma as ECMA-372. It is currently available in Visual Studio 2005, 2008, 2010, 2012, 2013, 2015 and 2017, including the Express editions.

C++/CLI is not mentioned in 'The .NET Language Strategy' by Mads Torgersen, posted February 1, 2017.[2]

Syntax changes

C++/CLI should be thought of as a language of its own (with a new set of keywords, for example), instead of the C++ superset-oriented Managed C++ (MC++) (whose non-standard keywords were styled like __gc or __value). Because of this, there are some major syntactic changes, especially related to the elimination of ambiguous identifiers and the addition of .NET-specific features.

Many conflicting syntaxes, such as the multiple versions of operator new() in MC++, have been split: in C++/CLI, .NET reference types are created with the new keyword gcnew (i.e. garbage collected new()). Also, C++/CLI has introduced the concept of generics from .NET (similar, for the most common purposes, to standard C++ templates, but quite different in their implementation).

Handles

In MC++, there were two different types of pointers: __nogc pointers were normal C++ pointers, while __gc pointers worked on .NET reference types. In C++/CLI, however, the only type of pointer is the normal C++ pointer, while the .NET reference types are accessed through a "handle", with the new syntax ClassName^ (instead of ClassName*). This new construct is especially helpful when managed and standard C++ code is mixed; it clarifies which objects are under .NET automatic garbage collection and which objects the programmer must remember to explicitly destroy.

Tracking references

A tracking reference in C++/CLI is a handle of a passed-by-reference variable. It is similar in concept to using "*&" (reference to a pointer) in Standard C++, and (in function declarations) corresponds to the "ref" keyword applied to types in C#, or "ByRef" in Visual Basic .NET. C++/CLI uses a "^%" syntax to indicate a tracking reference to a handle.

The following code shows an example of the use of tracking references. Replacing the tracking reference with a regular handle variable would leave the resulting string array with 10 uninitialized string handles, as only copies of the string handles in the array would be set, due to their being passed by value rather than by reference.

int main()
{
    array<String^> ^arr = gcnew array<String^>(10);
    int i = 0;

    for each(String^% s in arr) {
        s = i++.ToString();
    }

    return 0;
}

Note that this would be illegal in C#, which does not allow foreach loops to pass values by reference. Hence, a workaround would be required.

Finalizers and automatic variables

Another change in C++/CLI is the introduction of the finalizer syntax !ClassName(), a special type of nondeterministic destructor that is run as a part of the garbage collection routine. The C++ destructor syntax ~ClassName() also exists for managed objects, and better reflects the "traditional" C++ semantics of deterministic destruction (that is, destructors that can be called by user code with delete).

In the raw .NET paradigm, the nondeterministic destruction model overrides the protected Finalize method of the root Object class, while the deterministic model is implemented through the IDisposable interface method Dispose (which the C++/CLI compiler turns the destructor into). Objects from C# or VB.NET code that override the Dispose method can be disposed of manually in C++/CLI with delete just as .NET classes in C++/CLI can.

// C++/CLI
ref class MyClass
{
public:
    MyClass();  // constructor
    ~MyClass(); // (deterministic) destructor (implemented as IDisposable.Dispose())
protected:
    !MyClass(); // finalizer (non-deterministic destructor) (implemented as Finalize())

public:
    static void Test()
    {
        MyClass automatic; // Not a handle, no initialization: compiler calls constructor here
 
        MyClass ^user = gcnew MyClass();
        delete user;

        // Compiler calls automatic's destructor when automatic goes out of scope
    }
};

Operator overloading

Operator overloading works analogously to standard C++. Every * becomes a ^, every & becomes anĀ %, but the rest of the syntax is unchanged, except for an important addition: for .NET classes, operator overloading is possible not only for classes themselves, but also for references to those classes. This feature is necessary to give a ref class the semantics for operator overloading expected from .NET ref classes. (In reverse, this also means that for .NET framework ref classes, reference operator overloading often is implicitly implemented in C++/CLI.)

For example, comparing two distinct String references (String^) via the operator == will give true whenever the two strings are equal. The operator overloading is static, however. Thus, casting to Object^ will remove the overloading semantics.

//effects of reference operator overloading
String ^s1 = "abc";
String ^s2 = "ab" + "c";
Object ^o1 = s1;
Object ^o2 = s2;
s1 == s2; // true
o1 == o2; // false

C++/CX

The new C++/CX targeting WinRT, although it produces entirely unmanaged code, borrows the ref and ^ syntax for the reference-counted components of WinRT, which are similar to COM "objects".[3]

References

  1. ^ Managed Extensions for C++ Syntax Upgrade Checklist - MSDN Library
  2. ^ 'The .NET Language Strategy' by Mads Torgersen - MSFT, posted February 1, 2017
  3. ^ Inside the C++/CX Design - Visual C++ Team Blog - Site Home - MSDN Blogs

External links

  • ECMA 372: C++/CLI Language Specification
  • Herb Sutter: C++/CLI keywords: Under the hood
  • Herb Sutter: C++/CLI Rationale
  • MSDN documentation for C++/CLI
  • Patent application regarding whitespace in keywords
  • Bjarne Stroustrup's (designer/author of C++) views on C++/CLI
  • Stanley B. Lippman: Hello, C++/CLI
  • Stanley B. Lippman: Why C++/CLI Supports both Templates for CLI Types and the CLI Generic Mechanism
Retrieved from "https://en.wikipedia.org/w/index.php?title=C%2B%2B/CLI&oldid=858198553"
This content was retrieved from Wikipedia : http://en.wikipedia.org/wiki/C++/CLI
This page is based on the copyrighted Wikipedia article "C++/CLI"; it is used under the Creative Commons Attribution-ShareAlike 3.0 Unported License (CC-BY-SA). You may redistribute it, verbatim or modified, providing that you comply with the terms of the CC-BY-SA