大学IT网 - 最懂大学生的IT学习网站! QQ资料交流群:367606806
当前位置:大学IT网 > C++技巧 > C++/CLI中栈对象的设计问题

C++/CLI中栈对象的设计问题

关键词:对象设计CLI  阅读(549) 赞(10)

[摘要]本文是对C++/CLI中栈对象的设计成果的讲解,对学习C++编程技术有所协助,与大家分享。

  C++/CLI中新推出的自动确定性资源回收(Automatic deterministic destruction)被视为一个优秀的设计。是运用所谓C++/CLI这个“新瓶”来装Bjarne Stroustrup提出的RAII这个“旧酒”。

  这确实不错,绝对而言,这个比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中的栈对象只是为了取得自动确定性资源回收而存在?值得这样做吗?



相关评论