effective STL - 尽量使用vector和string来代替动态分配的数组(char *)

35 篇文章 2 订阅

 

尽量使用vector和string来代替动态分配的数组

这一刻,你决定使用new来进行动态分配,你需要肩负下列职责:

  1. 你必须确保有的人以后会delete这个分配的内存。如果后面没有delete,你的new就会产生一个内存泄漏。
  2. 你必须确保使用了delete的正确形式。对于分配一个单独的对象,必须使用“delete”。对于分配一个数组,必须使用“delete []”。如果使用了delete的错误形式,结果会未定义。在一些平台上,程序在运行期会当崩溃。另一方面,它会默默地走向错误,有时候会造成内存泄露。
  3. 你必须确保只delete一次。如果一个分配被删除了不止一次,结果也会未定义。

职责真多,而且我不能理解为什么如果可以省心你却还要负责。感谢vector和string,用了它们就可以不像以前那么麻烦了。

 

无论何时,你发现你自己准备动态分配一个数组(也就是,企图写“new T[...]”),你应该首先考虑使用一个vector或一个string。(一般来说,当T是一个字符类型的时候使用string,否则使用vector,但我们在本条款的后面将遇到的情况中,vector<char>可能是一个合理的设计选择。)vector和string消除了你的负担,因为它们管理自己的内存。当元素添加到那些容器中时它们的内存会增长,而且当一个vector或string销毁时,它的析构函数会自动销毁容器中的元素,回收存放那些元素的内存。

 

另外,vector和string是功能丰富的序列容器,他们不仅可以支持数组的操作,还有着更多的功能。虽然数组也可以用于STL算法,但没有提供像begin、end和size这样的成员函数,也没有内嵌像iterator、reverse_iterator或value_type那样的typedef。而且char*指针当然不能和提供了专用成员函数的string竞争。

 

如果你关心你必须继续支持的遗留代码,它们都是基于数组的,放松点,无论如何都应该使用vector和string。vector和string可以和

原生数组进行无缝连接。

 

坦白地说,我想到了一个(也是唯一一个)用vector或string代替动态分配数组会出现的问题,而且它只关系到string。很多string实现在后台使用了引用计数(参见条款15),一个消除了不必要的内存分配和字符拷贝的策略,而且在很多应用中可以提高性能。事实上,一般认为通过引用计数优化字符串很重要,所以C++标准委员会特别设法保证了那是一个合法的实现。

 

唉,一个程序员的优化就是其他人的抱怨,而且如果你在多线程环境中使用了引用计数的字符串,你可能发现避免分配和拷贝所节省下的时间都花费在后台并发控制上了。(细节请参考Sutter的文章《Optimizations That Aren't (In a Multithreaded World)》[20]。)如果你在多线程环境中使用引用计数字符串,就应该注意线程安全性支持所带来的的性能下降问题。

 

要知道你正在使用的string实现是否是引用计数的,通常最简单的方式是参考库的文档。因为通常认为引用计数是一种优化,制作商一般把它作为一个特性来吹捧。另一种方法是看库的string实现的源代码。我一般不推荐尝试从库源代码中得到东西,但有时候这是唯一能找出你想知道的东西的方法。如果你选择了这个方法,就要记住string是一个basic_string<char>的typedef(而wstring是basic_string<wchar_t>的typedef),所以你真正需要看的是basic_string模板。

 

最容易检查的地方是可能的类构造函数。看看它是否在某处增加了引用计数。如果是,string就是引用计数的。如果不是,要么就是string不是引用计数,要么就是你看错了代码。呵呵。

 

如果你用到的string实现是引用计数的,而你想在已经确定string的引用计数支持是一个性能问题的多线程环境中运行,你至少有三个合理的选择,而且没有一个放弃了STL。第一,看看你的库实现是否可以关闭引用计数,通常是通过改变预处理变量的值。当然那是不可移植的,但使工作变得可能,值得研究。第二,寻找或开发一个不使用引用计数的string实现(或部分实现)替代品。第三,考虑使用vector<char>来代替string,vector实现不允许使用引用计数,所以隐藏的多线程性能问题不会出现了。当然,如果你选择了vector<char>,你就放弃了string的专用成员函数,但大部分功能仍然可以通过STL算法得到,所以你从一种语法切换到另一种不会失去很多功能。

 

所有的结果都是简单的。如果你在使用动态分配数组,你可能比需要的做更多的工作。要减轻你的负担,就使用vector或string来代替。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值