何时应该在字符数组上使用std :: string?

时间:2014-04-30 08:38:44

标签: c++ string character-arrays

当我设计类接口时,我常常坐下来思考是否应该经常使用const char*const std::string&,当它归结为它时,我常常觉得有6个另一方面,另一方面有六打。

采用以下两个函数原型:

void foo(const char* str);
void foo(std::string str);

如果foo函数存储一个字符串,我会说第二个是更好的选择,因为能够传递字符串并尽可能利用移动语义。但是,如果foo只需要读取字符串,那么const char*解决方案会更好吗?

从性能角度来看,不需要创建临时std::string。但是,使用已存在的字符串作为参数调用该函数看起来很突出:foo(mystr.c_str())。更糟糕的是,如果需要在未来的某个时刻对阵列进行更高级的操作,或者如果应该存储副本,则接口必须更改。

所以我的问题是:

std::stringconst char*是更好的选择时,是否有明确定义的个人或其他约定?此外,在开始一个新项目时,最好是与用法保持一致,还是只选择最适合当前代码块的那个?

7 个答案:

答案 0 :(得分:51)

const char*是C的回归。我会说在体面的C ++中,关于它的唯一用途是extern "C" API。

std::string有许多优点:

  1. 它提供了一个恒定时间size()功能。发现const char*的长度需要线性时间。

  2. 保证有效。必须检查const char*是否为空,并且完全可以传递不正确的数据 - 数据缺少空终止符。这种情况几乎可以保证导致崩溃或更糟。

  3. 它与标准算法兼容。

  4. 如果您担心必须创建std::string来调用该函数会对性能产生影响,请考虑采用标准库使用的方法 - 将函数更改为使用一对迭代器。然后,您可以提供一个方便的重载,将const std::string&委托给迭代器对。

答案 1 :(得分:19)

个人经历中的一些注释。如果您正在处理一个c ++项目(根据您添加的标记),请尽可能多地提供std::string。不要试图重新发明所有结构中最基本的结构,即全能的字符串。我看到几个项目,他们重新发明了基本的字符串,然后花了几个月微调它。

如果您的c ++项目从您引入char*变量的那一刻开始,您将回归到标准C函数,例如strlen()strcpy(仅举两个... )。从这一点开始,你的项目开始变得混乱,手动管理内存分配等......

如果您需要与接受const char*作为参数的第三方库进行交互(我认为您信任这些库 - 即:您相信他们不会const_cast远离常量做恶你可怜的字符串)你可以使用std::string::c_str()从字符串中获取const char*

如果您需要与接受char*方法的库进行交互,我强烈建议您复制字符串的c_str()并将其用作库的输入参数(当然,请执行此操作)不要忘记删除额外的副本。)

除了这些额外的观点之外,我只赞同Angew的回应中的所有三点。

答案 2 :(得分:6)

std::string应始终是c ++的首选。为避免额外的复制开销,您几乎应该始终将参数作为参考传递,并尽可能地const引用。

在这种情况下,您的功能签名将变为如此

  

void foo(std :: string& str);

并且像这样,如果参数是const

  

void foo(const std :: string& str);

这个const关键词有好处,你可以看here

答案 3 :(得分:4)

std :: string比使用原始字符*更好,你必须管理分配,解除分配和大小相关的问题,要小心任何溢出,下溢,你没有超过大小边界。而std :: string这些都是通过抽象来处理的

答案 4 :(得分:4)

而不是使用

void foo(std::string str); 

你可以使用

void foo(const std::string& str);

等同于

void foo(const char* str);

就使用而言,因为在传递引用时没有分配内存。但对于C ++中的字符串,我绝对会使用std::string。对于随机数据或C兼容接口,我不会。

答案 5 :(得分:3)

如果你想更好地处理你的说法数据(在你的情况下,它将是字符串)我会说与char *一起去。它将使您更好地访问字符串和内存利用率。 但是,如果您不必担心性能和内存管理问题,那么您可以轻松地使用std :: string。

答案 6 :(得分:1)

好吧,我会稍微改一下你的问题。您应该询问何时应使用字符数组而不是std::string

这是因为您应该始终使用string,除非您不能使用它。所以你应该使用characters数组而不是string的情况:

  1. 使用支持C的API,因此您无法使用string
  2. exedll之间传递数据。建议不要在exedll之间交换具有构造函数和/或析构函数的数据类型

  3. 如果您担心性能,在使用所有已启用的优化进行编译后string变得类似于字符数组,在某些情况下可能会提供更好的性能,例如,如果您需要获取它包含的字符数。

    另外关于性能,你可以随时通过引用传递,如同你提到的其他答案一样,如果你必须将指针传递给字符数组,你可以使用方法c_str(),它首先返回const指针如果你必须传递指针(不是const指针)你可以(但实际上不应该)传递它,如下所示:&str[0]