C /CLI中栈对象的设计问题
2008-02-23 05:05:27来源:互联网 阅读 ()
这的确不错,相对而言,这个比C#中的using 关键字(dispose模式),连同Java中的hard-coded的dispose方法都要好许多。这个特性是由C /CLI中栈对象(局部对象)来提供的,局部对象本身没错,RAII也是局部对象应有之义。
但问题在于C /CLI中栈对象的可用性由于许多原因会大打折扣,使用起来已远远不如ISO-C 中那样流畅。下面列出了损伤其可用性的几大硬伤:
#1、C /CLI的栈对象并非真的位于栈中
只要类型是ref class,C /CLI中的栈对象就仍位于托管堆中。仍然使用newobj IL指令来分配。假如R没有定义析构器(~R)(注意:C /CLI中的析构器和C#中的析构器完全两回事),那么下面两行代码实际上将生成完全相同的IL代码:
R r;
R h=gcnew R;
似乎记得Herb Sutter曾说过他们将来可能会在真正的方法栈中分配r ——说实话恐怕只有C 背景的人敢这么“胡思乱想”:) 他们现在只是想在语法层面让程式员"感觉"就像r是从栈中分配的相同。又一个syntax sugar:)
当然为了对称和语义的完美,有时候还需要在r上应用%——虽然背后仍是什么也没做:)
#2、C /CLI编译器默认情况下不会自动产生拷贝构造函数和拷贝赋值操作符
这一点很令人烦恼,几乎让人“望栈对象而却步”。更糟糕的是BCL中的任何类型都没有提供拷贝构造函数和拷贝赋值操作符——因为恐怕只有C /CLI会用到他们。
话说回来,即使C /CLI会自动产生拷贝构造函数和拷贝赋值操作符,那么继承自BCL的类型还是会很麻烦。
#3、假如函数要被其他CLI语言调用,那么就不能将其参数设计为栈对象
a. static void add(R r){...}
编译出来有一个modopt元数据,所以能够被其他语言调用,但是假如被其他语言调用,比如C#,那么其他语言将是以传值的方式传递引用,而C /CLI将是传递对象拷贝(要调用拷贝构造器),所以语义混乱,完全不能够这样做。
b. static void add(R% r){...}
由于编译出来都有一个modreq元数据,所以不能被其他CLI语言调用。
#4、假如函数要被其他CLI语言调用,那么也不能将其返回值设计为栈对象
a. static R add(){...}
b. static R% add(){...}
两者编译出来都有一个modreq元数据,所以都不能被其他CLI语言调用。
#5。使用BCL时,假如要传递栈对象,总要使用“莫名其妙”的%操作符
比如:
String s("abc");
ArrayList list;
list.Add(%s);
实在很不好,还是使用追踪引用比较好:
String^ s="abc";
ArrayList^ list=gcnew ArrayList();
list->Add(s);
总结一下:
#1和#5对栈对象的可用性影响不算大,毕竟从语义层面来理解,还是行得通的。
但是,#2、#3、#4的影响就很大。#3和#4使得我们必须放弃使用栈对象来进行互操作。而#2会让编写C /CLI代码很的不方便——除非您以后不想使用栈对象。
现在的问题是,是否C /CLI中的栈对象只是为了获得自动确定性资源回收而存在?值得这样做吗?
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇: 利用C#实现标准的Dispose模式
下一篇: 浅议C /CLI的gcnew关键字
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash