85

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

char*如果性能(速度)至关重要并且由于内存管理而愿意接受一些有风险的业务,您似乎应该使用。

还有其他需要考虑的场景吗?

4

12 回答 12

58

我的观点是:

  • 如果您不调用“C”代码,切勿使用 char *。
  • 始终使用 std::string:它更容易,更友好,经过优化,是标准的,它可以防止你出现错误,它已经过检查并证明可以工作。
于 2009-04-29T08:16:54.537 回答
57

如果 s 很大以避免复制,或者指向实例的指针,您可以通过std::string引用传递,所以我看不出使用char指针有什么真正的优势。

我使用std::string/wstring或多或少的所有实际文本。char *但是对于其他类型的数据很有用,您可以确定它会像应有的那样被释放。否则std::vector<char>就是要走的路。

所有这些可能都有例外。

于 2009-04-29T07:20:41.193 回答
14

原始字符串使用

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

编写这样的代码通常比使用字符串或向量需要更多的思考和谨慎,但使用适当的技术是可以做到的。使用适当的技术,代码可以是安全的,但是您始终需要确保在复制到 char [] 时,您要么对要复制的字符串的长度有一定的保证,要么优雅地检查和处理过大的字符串。不这样做是给 strcpy 系列函数带来不安全声誉的原因。

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

至于 char [] 缓冲区的安全性,模板可以提供帮助,因为它们可以创建一个封装来为您处理缓冲区大小。像这样的模板由 Microsoft 实施,以提供 strcpy 的安全替换。这里的例子摘自我自己的代码,真实的代码还有很多方法,但这应该足以传达基本思想:

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;
}
于 2009-04-29T08:12:54.313 回答
9

当您需要静态字符串常量时,您必须使用char*而不是使用的一种情况。std::string原因是您无法控制模块初始化其静态变量的顺序,并且来自不同模块的另一个全局对象可能会在初始化之前引用您的字符串。http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Static_and_Global_Variables

std::string优点:

  • 为您管理内存(字符串可以增长,实现将为您分配更大的缓冲区)
  • 更高级别的编程接口,可以很好地与 STL 的其余部分配合使用。

std::string缺点: - 两个不同的 STL 字符串实例不能共享相同的底层缓冲区。因此,如果您按值传递,您总是会得到一个新副本。- 有一些性能损失,但我会说除非你的要求是特殊的,否则它可以忽略不计。

于 2009-04-29T07:56:13.027 回答
8

您应该考虑char*在以下情况下使用:

  • 该数组将传入参数。
  • 您事先知道数组的最大大小(您知道或强加它)。
  • 您不会对此数组进行任何转换。

实际上,在 C++ 中,char*通常用于固定的小字,如选项、文件名等...

于 2009-04-29T07:17:29.687 回答
5

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

  • strings,总的来说,比 s 更安全char*,通常当你在做事情时,char*你必须检查事情以确保事情是正确的,在string课堂上这一切都是为你完成的。
  • 通常在使用时char*,您必须释放分配的内存,您不必这样做,string因为它会在销毁时释放其内部缓冲区。
  • strings 与 c++ 配合得很好stringstream,格式化 IO 非常容易。

何时使用 char *

  • 使用char*使您可以更好地控制“幕后”发生的事情,这意味着您可以根据需要调整性能。
于 2009-04-29T07:54:05.327 回答
4

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

于 2009-04-29T14:59:38.780 回答
3

如果要使用 C 库,则必须处理 C 字符串。如果您想将 API 公开给 C,同样适用。

于 2009-04-29T07:54:33.110 回答
2

您可以期望 std::string 上的大多数操作(例如 eg find)尽可能优化,因此它们的性能可能至少与纯 C 对应物一样好。

还值得注意的是,std::string 迭代器经常映射到指向底层 char 数组的指针。因此,就性能而言,您在迭代器之上设计的任何算法本质上都与基于 char * 的相同算法相同。

需要注意的事情是例如operator[]- 大多数 STL 实现不执行边界检查,并且应该将其转换为对底层字符数组的相同操作。AFAIK STLPort 可以选择执行边界检查,此时此运算符会慢一些。

那么使用 std::string 有什么好处呢?它使您免于手动内存管理;调整数组的大小变得更容易,而且您通常不必考虑释放内存。

如果您在调整字符串大小时担心性能问题,那么reserve您可能会发现一个有用的函数。

于 2009-04-29T08:16:28.843 回答
1

如果您在文本等中使用字符数组,则使用 std::string 更灵活且更易于使用。如果您将其用于数据存储等其他用途?使用数组(首选向量)

于 2009-04-29T07:11:27.300 回答
1

即使性能至关重要,您也可以更好地使用vector<char>- 它允许提前分配内存(reserve() 方法)并帮助您避免内存泄漏。使用 vector::operator[] 会导致开销,但您始终可以提取缓冲区的地址并对其进行索引,就像它是 char* 一样。

于 2009-04-29T07:15:50.207 回答
-1

AFAIK 在内部大多数 std::string 实现写入时复制,引用计数语义以避免开销,即使字符串不是通过引用传递的。

于 2009-04-29T08:07:30.410 回答