在Visual Studio 2005中使用 C++编程
引入新的操作符^
当你最终解决了这些漏洞的时候,是不是感觉非常良好。在非常成功的编译和运行了三个测试的程序(RegexTest, RegexForm, and WordMess)后,我十分高兴。为什么不去接受这个新的语法了?如果你的知识还是一直停留在过去的话,那么你现在就应该知道C++/CLI的核心在于一种新的类型的引入,这个新的类型叫做追踪句柄,它用符号^标识。因此我放弃了使用/clr:旧的语法(见图四),并且把ManWrap.h文件作了一个小的改变,即把* 替换成^。
#ifdef _MANAGED
# define GCHANDLE(T) gcroot<T^>
#else
# define GCHANDLE(T) intptr_t
#endif

图四:使用新的语法
在做了这个小的变化后,我便把ManWrap载入到编译器,并且把出现的编译错误都一个一个的记录。大多数就是把把* 替换成^。 当然,还有其他需要改变的。我下面就列出我载入ManWrap后的一些错误。对于非常熟悉C++/CLI的,她们便是很旧的东西了,如果你是专家的话,你就可以跳过下面。
•托管类必须用ref 或value进行声明,而不用__gc 或__value。总之,所有的__managed 关键字将由敏感的关键字代替。
•默认的索引器将被称为"default"而不是"Item"。所以
x = m->Item[name];
就应该写成
x = m->default[i];
当有多个索引器时,也是这么工作的,如Regex库里的MatchCollection。
MatchCollection* mc;
mc->default[0]; // int
mc->default["alpha"]; // string
•托管对象需要用关键字gcnew进行分配定义。在任何地方如果要给一个托管类分配空间,要用gcnew而不是new。
•有些变得明显了。看下面的程序片断:
// native entry
void Foo(LPCTSTR lpsz)
{
// managed ctor takes a String
Mumble *m = new Mumble(lpsz);
}
以前的受控扩充件(Managed Extensions)会自动把lpsz初始化为字符串型。但是在Visual Studio 2005下,你必须给lpsz分配一个字符串的空间,就像这样:
void Foo(LPCTSTR lpsz)
{
Mumble ^m = gcnew Mumble(gcnew String(lpsz));
}
这需要敲入更多的代码,但是这同时也使得代码很容易理解。我喜欢用gcnew,因为它促使让你知道你什么时候从堆里分配了空间。这种变化使得代码变得清晰和简单-看起来简单。C++是一个相对易学的语言(我认为这真是一件幸福的事情),因此我觉得让代码保持清晰,不要看起来很晦涩将会更好一些。既然RegexWrap在许多的方需要创建字符串类型,我就把这些创建字符串的代码用一个宏来保存起来。
#define S(s) (gcnew String(s))
对于受控字符串来说,这看起来像字符串的修正器,如字符串S是"Hello, world."那么我可以这么写:
Mumble ^m = gcnew Mumble(S(lpsz));
C++/CLI在数组方面也有一个新的语法变化。不能这么写:
ManagedType* myarray[];
而应该这么写:
array <ManagedType^>^ myarray;
开始的时候我没有写上第二个^。如果你没有的话,将会报这样的错误:"error C3149: cannot use this type here without a top-level '^'",这个错误看起来还是不太清楚,但是一旦你知道了规则,你就会觉得很有道理。既然编译器知道关键字"array"是来定义数组的,那么我不太确定为什么top-level^是必需的。但是这一点我是确信的,这么做肯定是由它的理由的,并且看起来还是很有意义的。许多地方都需要带上^。你需要用^来创建数组。举个例子:
// managed array of ints
array<int>^ foo;
•不用 Count,而用Length来获得数组的长度。
•如果你需要判断是否是空的指针,用nullptr,而不是NULL。
•模版能和托管类很好的组合在一起用。这是用C++/CLI的最重要的原因。因为每个托管类和本地的类都有他们各自的语法(并不是共用过多的*),这是模版产生器就能让这些类区分。
这里有更多的语法改变我还没有提到。毫无疑问你将自己会发现他们。要想察看全部,请看Stan Lippman的这篇文章《Hello C++/CLI》,这篇文章在msdn 杂志Visual Studio 2005专栏里面(网址是:msdn.microsoft.com/msdnmag/issues/06/00/PureC)我还推荐Stan的这篇文章《A Baker's Dozen: Thirteen Things You Should Know Before Porting Your Visual C++ .NET Programs to Visual Studio 2005》,网址是:(msdn.microsoft.com/library/en-us/dnvs05/html/BakerDozen.asp)。
别让新的语法吓着你了。一旦我把* 替换为^和把/clr:oldSyntax替换为/clr,剩下的工作仅仅是固化每个编译器的报错信息。一旦编译器让ManWrap成功的部署在里面,ManWrap就会运行的很好。Redmondtonians应该感到自豪,因为改善后的编译器能够保证它的正确性,就这一点来说,已经是一个成功了。* 到^的转换让我非常高兴,我正考虑把GCHANDLE重命名为MANHANDLE。
0
相关文章