C++托管扩展
此條目目前正依照其他维基百科上的内容进行翻译。 (2008年9月13日) |
C++托管扩展(Managed Extensions for C++)是对C++的一个属性和关键字的扩展,以便于在微软公司的.NET Framework进行编程。它也经常被称为托管C++。
注意:C++托管扩展正在被一个新的语言规范,正在标准化的C++/CLI所取代。
托管C++并非独立存在的编程语言,而仅仅是微软对C++的一个语法扩展,允许C++程序员在.NET框架和CLR的基础上进行托管编程。与C#和Visual Basic .NET相比,其主要优点是旧代码可以比较快地移植到新的平台上,而且即使不完全重写代码,也可以通过互操作在同一个模块中无缝整合托管和非托管代码,从新的.Net框架中获益。.Net框架封装了大量的API,例如网络访问、字符串操作、数据访问、XML服务、图形界面控件库、邮件服务、加密服务、文件输入/输出,甚至是WMI管理,也使得应用程序员可以编写更加简洁的代码。目前只有托管C++及其后继者C++/CLI可以做到无缝整合托管和非托管代码,而在托管代码中调用COM的速度又相当慢,所以经常被用于其他语言和非托管代码之间的桥梁。
托管C++允许程序员编写托管代码,内存管理的工作现在可以让CLR去自动处理,访问时也增加了类型检查,减少了缓冲区溢出和内存泄漏的危险,增加了程序的稳定性,但是在性能敏感的应用中,庞大的.NET框架和缓慢的自动内存管理并不是必要的,传统非托管代码仍然是一些人的首选。
在面向对象编程方面,主要的变化是对多重继承的限制,这是因为CLR的限制和内存管理的需要。一个托管类不能基于多于一个的类。同时,类属性和微软中间语言(MSIL)的引入也使得托管类可以在其他语言中使用和继承。
与此同时,托管C++引入了大量的关键字和语义转换,减少了代码的可读性和明确性。缺少在很多语言中都支持的泛型和for each语句也增加了其他语言的程序员转向托管C++的困难。在其后继者C++/CLI中泛型和for each语句才被支持。
Managed C++ 的重大改變
以下列出物件導向程式設計與 unmanaged C++ 之間的差異性。
- (Global change) Existing C++ to be ported over the CLR must be appended with the following:
//hello.cpp //new using directive #using <mscorlib.dll> //another using namespace directive. using namespace System; int main() { Console::WriteLine("Hello"); return 0; }
一個新的前置處理引導(preprocessor directive)
#using <mscorlib.dll>
這是必須的。此外 #using directives 必須用 namespace 的方法來 import 更多的函式庫(libraries),像是 Base Class Library, 例如:
#using <System.Windows.Forms.dll>
以及
using namespace System::Windows::Forms;
to utilize Windows Forms.
- To compile code to target the CLR, a new compiler option must be introduced.
cl.exe hello.cpp /clr
/clr enables any code referencing the .NET Framework to be compiled as CIL.
- A class can be designated to be garbage collected via the
__gc
extension keyword.
//gc.cpp #using <mscorlib.dll> __gc class gc { int* i; char* g; float* j; }; int main() { while(true) { gc* _gc = new gc(); } return 0; }
The preceding code can be compiled and executed without any fear of memory leaks. Because class gc
is managed under the garbage collector, there is no need to call the delete
operator. Thus this program can run for an indefinite period of time without wasting any memory. To achieve the same with unmanaged code, the delete
keyword is required:
//nogc.cpp class gc { int* i; char* g; float* j; }; int main() { while(true) { gc* _gc = new gc(); delete _gc; } return 0; }
NOTES:
A __gc designated class can have a constructor declared.
A __gc designated class can have a destructor declared.
A __gc designated class cannot inherit more than one class. (This is a limitation of the CLR)
A __gc designated class cannot inherit another class that is not __gc designated.
A __gc designated class cannot be inherited by another class that is not __gc designated.
A __gc designated class can implement any number of __gc interfaces.
A __gc designated class cannot implement an unmanaged interface.
A __gc designated class is by default not made visible outside of its own assembly. Use
public __gc class hey { };
the public keyword to modify the access of the a __gc designated class.
A __gc designated class can be destroyed manually using the delete keyword, but only if the __gc designated class has a user-defined destructor.
- An interface can be declared with the __gc extension keyword preceding it. Such as:
//interface.cpp #using <mscorlib.dll> __gc __interface ClassBase { void Init(); int Common(); }
The preceding code must be compiled with /clr and /LD to produce a simple DLL file.
NOTES:
A __gc __interface cannot contain any data members, static members, nested class declarations and no access specifiers.
A __gc __interface can only inherit from another __gc __interface interface or the System::Object. Inheritance from System::Object is the default behavior.
A __gc __interface cannot contain any implementation (body code) of its declared function prototypes.
比較 Managed C++
以下列出 Managed C++ 與其它程式語言在類似觀念上的差異。
...to Java
缺點
- Java 幾乎可支持所有的平台,而 Managed C++ 僅可以在 Windows 或其它實作出 .NET Framework 的平台上執行。
- Java 程式碼複雜度較小,且易於閱讀,並提供有程式碼使用文件可供參考。而 Managed C++ 則無。 (C++/CLI 於 Visual C++ .NET 2005 中已有支援)
- Java 有許多開發工具與解答(solutions)可提供開發者參考,Managed C++ 僅能使用 Visual Studio .NET。不過,Managed C++ applications 可用免費的 Visual C++ Toolkit 2003 編譯。
- Java 的例外機制是可以檢查的(checked), Managed C++ 則無法檢查。 (This can be considered an advantage over other languages depending on the code)
優點
- Managed C++ 可以直接與系統低階(low level)服務介面溝通,Java 程式員必須使用 JNI (Java Native Interface) 與系統低階服務溝通。 (This applies to Windows only)
- Managed C++ 是無法檢查例外,Java 可以檢查。. (This can be considered a disadvantage compared to other languages depending on the code)
...to C#
缺點
- 一如 Java, C# 的複雜度較小。而且 C# 可以直接支援 .NET Framework 。
- C# 支援指標 (pointers) ,如同 C++, 這個機制預設是關掉的。
- C# can achieve basically the same result when applied to the same solution as one used with Managed C++, as all syntactic and structural conventions remain strikingly similar.
- C# is a much more strongly typed language, which helps reduce certain bugs, such as buffer overflow vulnerabilities.
- Managed C++, 是一種強型別 (strongly typed)語言 language due to its introduction into the CLR, can be prone to errors if unmanaged native code is introduced in the same solution, while C# is pure MSIL.
優點
- C# must use the .NET Framework and provided class libraries to access the computer system on a low level.
- Using Managed C++ to port over applications to the .NET Framework from C or C++ is much easier to do using Managed C++.
- The Microsoft Visual C++ .NET compiler, which compiles Managed C++ to target the .NET Framework, produces a much more matured set of instructions in its resultant assembly, thus improving performance. Performance will vary depending on the code, but in general, Managed C++ code (MSIL) is slightly faster or more efficient than code (MSIL) compiled using the C# compiler[來源請求].
...to unmanaged C++
Disadvantages
- Unmanaged (native) C++ code may be faster at runtime. [Citation or Reference needed]
- Unmanaged C++ does not require an installation of an associated compiler and managed runtime environment on the target system
- Unmanaged C++ supports generic programming. Until the final release of C++/CLI however, Managed C++ programmers must revert for workarounds for using generics in their solutions.
- Unmanaged C++ supports the keyword "const" and const correctness. Managed C++, like Java and C#, does not contain this feature. [Making a managed class immutable, or restricting set accessors on public interfaces enables managed code to have the same protection, to a degree.]
- Unmanaged C++ code is not constricted by the CLR's restrictions. For example, the CLR does not allow classes to inherit other classes privately, thus
public __gc class one { int i; }; public __gc class two: private one { int h; i = h; }; //error
will produce a compiler error.
[Though this is not necessarily a redeeming feature, as the point of making a class private is to prevent inheritance or access outside the class library.]
Also, __gc classes cannot inherit from more than one class, as such
__gc class a {}; __gc class b {}; __gc class c: public a, public b {}; //will produce an error
the preceding will produce a compile error.
[Is this an advantage when multiple derivation leads to problems. It could be interpreted as an advantage of managed code to prohibit poor technique.]
Advantages
- Managed C++ supports a greater degree of reflection than regular C++, which is generally much more convenient depending on the function of the code, or what the code is intended for.
- Managed C++ can interoperate with all other .NET capable languages, including other third party languages.