科技时代新浪首页 > 科技时代 > 学园 > 正文

C++/CLI解析之基于堆栈的对象与跟踪引用(2)


http://www.sina.com.cn 2006年10月18日 09:15 天极yesky

  取句柄操作符

  如果想把p1的值写到标准输出,代码似乎应该像下面这样:

Console::WriteLine("p1 is {0}", p1);

  然而,这却不能通过编译,因为WriteLine没有一个可接受Point的重载版本。前面也提过,任何值类型的表达式(如int、long、double)会由一个"装箱"的过程,自动转换为Object^。虽然p1看上去比较像一个值类型的实例,但它实际上却不是,它是一个引用类的实例,所以代码需要这样修改: Console::WriteLine("p1 is {0}", %p1);

  通过使用一元 % 操作符,我们创建了对象p1的一个句柄,因为每个引用类最终都是从System::Object继承的,而WriteLine也有一个其第二个参数可接受Object^的重载版本,所以,%p1的Point^就转换为Object^,并显示出p1相应的值。要留意的是,此处没有装箱,但这个操作符不能应用到本地类的实例上。

  GC-Lvalues

  在C++标准中定义及使用了lvalue术语,而C++/CLI标准则添加了gc-lvalue术语,其指"一个引用CLI堆中对象、或包含此对象的数值成员的表达式"。如果有一个指向gc-lvalue的句柄,可对其使用一元 * 操作符来产生一个gc-lvalue;而跟踪引用也是一个gc-lvalue,当%h中h是一个句柄时,它也可以产生一个gc-lvalue。(因为有从lvalue至gc-lvalue的标准转换,所以一个跟踪引用可绑定至任意的gc-lvalue或lvalue。)

  拷贝构造函数

  在下面的例子中,p6由给定的坐标构造而成,而p7则初始化为p6的一个副本,这就需要Point有一个拷贝构造函数;然而,在默认情况下,编译器不会为这些引用类产生一个拷贝构造函数。那么,在这种情况下,就必须自己编写一个。

Point p6(3,4), p7 = p6;

  以下,是Point的拷贝构造函数:

Point(Point% p)
{
 X = p.X;
 Y = p.Y;
}

  而对一个本地类N的拷贝构造函数,一般声明成如下形式:

N(const N& n);

  但是,对引用类来说,因为%取代了&,所以在CLI的世界中,const显得有点格格不入。

  赋值操作符

  以下表达式:

p7 = p6;

  就需要一个赋值操作符,但再次提醒,这不是自动提供的。以下就是一个自定义的操作符例子:

Point% operator=(Point% p)
{
 X = p.X;
 Y = p.Y;
 return *this;
}

  之所以没有提供默认的拷贝构造函数或赋值操作符,是因为所有的引用类(除了System::Object),都有一个基类:System::Object,而这个类并没有提供一个拷贝构造函数或赋值操作符。基本上,这两者默认都会调用它们基类中相应的实现版本,但基类中却一个对应的定义也没有。

[上一页] [1] [2] [3] [4] [下一页]

本文导航:
·C++/CLI解析之基于堆栈的对象与跟踪引用
·C++/CLI解析之基于堆栈的对象与跟踪引用(2)
·C++/CLI解析之基于堆栈的对象与跟踪引用(3)
·C++/CLI解析之基于堆栈的对象与跟踪引用(4)

发表评论 _COUNT_条

爱问(iAsk.com)



评论】【论坛】【收藏此页】【 】【多种方式看新闻】【下载点点通】【打印】【关闭




科技时代意见反馈留言板 电话:010-82628888-5595   欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

Copyright © 1996 - 2006 SINA Inc. All Rights Reserved

新浪公司 版权所有