ptr_vector-一个指针的容器

来源:互联网 发布:手机淘宝联盟链接转换 编辑:程序博客网 时间:2024/06/03 19:55

 http://www.orcode.com/article/STL_20117335.html

简介

STL容器,迭代器和算法,而不是对象。值语义变得很明显的,当您尝试存储在一个标准集装箱,如指针,在一个std::vector的。你立刻感受到"阻抗失配"标准的矢量值之间的接口和存储的指针。一个额外的*(解引用)是必要的,达到指向的对象。这是烦人的,尤其是当你使用的算法。
ptr_vectorlt; TGT;是一个标准vectorlt的包装,T * GT;削减一个迭代器和成员函数的间接水平。从本质上讲,ptr_vector让你把一个指针的向量,就好像它是一个值的向量。在许多情况下,这正是你想要的。
,如果你不使用STL熟悉,在CodeProject。
ptr_vector是也。
参见代码和文章最近的变化。背景核心功能ptr_vector实现为标准C(STL)的载体的包装。迭代器遍历指向的对象,不是指针。迭代器是稳定的:ptr_vector容器扩展(标准矢量迭代器变得无效)时ptr_vector迭代器仍然有效。一些ptr_vector(即"右")的成员函数(operator []的,在(),()的前面,背面(),... ...)是指指向的对象,不是指针。不依赖第三方库 - 只是:#包括"ptr_vector.hquot;ptr_vectorlt; TGT;有相同的异常担保标准vectorlt,T * GT;成员函数提供的异常保证。ptr_vector非侵入性为指向的对象(例如,它们不需要从一个共同的基类派生)。先决条件:ptr_vector指针必须是0或NULL。
[1]为了更准确:会员功能,插入对象或脱离ptr_vector的对象有一个"指针接口",其余有一个"价值接口"。比较标准向量
一个代码片段,胜过千言万语。下面的示例比较:stdx:ptr_vectorlt; TGT;(类型T的对象的指针的一个新的容器),的std::vectorlt; TGT;(标准C类型T的对象的容器),并vectorlt,T * GT;的std::(标准C类型T的对象的指针的容器)。
以下三个代码片段打印相同的结果:你好,世界!你好,世界!你好,世界!stdx::ptr_vectorlt; TGT; ptr_vectorlt; stringgt;载体;vec.push_back(新的字符串("您好,quot;));vec.push_back(新的字符串("!世界"));法院LT,LT; VEC [0] LT,LT; vec.at(1) LT,LT; * vec.begin()LT,LT; vec.begin()[1]  0; LT,LT; vec.front()LT,LT; vec.back();:vectorlt; TGT; vectorlt; stringgt;载体;vec.push_back(字符串(quot;您好,quot;));vec.push_back(字符串("世界quot;!));法院LT,LT; VEC [0] LT,LT; vec.at(1) LT,LT; * vec.begin()LT,LT; vec.begin()[1] LT,LT; vec.front()LT,LT; vec.back();STD:vectorlt; T · GT; vectorlt;字符串* GT;载体;vec.push_back(新的字符串("您好,quot;));vec.push_back(新的字符串("!世界"));法院LT,LT; * VEC [0] LT,LT; * vec.at(1) &# 160; LT,LT; ** vec.begin()LT,LT; * vec.begin()[1] &# 160;LT,LT; * vec.front()LT,LT; * vec.back();TGT; ptr_vectorlt优势相比,vectorlt; TGT;ptr_vector不复制对象不必要的,因此它也是(不公开的拷贝构造函数和赋值运算符的对象)适用于实体对象。可容纳多态对象(例如,基类和派生对象)。有更好的异常担保(复制,而不是唯一指针指向的对象)。执行得更好(只有指针被复制,而不是...).ptr_vector扩展时,迭代器仍然有效。TGT; ptr_vectorlt相比优势vectorlt; T · GT;ptr_vector更方便,你没有看到这么​​多明星(*)在你的代码,尤其是。(STL)的算法,可用于没有特殊的比较对象直接内部,解引用指针。你不能改变一个指向一个const ptr_vectorlt对象; TGT(您可以更改指出,在一个const vectorlt对象,T * GT)。ptr_vector扩展时,迭代器仍然有效。缺点ptr_vectorlt; TGT;相比vectorlt TGT; vectorlt,T * GT;解引用一个iterator ptr_vectorlt; TGT效率略少;:迭代器vectorlt,T * GT相比;::iterator和vectorlt; TGT;:迭代器。ptr_vector的设计原则ptr_vector不构造,复制,转让,克隆,或破坏任何指向的对象。你不会失去控制指向的对象。
这是什么意思? ptr_vector往往是用来保存在堆上分配的对象(虽然它也可以包含全球或基于堆栈的对象)。 ptr_vector不提供像清晰(成员函数)和分配()这将使(特别是人迹罕至的基于堆)指向的对象被调用时,除非你有一个指针的第二个容器(另见下文)。会员功能概述功能性病::向量stdx::ptr_vector评论拷贝构造函数 - (1)=操作符(),分配() - (1)(2)开始(),rbegin() - ()的结尾,撕裂() - 调整() - (1)大小MAX_SIZE(),(),空() - ,储备容量()() - 运算符[],在() - 阵线(),回() - push_back() - pop_back() (3)插入() - - (2)(4)分离() - (4)(5)交换()  0;明确() - (2)排序() - (7)
评论:设计原则1:指向的对象不是构造,复制,分配,克隆,或通过ptr_vector销毁。设计原则2:此功能不ptr_vector提供指向的对象,因为你会失去控制。ptr_vector:pop_back()删除最后一个元素,并返回一个指向被删除的对象!使用ptr_vector:分离(以用于矢量):擦除();因为载体:擦除()返回一个迭代的第一个对象不会被删除,它违反了设计原则2。ptr_vector:分离()从容器中删除一个或多个元素(S);删除的元素是通过返回给调用者。ptr_vector:swap()的交流与ptr_vectorlt元素; TGT; vectorlt,T * GT;ptr_vector::sort()的各种指出,交换指针的对象。
你可以得到有关ptr_vector从API文档(参见下载)成员函数的更多信息。资源管理和异常安全ptr_vector_owner
ptr_vector_owner是一个可选的辅助类模板,范围后卫,ptr_vector动态创建对象的所有权(按设计,ptr_vector本身并不知道任何有关指向的对象的所有者(S))。 
"所有权"是指ptr_vector_owner在ptr_vector删除所有指向的对象时,超出范围(在其析构函数)。当然,你只需要ptr_vector_owner时,你必须用新的分配指向的对象。例子:void MYFUNC(){ ptr_vectorlt; stringgt; PTV; &# 160;ptr_vector_ownerlt; stringgt;所有者(PTV); / /范围后卫  60;ptv.push_back(新的字符串("曾几何时... ...")); / / ... IF(something.isWrong()) 抛出异常("看得真正的错误quot;); / / ... 回报;} / /指向的对象在PTV被删除!
上面的函数结束执行常规路径上的异常或返回。在这两种情况下,在ptr_vectorlt所有的对象; stringgt; PTV被删除ptr_vector_ownerlt stringgt;所有者。换句话说,ptr_vector_owner是一个著名的彗星成语的变种,叫。 建议:特设尽可能删除的对象喜欢使用ptr_vector_owner(或其他资源管理器)自动资源管理。业主(范围卫士)的工作最好的,因为在这种情况下,资源管理被封装为类成员。对象没有用户干预的情况下,如资源管理。 MyClass的{市民: MyClass的():mOwner(mPtv){} / / ...私人: ptr_vectorlt; stringgt; mPtv; ptr_vector_ownerlt; stringgt; mOwner; / /范围后卫};使用代码
下面是一个完整的例子(见下载)。例如为了使用对象的类型为std::字符串,但会做任何类(非复制)以及。完整的例子#包括LT; iostreamgt;#包括LT; stringgt;#quot; ptr_vector.hquot;使用命名空间std; / /为法院,endl,查找,替换.../ /使用命名空间stdx; ptr_vector,ptr_vector_owner主要INT(){  60; 法院LT,LT; quot ;---- ptr_vector演示---- quot; LT,LT; endl; ptr_vectorlt; stringgt; PTV; ptr_vector_ownerlt; stringgt;所有者(PTV); / /范围后卫:- ED新对象的所有者 ptv.push_back(新的字符串("; Peterquot";)); & #160;ptv.push_back(新的字符串("; Paulquot";)); ptv.insert(ptv.end(),新的字符串("; Margaretquot";)); 法院LT,LT;"1:"LT,LT; ptv.front()LT,LT;""LT,LT; ptv.back()LT,LT; endl; 法院LT,LT;"2:"LT,LT; PTV [1](2)LT,LT;""LT,LT; ptv.at LT,LT; endl; 法院LT,LT;"3:"LT,LT; * ptv.begin()LT,LT;""LT,LT; *(ptv.begin(1))LT; <endl; 法院lt,lt;"4";="" &="" #160;="" (ptr_vectorlt;="" stringgt;:迭代="ptv.begin();" =="" ptv.end();吧!)="" 法院lt,lt;""lt,lt;它;="" 法院<<endl;="" ptv.sort();="" 法院lt,lt;"5:"lt,lt;="" ptv="" [0]="" lt,lt;""lt,lt;="" [1]="" [2="" ]="" <<endl;="" ptv.sort(greaterlt;="" stringgt="" ;());="" 法院lt,lt;"6:"lt,lt;="" ptr_vectorlt;="" stringgt;:迭代iter;="" iter="(ptv.begin(),ptv.end(),"Paulquot);" (iter="ptv.end())!" 法院lt,lt;"7:"lt,lt;="" *="" lt,lt;="" endl;="" 取代(ptv.begin="" ptv.end()(),字符串("paulquot),字符串("fredquot;));="" 法院lt,lt;"8:"lt,lt;="" ptv.begin()[1]="" lt;="" <endl;="" 字符串*="" str="ptv.pop_back();" 法院lt,lt;"9:"lt,lt;="" lt,lt;"="" -="" 大小:"lt,lt;="" ptv.size()lt,lt;="" ="" 60;删除str;="" 删除ptv.detach(ptv.begin());="" 法院lt,lt;"10:"lt,lt;="" stringgt;="" ptvtwo;="" ptr_vector_ownerlt;="" ownertwo(ptvtwo);&#="" 160;="" ptvtwo.push_back(新的字符串(";="" elisabethquot";));="" susanquot";));="" ptv.swap(ptvtwo);="" (ptv="" ptvtwo)="" 法院lt,lt;"11:"lt,lt;="" ptv.begin()lt,lt;"="" ptv.size(lt);="" 返回0;}
程序的输出:ptr_vector演示---- ---- 1:彼得玛格丽特 2:保罗玛格丽特 3:彼得保罗 4:彼得保罗玛格丽特 5:玛格丽特保罗彼得 6:彼得保罗玛格丽特 7:保罗 8:弗雷德& #160; 9:玛格丽特 - 大小:2 弗雷德 - 10:大小:1 11:伊丽莎白 - 大小:2ptr_vector和标准算法问题
考虑下面的例子:ptr_vectorlt; MyClassgt; PTV;ptr_vector_ownerlt; MyClassgt;所有者(PTV);/ /插入PTV元素...STD:stable_sort(ptv.begin(),ptv.end()); / /交流MyClass的对象:(
stable_sort是一个标准的算法,传递范围内的各种元素保持相等元素的相对顺序。在上面的例子,算法低效交流(拷贝)指向的对象,在stable_sort(MyClass的对象)。但它应该只交换指针!
这同样适用于所有的算法,重新排列序列中的元素。目前尚无有效的方式来改变所需的标准算法的行为。 ptr_vector,这似乎是一个值的向量的指针的向量,只是工作不太好,在这种情况下。我们如何保持当前的方便的接口和标准算法的高效工作的根本指针?解决方案
修改后的例子:ptr_vectorlt; MyClassgt; PTV;ptr_vector_ownerlt; MyClassgt;所有者(PTV);/ /插入PTV元素...stdx:stable_sort(ptv.begin(),ptv.end()); / /交流指针  ; / / MyClass的对象!
的差异,以前面的例子可以很容易被忽视。 stable_sort算法从命名空间stdx的命名空间std算法是用来代替。 (ptr_vector还驻留在命名空间stdx)
其实,stdx:stable_sort仅仅是一个对性病瘦包装:stable_sort,引擎盖下的"正确的事":它的顺序进行排序,交换指针,而不是指向的对象。在命名空间stdx中的算法包裹算法的工作像ptr_vector指针迭代器:迭代器。只重新排列元素序列的算法,包装成为"指针知道"。非变异的算法比如std::发现不和不需要包裹,他们的工作,因为它们。已被删除,remove_if,以及独特的指针迭代器实现的,因为标准的实现不工作在这些案件中的指针(他们不工作的顺利开展与价值观,无论是)。这些算法现在只删除或覆盖的任何元素的元素进行重新排序。包装是一个简单和统一的方式进行。通常情况下,被添加到一个间接层的参数,才传递到底层的标准算法。因此,可以假设包裹算法如裹的可靠的标准算法。包裹算法列表:swap_ranges,相反,旋转,random_shuffle,分区,stable_partition,排序stable_sort,partial_sort,nth_element,inplace_merge,push_heap,pop_heap,make_heap,sort_heap,next_permutation,prev_permutation使用提示:排序算法要求operatorlt;定义为指向的对象,或者说是一个比较对象作为第三个参数传递。对于其他算法,运算符==可能是必要的。始终指出对象与检查算法的要求,在使用它之前。违反规定,通常会产生一个STL是臭名昭著的一堆难以理解的编译器错误信息。两全其美
我们已经得到了无论是现在,仅仅是重新排列指针引擎盖下和方便处理表面上的值的效率。标准算法库ptr_vector迭代器,可以直接(不交换元素的算法,)或薄包(重新排列算法)。
高级用户可以编写他们自己的算法标准迭代器和指针迭代器都使用类似标准迭代特征(见单元测试的一个例子)中发明的编译时间派遣技术工作。兴趣点单元测试
ptr_vector,ptr_vector迭代器和算法提供的单元测试(见下载)。他们不仅检查执行的正确性,但也可作为:如何用ptr_vector程序和例子如果你想使用或到一个新的编译器的端口ptr_vector ptr_vector的(虽然有问题的模板构造是可以避免的,期望的编译器和标准库不兼容)的援助。
单元测试已经证明,发展中国家和重构的代码和模板代码一般是必不可少的。通常,编译器甚至没有(彻底)语法检查,除非实际上是一个模板函数实例化。优化
ptr_vector的实现是基于标准C向量。它使用的vectorlt; T · GT;在调试模式(调试版本)和一个vectorlt;无效* GT在Release模式(发布版本)的基础容器。这就避免了在发布程序的模板"代码膨胀"。请注意,始终是强类型的ptr_vector的接口(包括迭代器)。优化内部只发生。编译器兼容性
单元测试成功编译和运行:VC + + 6.0(几种替代方法,特别是为VC 6.0实现)VC + + NET 7.1,8.0GCC 3.2,3.4(Windows)中,3.3,4.0(Linux)的EDG编译器使用网上。
除了从平时的不兼容性,ptr_vector应与大多数编译,至少温和,符合标准的C编译器和标准库。请我一张纸条,如果您有没有在上面列出的编译器编译的测试案例,也(especially!)如果您遇到编译时的错误,从而。顺便说一下,多年后,彗星标准化(1998年),编译器生产商(商业和非商业)仍然改变模板加工与每一个轻微的释放。这个事实本身表明在C模板机制的严重问题。历史注释
各种容器和指针迭代器已生产库供应商和个人开发者,基于STL的或不。例如:,,,,,,,,,... ...
C标准由于缺乏对指针的容器,可能很多自制的实现存在。谢谢
非常感谢安德烈亚斯R.本文的审阅,并用VC编译的代码的。NET 7.1。结论
ptr_vector主要目的是使在STL的容器更方便了用户的处理对象(指针)。 ptr_vectorlt; TGT;接近标准vectorlt; TGT;接口和使用方面 - 有没有需要学习一门新的"范式"。裹标准算法方便,快捷的方式,重新排列序列。 ptr_vector_owner提供了一个易于使用的正常和特殊情况下的默认资源管理器。网上资源他说:""(注:只有一个STL的一个子集,包括C标准)。"历史2004年6月6日 - 提交CodeProject上2004年12月16日 - 更新版本提交给在CodeProject实施ptr_vector迭代器包裹算法增加包裹算法的测试用例代码清理了文章:章"ptr_vector和标准算法"添加文章修改和清理2005年3月14日 - 更新版本提交给在CodeProject邮编:私有继承下降由于在迭代执行新模板查找规则(2相名称查找)由GCC 3.4执行;这个重构不影响"外"的行为文章:小的改动和更正2006年10月21日 - 更新版本提交给在CodeProject邮编:较新的编译器版本的测试与代码文章:更新的无效链接小的改动和更正
0 0
原创粉丝点击