使用vector和string代替动态申请的数组

 
若我们决定使用new来进行动态分配,需要肩负下列职责:
# 必须确保有的人以后会delete这个分配。如果后面没有delete,我们的new就会产生一个资源泄漏。
# 必须确保使用了delete的正确形式。对于分配一个单独的对象,必须使用“delete”。对于分配一个数组,必须使用“delete []”。如果使用了delete的错误形式,结果会未定义。在一些平台上,程序在运行期会当掉。另一方面,它会默默地走向错误,有时候会造成资源泄漏,一些内存也随之而去。
#必须确保只delete一次。如果一个分配被删除不止一次,结果再次未定义。
 
这里的职责真多,用了vector和string就可以不像以前那么麻烦了。
 
无论何时,发现自己准备动态分配一个数组(也就是,企图写“new T[...]”),应该首先考虑使用一个vector或一个string。(一般来说,当T是一个字符类型的时候使用string,否则使用vector,)vector和string消除了上面的负担,因为它们管理自己的内存。当元素添加到那些容器中时它们的内存会增长,而且当一个vector或string销毁时,它的析构函数会自动销毁容器中的元素,回收存放那些元素的内存。
 
另外,vector和string是羽翼丰满的序列容器,所以它们让我们支配可以作用于这样的容器的整个STL算法。虽然数组也可以用于STL算法,但没有提供像begin、end和size这样的成员函数,也没有内嵌像iterator、reverse_iterator或value_type那样的typedef。而且char*指针当然不能和提供了专用成员函数的string竞争。STL用的越多,越会歧视内建的数组。
 
如果关心必须继续支持的遗留代码,它们都是基于数组的,可以把vector和string中的数据传给需要array的API,所以整合遗留代码一般都没有问题。
 
坦白地说,有一个(也是唯一一个)用vector或string代替动态分配数组会出现的问题,而且它只关系到string。很多string实现在后台使用了引用计数,一个消除了不必要的内存分配和字符拷贝的策略,而且在很多应用中可以提高性能。事实上,一般认为通过引用计数优化字符串很重要,所以C++标准委员会特别设法保证了那是一个合法的实现。
 
如果在多线程环境中使用了引用计数的字符串,可能发现避免分配和拷贝所节省下的时间都花费在后台并发控制上了。如果在多线程环境中使用引用计数字符串,就应该注意线程安全性支持所带来的的性能下降问题。
 
要知道正在使用的string实现是否是引用计数的,通常最简单的方式是参考库的文档。因为通常认为引用计数是一种优化,制作商一般把它作为一个特性。另一种方法是看库的string实现的源代码。一般不推荐尝试从库源代码中得到东西,但有时候这是唯一能找出想知道的东西的方法。如果选择了这个方法,就要记住string是一个basic_string<char>的typedef(而wstring是basic_string<wchar_t>的typedef),所以真正需要看的是basic_string模板。最容易检查的地方是可能的类构造函数。看看它是否在某处增加了引用计数。如果是,string就是引用计数的。
 
如果用到的string实现是引用计数的,而想在已经确定string的引用计数支持是一个性能问题的多线程环境中运行,至少有三个合理的选择,而且没有一个放弃了STL。第一,看看这个库实现是否可以关闭引用计数,通常是通过改变预处理变量的值。当然那是不可移植的,但使工作变得可能,值得研究。第二,寻找或开发一个不使用引用计数的string实现(或部分实现)替代品。第三,考虑使用vector<char>来代替string,vector实现不允许使用引用计数,所以隐藏的多线程性能问题不会出现了。当然,如果选择了vector<char>,就放弃了string的专用成员函数,但大部分功能仍然可以通过STL算法得到,所以从一种语法切换到另一种不会失去很多功能。
 
所有的结果都是简单的。如果在使用动态分配数组,可能比需要的做更多的工作。要减轻的负担,就使用vector或string来代替。
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值