std::string与char*的区别

14
std::string和char*在堆栈上存储数据的方式是否不同,或者std::string只是从char*派生而来的类?

6
指针(特别是char*)不是类类型,不能派生自类。 :-) - C. K. Young
3个回答

13

char*

  • 它的大小取决于你的CPU架构中一个指针的大小。
  • 可能是malloccallocnewnew[]返回的值。
    • 如果是这样,当使用完毕后必须传递给freedeletedelete[]
    • 如果是这样,字符存储在堆上。
  • 可能是由char[ N ](常量N)数组或字符串文字的“分解”结果。
    • 通用地,无法确定char*参数指向堆栈、堆还是全局空间。
  • 不是类类型。虽然参与表达式但没有成员函数。
  • 仍然实现了RandomAccessIterator接口以供<algorithm>等使用。

std::string

  • 它的大小通常为三个指针大小。
  • 创建时会自动构造自己:不需要使用newdelete
    • 如果字符串可能被更改,则拥有该字符串的副本。
    • 可以从char*复制此字符串。
    • 默认情况下,内部使用new[]获取char*
  • 提供隐式转换,使得从char*或字面量构造变得透明。
  • 是类类型。定义其他运算符用于表达式的串联。
    • 定义c_str(),它返回一个char*以供临时使用。
  • 实现了std::string::iterator类型,具有begin()end()函数。
    • string::iterator 是灵活的:实现可以通过开关将其变为范围检查的高安全性调试辅助工具,也可以将其简单地变成超高效的 char*

5
如果您的意思是是否连续存储,那么答案是不需要,但所有已知(至少对我来说)的实现都这样做。这很可能是为了支持c_str()和data()成员要求,即返回一个连续的字符串(在c_str()的情况下以空字符结尾)。
就存储内存的位置而言,它通常位于堆上。但有些实现采用“短字符串优化”,其中短字符串内容存储在小型内部缓冲区中。因此,在字符串对象在栈上的情况下,存储的内容可能也在栈上。但这对您的使用方式应该没有影响,因为一旦对象被销毁,存储字符串数据的内存在任何情况下都会失效。
(顺便说一句,这里有一篇关于类似技术的文章,介绍了优化方法。)

6
C++0x委员会发现当前所有的实现都是连续存储,因此他们决定加强语言并将其作为要求。很抱歉我没有相关引用来支持这一点。 - Mark Ransom
1
@Mark Ransom:好观点,不过这只适用于C++0x+;C++98/03没有这个要求。 - dcw
3
@Mark:这是你要找的参考文献链接:http://herbsutter.com/2008/04/07/cringe-not-vectors-are-guaranteed-to-be-contiguous/#comment-483 和 http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#530。 - Carl

2
这些解决不同的问题。 char*(或char const*)指向C风格的字符串,该字符串并不一定由存储char*指针的人拥有。在C中,由于缺乏字符串类型,通常将char*用作“字符串类型”。std::string拥有其指向的字符串数据。因此,如果您需要在类中存储字符串,则很可能要使用std::string或您的库的字符串类,而不是char*
关于std::string存储的连续性,其他人已经回答了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接