为什么在C ++中使用std :: string而不是c风格的字符串?

时间:2012-04-05 03:01:36

标签: c++ string c-strings

“人们应该总是使用 std::string 而不是c风格的字符串(char *)”这是几乎所有在此处发布的源代码的建议。虽然建议无疑是好的,但实际解决的问题不允许详细阐述建议的为什么?方面。这个问题是作为占位符。

一个好的答案应该包括以下几个方面(详细):

  1. 为什么要在C ++中使用std::string而不是c-style字符串?
  2. #1中提到的做法有哪些缺点(如果有的话)?
  3. #1中提到的建议相反的情况是一种好的做法是什么?

6 个答案:

答案 0 :(得分:13)

  1. std :: string管理自己的内存,因此您可以轻松地复制,创建和销毁它们。
  2. 您不能将自己的缓冲区用作std :: string。
  3. 您需要将c字符串/缓冲区传递给期望获取缓冲区所有权的内容 - 例如第三方C库。

答案 1 :(得分:4)

好吧,如果只是需要一个字符数组,std :: string几乎没有什么优势。但面对现实,这种情况多少次?通过使用std :: string等附加功能包装char数组,您可以获得某些操作的功能和效率。

例如,确定字符数组的长度需要“计算”数组中的字符。相反,std :: string为此特定任务提供了有效的操作。 (见https://stackoverflow.com/a/1467497/129622

  1. 力量,效率和理智
  2. 内存占用量大于“只是”char数组
  3. 需要一组字符

答案 2 :(得分:2)

3)建议始终使用string当然必须采取一些常识。字符串文字是const char[],如果你将一个文字传递给一个带const char*的函数(例如std::ifstream::open()),那么绝对没有必要将它包装在std::string中。

答案 3 :(得分:1)

char *基本上是指向角色的指针。 C做的经常使这个指针指向数组中的第一个字符。

std :: string是一个非常像向量的类。在内部,它处理一个字符数组的存储,并为用户提供几个成员函数来操作所述存储的数组以及几个重载的操作符。

在std :: string上使用char *的原因:

C backwards-compatibility.
Performance (potentially).
char*s have lower-level access.

在char *:

上使用std :: string的原因
Much more intuitive to use.
Better searching, replacement, and manipulation functions.
Reduced risk of segmentation faults.

示例:

char *必须与char数组或动态分配的char数组一起使用。毕竟,指针是没有价值的,除非它实际指向某事。这主要用于C程序:

char somebuffer[100] = "a string";
char* ptr = somebuffer;  // ptr now points to somebuffer
cout << ptr; // prints "a string"
somebuffer[0] = 'b';  // change somebuffer
cout << ptr;  // prints "b string" 

请注意,当您更改'somebuffer'时,'ptr'也会发生变化。这是因为somebuffer在这种情况下是实际的字符串。 ptr只是指/指它。

使用std :: string它不那么奇怪:

std::string a = "a string";
std::string b = a;
cout << b;  // prints "a string"
a[0] = 'b';  // change 'a'
cout << b;  // prints "a string" (not "b string") 

在这里,你可以看到改变'a'不会影响'b',因为'b'是实际的字符串。

但实际上,主要区别在于使用char数组,你负责管理内存,而std :: string则为你做。在C ++中,使用char数组而不是字符串的原因很少。 100个中的99次你最好用一根绳子。

在完全理解内存管理和指针之前,只需要节省一些麻烦并使用std :: string。

答案 4 :(得分:1)

  

为什么要在C ++中使用st-:: string而不是c-style字符串?

主要原因是它使您无需管理字符串数据的生命周期。您可以将字符串视为值,让编译器/库担心管理内存。

手动管理内存分配和生命周期是单调乏味且容易出错的。

  

#1中提到的做法有哪些缺点(如果有的话)?

您放弃了对内存分配和复制的细粒度控制。这意味着您最终会得到工具链供应商选择的内存管理策略,而不是选择符合程序需求的内存管理策略。

如果您不小心,最终可能会导致大量不必要的数据复制(在非refcounted实现中)或引用计数操作(在refcounted实现中)

在混合语言项目中,任何参数使用std :: string或任何包含std :: string的数据结构的函数都不能直接在其他语言中使用。

  

与#1中提到的建议相反的情况是一种好的做法是什么?

不同的人会对此有不同的意见,但IMO

  • 对于在&#34; const char *&#34;中传递字符串的函数参数是一个很好的选择,因为它避免了unnessaceacery复制/ refcouning,并给予调用者他们传递的灵活性。
  • 对于与其他语言互操作的东西,你别无选择,只能使用c风格的字符串。
  • 当你有一个已知的长度限制时,使用固定大小的数组可能会更快。
  • 当处理非常长的字符串时,最好使用一个肯定会被重新计算而不是复制的结构(例如包装在shared_ptr中的字符数组)或者确实使用不同类型的数据结构

答案 5 :(得分:-1)

一般来说,你应该总是使用std :: string,因为它不易出错。请注意,std :: string的内存开销很大。最近我做了一些关于std :: string开销的实验。一般来说它大约是48个字节!文章在这里:http://jovislab.com/blog/?p=76