您的位置:首页 > 编程语言 > C语言/C++

Pro visual c++/cli and .net 2.0 platform2 学习笔记(7第二章 C++/CLI基础=2)

2007-01-17 16:16 701 查看
  
用户定义的类型
值类型
只能定义三种:enum class等价enum struct,value struct,value class
struct缺省的访问限定符public,class是private。
enum和常量(const)有很多相似处:使一个值更容易被理解;也可以使一个值在一个地方定义,当改变这个值时,改变能被反映到各个使用到它的地方。不同之处:enum定义了一个新的类型(同时也就是说只有这种枚举类型的值才能赋给它),const则没有。/*如果大家不明白我翻译的,请大家参看C++primer*/
c++/CLI为枚举类型增加了选择基础类型(c++中只能是int)的功能。可以是bool, char, unsigned char, signed char, short, unsigned short, int, unsigned int, long long, unsigned long long, float,or double。
enum Creature{Dog,Cat,Eagle};
enum Vehicle:char{Car,Boat,Plane};
上面的枚举定义方法称为native enum,
另外还可以用称为“CLIenums”的语法定义
enum class Creature{Dog,Cat,Eagle};
enum struct Creature{Dog,Cat,Eagle};
Native enum和CLIenum的区别:CLIenum的值(也就是她的枚举成员)只能在枚举名的作用域内可见。这可通过代码说明:
Creature animall;
animal=Cat;//native enum
Creature animal;
animal=Creature::Cat;//clienum
/*可见CLIenum更能防止出错,比如 Color a=Fruit::Orange就会报错(Color a=Color::Orange),也就是说它的类型更强*/
value struct和value class都是非托管的。不过value struct和value class的一个拷贝可以被赋值给在托管堆上的变量。
注意:不带value的struct和class都是unsafe代码,因为他们可以用指针而不是handle来使用,而且他们是在CRT堆上,需要你自己管理。
value struct和value class都继承自System:ValueType,他们都放在栈上。
value struct和value class只能被接口继承,否则编译器报错。
引用类型
用户可以定义的引用类型:数组,类,接口和委托。建立他们的实例用gcnew。
发明了gcnew和handle就是清楚的表明你创建的是什么类型。
数组
不同于C++数组(没有垃圾收集,在crt堆上)。
继承自System::Array,可以放任何继承自System::Object类型的数据。
数组不能建立在栈上只能在托管堆上。(C++可以)
using namespace stdcli::language;//必须
array<datatype>^ arrayname;
array<int>^ fiveints=gcnew array<int>(5);//定义有5个整数的数组
array<String^>^ sevenstrings=gcnew array<String^>(7);//定义有7个String对象的数组
array<String^>^ name = gcnew array<String^> {"Stephen", "R", "G", "Fraser"};/*直接初始化*/
array<int, 3>^ Ints_5x3x2 = gcnew array<int>(5, 3,2);//多维数组
注意:多维数组的使用 a[2][3],变为a[2,3]/*更好看,更像matlab啦?我说的还对吧,有空看看matlab<todo>。*/
 
//略去jagged多维数组,感兴趣者可自己看一看
 
/*begin===========
Unsafecode:在数组里可以有非托管的数据类型,不过还是老话,在crt堆上,自己管理。
class CLASS {};
array<CLASS*>^ pClass = gcnew array<CLASS*>(5);
for (int i = 0; i < pClass->Length; i++)
pClass[i] = new CLASS();
...
for (int i = 0; i < pClass->Length; i++)
delete pClass[i];
==================*/
类,接口,托管和事件(event)
将在后面章节(3,4)介绍
装箱和拆箱
在托管扩展c++中(c++/cli的前一个版本),box和unboxing可真挺麻烦。
.net中,值类型放在栈中,这就没有办法调用它的方法,如tostring(),因为他不是对象(引用)格式。为了弥补这一点,值类型当调用方法时被隐式装箱。
value class POINT
{
public:
int x, y;
POINT(int x, int y) : x(x) , y(y) {}
};
POINT p1(1,2);

