char * vs std ::string在c + +

什么时候应该使用std::string ,什么时候应该用char*来pipe理C ++中的char数组?

看来你应该使用char*如果性能(速度)是至关重要的,并且由于内存pipe理你愿意接受一些冒险的业务。

还有其他情况需要考虑吗?

你可以通过引用传递std :: strings,如果它们很大,以避免复制或指向实例的指针,所以我没有看到使用字符指针的真正优势。

我使用std :: string / wstring或多或less都是实际的文本。 char *对于其他types的数据是有用的,但是你可以肯定它会被释放。 否则,std :: vector是要走的路。

所有这些可能都有例外。

我的观点是:

  • 如果不调用“C”代码,千万不要使用char *。
  • 总是使用std :: string:它更容易,更友好,优化,标准,它会防止你有错误,它已被检查并certificate工作。

原始string的使用

是的,有时你真的可以做到这一点。 当使用const char *时,在堆栈和string文字上分配的字符数组,你可以这样做,根本没有内存分配。

编写这样的代码通常需要比使用string或向量更多的思考和关注,但是可以使用适当的技术来完成。 使用适当的技术,代码可以是安全的,但是您总是需要确保在复制到char []时,要么保留所复制string的长度,要么检查并处理超大的string。 不这样做是由于不安全的声誉给了这个function强大的家庭。

模板如何帮助编写安全的字符缓冲区

至于char []缓冲区的安全性,模板可以提供帮助,因为它们可以创build一个用于处理缓冲区大小的封装。 这样的模板例如由微软实现,以提供对strcpy的安全replace。 这里的例子是从我自己的代码中提取的,真正的代码有更多的方法,但是这应该足以传达基本的想法:

 template <int Size> class BString { char _data[Size]; public: BString() { _data[0]=0; // note: last character will always stay zero // if not, overflow occurred // all constructors should contain last element initialization // so that it can be verified during destruction _data[Size-1]=0; } const BString &operator = (const char *src) { strncpy(_data,src,Size-1); return *this; } operator const char *() const {return _data;} }; //! overloads that make conversion of C code easier template <int Size> inline const BString<Size> & strcpy(BString<Size> &dst, const char *src) { return dst = src; } 

在下列情况下你应该考虑使用char*

  • 这个数组将被传入参数。
  • 你事先知道你的数组的最大大小(你知道它或者你强加它)。
  • 你不会对这个数组做任何转换。

实际上,在C ++中, char*经常用于固定的小字,作为选项,文件名等等。

有一点你必须使用char *而不是std :: string,当你需要静态string常量的时候。 原因是你没有任何控制命令模块初始化它们的静态variables,另一个来自不同模块的全局对象可能会在初始化之前引用你的string。 http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Static_and_Global_Variables

std :: string优点:

  • 为你pipe理内存(string可以增长,实现将分配一个更大的缓冲区)
  • 更高层次的编程接口,与STL的其他部分很好地协同工作。

std :: string缺点:两个不同的STLstring实例不能共享相同的底层缓冲区。 所以,如果你通过价值传递你总是得到一个新的副本。 – 有一些性能损失,但我会说,除非你的要求是特殊的,它是微不足道的。

何时使用c ++ std :: string:

  • 总的来说,string比char *更安全,通常当你用char *做事情时,你必须检查事情以确保事情是正确的,在string类中,所有这些都是为你完成的。
  • 通常当使用char *的时候,你将不得不释放你分配的内存,你不需要用string来做这件事,因为它会在被破坏的时候释放它的内部缓冲区。
  • string与c ++ stringstream很好地工作,格式化IO非常容易。

何时使用char *

  • 使用char *可以更好地控制场景后面发生的事情,这意味着如果需要的话可以调整性能。

如果正在编写库,请使用(const)char *作为参数。 不同编译器之间的std :: string实现有所不同。

如果你想使用C库,你将不得不处理Cstring。 如果您想将您的API暴露给C,则同样适用

你可以期望std :: string上的大多数操作(例如find )尽可能优化,所以它们可能至less和纯C的操作符一样好。

还值得注意的是,std :: string迭代器通常映射到指向底层char数组的指针。 因此,在迭代器之上devise的任何algorithm在性能上与char *之上的algorithm基本相同。

要注意的是例如operator[] – 大多数STL实现不执行边界检查,并应将其转换为基础字符数组上的相同操作。 AFAIK STLPort可以select执行边界检查,此时这个运算符会慢一点。

那么使用std :: string会得到什么呢? 它免除你手动内存pipe理; 调整数组的大小变得更容易,而且你通常不得不考虑释放内存。

如果在调整string大小时担心性能,可能会有一个reservefunction,您可能会觉得有用。

如果你正在使用像文本等字符数组使用std ::string更灵活,更容易使用。 如果你把它用于其他的数据存储? 使用数组(更喜欢vector)

即使性能至关重要,您最好使用vector<char> – 它允许提前分配内存(reserve()方法),并且可以帮助您避免内存泄漏。 使用vector :: operator []会导致开销,但是您总是可以提取缓冲区的地址,并将其索引为如果它是char *。

AFAIK内部大多数std :: string实现拷贝写入,引用计数语义以避免开销,即使string没有被引用传递。