09C++CLIWord下载.docx
《09C++CLIWord下载.docx》由会员分享,可在线阅读,更多相关《09C++CLIWord下载.docx(88页珍藏版)》请在冰点文库上搜索。
inta__gc[];
//托管数组,不能指定大小
//intb[10];
//错误,托管类的数据,必须用__gc或__nogc明确指出是否为托管类型
intb__nogc[10];
//非托管数组,可以指定大小
intsum(int);
//声明sum函数
intG:
:
sum(inti){returni*(i+1)/2;
}//定义sum函数
intmain(){//主函数,程序入口
Valv={20};
//创建Val结构对象并初始化
__boxVal*pV=__box(v);
//托管类型的指针,须进行装箱转换
pV->
nVal=5;
//修改托管对象的值,不会影响值类型变量v的值
G*g=newG;
//创建托管对象
g->
a=newint__gc[100];
//创建托管数组
a[0]=8;
//用S转换字符串、用__box装箱、用{i}进行托管数据的格式化输出:
System:
Console:
WriteLine(S"
v={0},a[0]={1},sum={2}"
__box(v.nVal),__box(g->
a[0]),__box(g->
sum(4)));
Object*oV=__box(v);
//装箱后赋值给对象指针
Valv1=*pV;
//直接拆箱
Valv2=*__try_cast<
__boxVal*>
(oV);
//类型转换拆箱
WriteLine(v1.nVal);
//直接输出整数值
WriteLine(v2.nVal);
printf("
Hello,world!
\n"
);
//也可以使用传统的C函数,来进行屏幕输出
return0;
}
步骤:
⏹创建“VisualC++/CLR/CLR空项目”型项目mcpp
⏹加入上面的源文件
⏹修改编译开关:
◆选“项目/[mcpp]属性页”菜单项,打开的“mcpp属性页”对话框
◆选“配置”栏中的“配置属性/C/C++/命令行”项,在右边下部的“附加选项”栏中,输入“/clr:
oldSyntax”并按“应用”钮(它会抑制原来的“/clr”开关),再按“确定”钮关闭对话框
⏹编译运行
输出结果为:
2.C++/CLI
随VisualStudio2005推出的C++/CLI是对MC++的彻底更新,并已于2005年12月成为欧洲标准——ECMA-372:
C++/CLILanguageSpecification,1stedition(December2005)(C++/CLI语言规范)。
几乎所有的程序员,对原来MC++中所提供的晦涩语法感到很痛苦。
微软也明显从用户的反馈中感觉到托管C++不是那么成功。
1)MC++的问题
MC++的语法存在的问题有:
●晦涩繁琐的语法和文法——这两个"
双重底线"
问题加重了阅读的负担;
●二流的CLI支持——相对与C# 与VB.NET,MC++使用不方便的工作区来提供CLI支持,例如,它没有一个一一对应的结构来列举.NET的集合;
●C++与.NET粗陋地结合——对于CLI类型,你不能使用C++的特色,例如模板;
同样,对于C++类型,你不能使用CLI的特色,例如碎片帐集;
●令人混淆的指针——非托管的C++的指针及托管的引用指针都使用*语法,这非常令人混淆,因为__gc指针与托管指针在本质和行为上完全不同;
●MFC编译器不能产生可校验的代码。
2)C++/CLI的优点
针对MC++的问题,C++/CLI进行了彻底的改进,它具有如下优点:
●优雅流畅的语法和文法——C++/CLI为C++开发人员书写托管代码提供了一种非常自然的感觉,并且它提供了非托管代码到托管代码的平滑过度。
以前所谓的"
问题现在已经荡然无存;
●一流的CLI支持——CLI特色,例如属性、碎片集合和属类得到了直接支持,此外,C++/CLI还准许将这些特色用于本地非托管的类;
●一流的C++类支持——C++特色,例如模板和析构函数对于拖管和非拖管类继续有效。
实际上,C++/CLI是你可以"
表面上"
在栈或C++本地堆上声明一个.NET类型唯一的.NET语言;
●在.NET与C++之间的沟壑上架起了一座桥梁——C++开发人员在抨击BCL时不再象离开水的鱼;
●C++/CLI编译器产生的可执行文件完全是可校验的。
3)改进
在C++/CLI中,将MC++中的托管关键字__gc改为ref(reference引用)、值类型关键字__value改为value、支持隐式装箱(再也不需要反复使用关键字__box了)。
在C++/CLI中,新增加了引用类类型对象的声明符“^”(称为“[跟踪]句柄”或“帽子”,用来代替原来的指针符“*”)和创建符gcnew。
C++/CLI还修改了,引用型数组的声明和创建方式:
array<
类型名[^],m>
^数组名=gcnewarray<
(n1,n2,...,nm);
其中,array是新加的关键字;
只是在引用类型的类型名后,才需要帽子符^;
m是数组的维数,缺省为1;
ni是数组第i维的大小。
4)例子
例如,1中MC++的例子,在C++/CLI中,可以改为:
//cppcli.cpp
valuestructVal{//值类型结构
refclassG{//引用类
array<
int>
^a;
//错误,托管类中不再允许有混合类型(非托管类型)
int*b;
//非托管指针,若改成int^b;
则为托管指针,不再支持__nogc
//声明sum函数
Val^pV=v;
//自动转换为托管类型,不须进行显式装箱转换
G^g=gcnewG;
b=newint[10];
//创建非托管数组
a=gcnewarray<
(100);
//不需S前缀来转换串、隐式装箱、用{i}进行托管数据的格式化输出:
WriteLine("
v.nVal,g->
a[0],g->
sum(4));
Object^oV=v;
//自动装箱后赋值给托管对象
Valv2=safe_cast<
Val>
//直接输出整数值(5)
//直接输出整数值(20)
⏹创建“VisualC++/CLR/CLR空项目”型项目cppcli
输出结果同1.中的MC++例。
3.关键字
下面是MC++和C++/CLI中新引进的非标准C++扩展关键字的列表。
注意其中C++/CLI的有些关键字是由两个单词组成的聚合关键字(aggregatekeyword)。
表9-1MC++和C++/CLI新关键字
类型
C++/CLI关键字
MC++关键字
上下文
敏感
用处
CLR数据类型
ref
class
struct
__gcclass
__gcstruct
否
定义CLR引用类
value
__valueclass
__valuestruct
定义CLR值类
interface
__interface
定义CLR接口
enum
--
定义CLR枚举
property
__property
是
定义CLR属性
delegate
__delegate
定义CLR委托
event
__event
定义CLR事件
重载说明符
abstract
__abstract
指明函数或类是抽象的
new
指明一函数不是基类版本的覆盖
override
指明一方法必须是基类版本的覆盖
sealed
__sealed
防止类被用作基类
泛型
generic
定义泛型类型
where
指定泛型类型的限制
其他
finally
__finally
指明缺省异常处理行为
foreach,in
列举集合中的元素
gcnew
在垃圾回收堆上分配类型
initonly
指明一成员只能在声明或静态构造函数中被初始化
literal
创建直接量变量
nullptr
指明句柄或指针没有指向对象
非关键字语言构造
array
表示CLR数组的类型
interior_ptr
指向引用类型内部数据
pin_ptr
__pin
指向CLR引用类型以临时抑制垃圾回收系统
safe_cast
确定并执行对CLR类型的最佳强制转换方法
typeid
获取描述给定类型或对象的System.Type对象,格式:
类型:
操作符
^
指明一对象句柄位于垃圾回收堆上
%
指明一跟踪引用
更多CLR构造
__identifier
~
允许使用C++关键字作为标识符
System.Boolean~System.Void
与C++原生类型等价的.NET框架类型,参见表9-2。
appdomain
要求静态和全局变量在每个应用域中存在的__declspec修饰符
__clrcall
指明适合CLR的调用约定
__cplusplus_cli
对应于编译开关/clr、/clr:
pure或/clr:
safe打开的预定义宏
has_assign(类型)~_is_value_class(类型)
在编译时检测类型的特征(Trait)(可用于模版类编程等),共28个
managed,unmanaged
在同一模块中指明共存的托管和非托管函数的编译指令(#pragmas)
process
要求静态和全局变量在每个进程中存在的__declspec修饰符
#using
输入外部程序集
其中,--表示没有,~表示相同。
另外,MC++中的关键字__box和__nogc,在C++/CLI中已经不需要,所以没有对应的关键字。
6.2C++/CLI编程基础
C++/CLI除了对标准C++进行了大量扩充外,还提供了一些附加功能,如:
●在C++/CLI中可以使用所有标准C++的基本数据类型,但是在某些上下文中,它们具有一些额外的属性。
●在控制台程序中,C++/CLI对键盘输入和命令行输出,提供了它自己的机制。
●C++/CLI引入了safe_cast运算符,以确保类型的强制转换操作能够生成可检验代码。
●C++/CLI提供了一种基于类的枚举功能。
1.C++/CLI的基本数据类型
表9-2对应于C++本机类型的.NET框架类型
C++类型
.NET框架类型
字节数
bool
System:
Boolean
1
char和signedchar
SByte
unsignedchar
Byte
wchar_t
Char
2
double和longdouble
Double
8
float
Single
4
int、signedint、long和signedlong
Int32
unsignedint和unsignedlong
UInt32
__int64和signed__int64
Int64
unsigned__int64
UInt64
short和signedshort
Int16
unsignedshort
UInt16
void
Void
4/8
在C++/CLI中,除了可以使用所有的标准C++基本数据类型之外,还定义了如下两种特有的8字节(64位)长的整数类型:
表9-3C++/CLI特有的整数类型
C++/CLI
.NET框架
VisualC++
字节
值域
后缀
longlong
Int64
__int64
-9223372036854775808
~9223372036854775807
LL或ll
unsignedlonglong
UInt64
unsigned__int64
0~18446744073709551615
ULL或ull
在指定longlong类型的常量时,需要在数值后面附加LL或ll后缀;
在指定unsignedlonglong类型的常量时,也需要在数值后面附加ULL或ull后缀。
longlongx=-123456LL;
unsignedlonglongy=1234567890ull;
C++/CLI还支持.NET框架的System命名空间中的Decimal值类型(一种用128个二进制位存储的可代小数点位置的28有效位的精确十进制数)。
在C++/CLI中,与.NET框架的值类型向关联的C++基本类型(参见图9-2)被添加了重要的附加功能,例如会被编译器自动装箱和拆箱(即在不同的环境下,这些类型的变量会表现为简单的值或复杂的对象)、可以使用ToString等成员函数。
将基本类型的数据表示为值类类型的对象,是C++/CLI的一个重要特性。
标准C++中的基本类型的名称是C++/CLI程序中值类型名称的别名,不过,除非需要指定整数的固定字节数,一般还是提倡使用C++中的基本类型。
2.C++/CLI的控制台输出
在C++中,一般使用printf来进行控制台输出。
但是在C++/CLI中,则是使用命名空间System中的Console类的成员函数Write或WriteLine来进行控制台输出。
例如,创建一个VisualC++的“CLR”类型的“CLR控制台应用程序”模板项目Test1:
则会自动生成包含如下主程序的项目:
//Test1.cpp:
主项目文件。
#include"
stdafx.h"
usingnamespaceSystem;
intmain(array<
String^>
^args)
{
Console:
WriteLine(L"
HelloWorld"
编译后运行,会在控制台的命令行窗口中输出文本串“HelloWorld”:
其中WriteLine的函数的功能是将指定的数据(后跟当前行结束符)写入标准输出流。
该函数有很多版本,其中常用的函数原型为:
staticvoidWriteLine(
String^format,//格式字符串
Object^arg0,//要使用format写入的第0个对象
Object^arg1,//要使用format写入的第1个对象
……
Object^argn//要使用format写入的第n个对象
该函数在输出指定格式的数据字符串后,会在末尾添加一个换行符。
Console类的另一个函数Write的格式和功能都与此函数类似,只是不在末尾加换行符。
1)格式规范
与C++中的格式化输出函数printf类似,Write[Line]函数也用格式化串来指定后面对应数据项的输出格式。
只是printf中的格式串“%[f][w][.p][F|N|h|l]type”被Write[Line]的格式符串“{n[,w][:
Axx]}”所代替。
其中,n为后跟数据项的索引值(从0开始)、w为可选的字段宽度、A为可选的单个字母(格式说明符),xx是可选的整数(精度说明符)。
格式说明符必须是某个内置格式符(参见下表)。
精度说明符的范围从0到99,它控制有效位数或小数点右边零的个数。
格式串中不能包含空白。
(可在上面项目的代码文件Test1.cpp上进行修改,下同)
inti=15;
longl=12345;
floatx=12.0f;
i=%d=0x%x,l=%ld=0x%lx;
x=%.4f=%.2e=%5g\n"
i,i,l,l,x,x,x);
i={0}=0x{0:
x},l={1}=0x{1:
x};
x={2:
f4}={2:
e2}={2,5:
g}"
i,l,x);
则输出为:
下表描述了标准数字格式字符串。
请注意,这些格式说明符产生的输出字符串受“区域选项”控制面板中的设置的影响。
使用不同设置的计算机会生成不同的输出字符串。
表9-4格式说明符
格式
说明符
名称
说明
C或c
货币
数字转换为表示货币金额的字符串。
转换由用于格式化数字的NumberFormatInfo对象的货币格式信息控制。
精度说明符指示所需的小数位数。
如果省略精度说明符,则使用NumberFormatInfo给定的默认货币精度。
D或d
十进制数
只有整型才支持此格式。
数字转换为十进制数字(0-9)的字符串,如果数字为负,则前面加负号。
精度说明符指示结果字符串中所需的最少数字个数。
如果需要的话,则用零填充该数字的左侧,以产生精