c682
将会代替下面的代码//更简明了//这里翻译的不一定对,希望高手指正
Object ^o = p1;
// -or-
POINT ^hp = p1;
 
拆箱需要类型装换:
POINT p2 = (POINT)o;
POINT p3 = (POINT)hp;
 
注意:在托管扩展c++中只有基本值类型才能被隐式装箱,.net2.0中所有值类型都被隐式装箱。
类型修饰符和限定符
auto
const限定符
c++/cli的托管数据类型包括接口不支持const成员函数
extern
static:根据被修饰者的位置(全局变量,函数中的变量,类中的变量,类中的函数)有四种不同的意义。
类型转换
建议用safe_cast<char>(a)代替(char),虽然绝大多数情况下两者是相同的。
变量作用域
global和local
名字空间
<skip>
文字(literals)
数字文字
八进制:小心0,如0246被看为166
整数
小数
指数表示的数:1.23e4=12300.0
布尔文字
字符文字
字符串文字
注释
由于嵌套块注释的问题,许多程序员选择//
操作符
这部分除了一元操作符%和解引用操作符外,对c++没有什么新的内容。
数学操作符
比较和逻辑操作符
位操作操作符
条件操作符
逗号操作符
int a = 2;
int b = 3;
int c = (b++, a = b++ * a++, a % b);
运行后结果
a = 9
b = 5
c = 4
赋值操作符
取地址,句柄引用,解引用
&
%句柄引用
*解引用:指针引用和句柄引用(c++/cli增加的)都用它来解。
注意:直接修改解引用的值被认为不可检验(unverifiable), 无法通过/clr:safe编译。
操作符优先级
<skip>
流程控制
if
switch
注意:别忘了break,否则难于找出bug。
循环结构
while
do while
别忘了while();后的分号。
for
for each
vb和c#中的东西,现在c++/cli也支持了。
for each ( <data declaration> in collection/*只能是继承于System::Collections中的IEnumerable接口的集合类,幸好大部分都是*/)
{
}
例如:
array<int>^ numbers = gcnew array<int> { 1, 2, 3, 4 };
for each ( int i in numbers )
{
Console::WriteLine(i);
}
这里有个问题,你不能在for each循环中add或remove该集合类。
Continue
打印素数的例子://不知i<多少,就会有遗漏或错误了。<todo>
for (Int32 i = 1; i < 30; i++)
{
if ( i % 2 == 0 && i / 2 > 1)
continue;
else if ( i % 3 == 0 && i / 3 > 1)
continue;
else if ( i % 5 == 0 && i / 5 > 1)
continue;
else if ( i % 7 == 0 && i / 7 > 1)
continue;
Console::WriteLine(i);
}
 
Break
函数
缺省的返回值类型为int
传递参数
传引用比传值快,为了防止意外的引用修改,可以用const修饰/*译者的理解,这样传值就没有必要了*/。
返回值
返回句柄/引用要注意:不要返回函数中局部变量的句柄/引用,而要返回通过参数传入函数中的句柄/引用或函数内部通过gcnew产生的句柄/引用。
返回引用时要注意:不要返回函数中局部变量的引用,
函数原型声明
函数重载
c++程序员需要注意的是:基本类型与他们相对应的运行时类型产生同样的signature。int等同于Int32
向main()函数传参
int main ( int argc, char *argv[] )
Unsafe,产生本地代码而不是MSIL。/clr或/clr:pure通过,/clr:safe通不过。虽然argv被自动清理,但那不是垃圾清理。
 
int main ( array<System::String ^> ^args )
一个参数,/clr:safe通过。
注意:第一个参数不是程序名,而是第一个参数了。
总结
这章对c++程序员没有太多新内容,除了:.net类库的基本数据类型,String,值类型,数组,string文字和从函数返回指针和引用          //还有句柄
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息