第四章 高级C++/CLI
头文件中可以有类的实现,但不能有类成员函数的实现。
c++的名字空间,缺省public;c++/CLI缺省:private(java c#也是private)。作者反对这样,因为与c++不一致。
使用程序集不需要他的头文件,这是与c++的不同之处。因为程序集是自描述的。
模板
托管扩展c++好像不支持模板。
c++/CLI的模板和c++相同。c++程序员应注意的是,模板是verifiable,并且只能被在一个程序集内有用。建立跨程序集应用的模板要用到.net的generics。
模板的定义和实现必须在同一个文件。
<skip>//大家可以参看c++primer
模板特化:你的模板可能不支持某种类型的参数,所以写一个特定的版本。
Generics
语法与模板相同,generic代替template。
generic不支持特化和缺省参数。
generics运行时实例化(同一generics只有一个程序集)。模板编译时实例化,所以同一模板被实例化为不同的程序集。
子类型约束:语法 where
跨语言支持。
异常
跨语言支持
System::Exception .net所有异常的集类。派生出两类异常ApplicationException(用户定义的异常);SystemException。
不是继承于System::Exception的异常不支持跨语言。
异常被处理后从try块结尾处重新开始执行。
catch(…)是unsafe的。仅应该用在测试阶段。
finally:不管try块执行否,都要执行的语句块。
委托
.net有两种委托:System::Delegate和System::MulticastDelegate
c++/cli只支持System::MulticastDelegate,不过没关系。
委托被编译为一个类。
语法:delegate-name (address-of-method);
delegate-name (handle-of-object, address-of-method);
say+= gcnew SayDelegate(&Talkative::SayHiThere);
SayDelegate ^say =
(SayDelegate^)(Delegate::Combine(say, gcnew SayDelegate(&SayHello)));
Combine,Remove。建议使用重载(编译器自动产生)的+-操作符。
say->Invoke("Mr Fraser");
say("Stephen");
命名约定:委托后缀delegate,事件handler
不必检查nullptr(托管扩展c++这样做了)
事件
和事件相关有一个全局的委托。
<skip>
事件源
事件接受者
//这里介绍的很见单,需要进一步学习<todo>