使用const char[]还是const std::string?

7
哪种字符串字面量更好,标准字符串还是字符数组?
我的意思是对于常量字符串,比如说
const char name[] = "so"; //or to use 
const string name = "so";
4个回答

10
对于字符串字面量,以及仅限于来自字面量的字符串常量,我会使用const char []std::string的主要优点在于它具有免费的内存管理,但字符串字面量不需要考虑这个问题。
无论如何,它都是字面类型,并且可以直接用于任何需要旧式C风格空终止字符串或C ++字符串的API中(隐式转换会启动)。通过使用数组而不是指针,您还可以获得编译时大小实现。
现在,在定义函数接口时,即使是意图传递常量,我也更喜欢使用std::string而不是const char *,因为在后一种情况下,大小会丢失,并且可能需要重新计算。
从我的经验来看,我已经厌倦了在每次调用日志记录库(使用可变参数)记录信息/错误消息的文字字符串上编写.c_str()

2

您应该选择更适合自己的选项。如果没有特殊要求,我会使用std::string,因为它可以处理所有的内存工作。

对于字符串字面值,我会使用const char*。不使用const char[]的原因是,您可以使用const char*来初始化另一个常量。请查看以下代码:

const char str1[] = "str1";
const char* str11 = "str11";

const char str2[] = str1;    // <<< compile error
const char* str22 = str11;   // <<< OK

字符串字面量具有静态存储期(根据2.13.4/2),因此指针const char*将在程序完成之前保持有效。


如果您在许多不同的地方使用相同的字符串,那么由于写时复制机制,在许多STL实现中它会更快,这也使得它比普通的C字符串更容易使用。此外,如果您需要支持许多语言,我建议使用std::wstring。 - jdehaan
@jdehaan:如果仍然存在许多标准库实现(不是STL实现,因为std :: string不是STL的一部分)使用COW,我会感到惊讶。在MT环境中,这通常会变成一种悲观化。我认为小字符串优化(小字符串不是在堆上分配,而是在栈上分配)现在是常见的偏好。 - sbi
1
大多数实现中都已经删除了写时复制(如果仍然存在)。它在多线程环境中存在问题,因为从用户角度看似乎是线程安全的一些操作(它们引用不同的std::string),实际上可能不是线程安全的。考虑将一个字符串复制并将每个副本传递到不同的线程进行修改。每个线程都有自己的字符串,没有共享对象,但实际上在“写时复制”的内部实现中可能存在竞争条件。在库中添加锁定机制会使其在许多情况下变得比普通实现更慢。 - David Rodríguez - dribeas
@sbi, @dribeas,感谢你们的提示,我确实还在使用旧版实现... 我用.NET做我的新项目。我看到我需要更新一下对现代STL实现的了解。谢谢。 - jdehaan
@jdehaan,@sbi 无论如何,直接将字符串字面量传递给string::string将会复制它,并且不会使用COW,假设编译器除了const char[]之外还有一个特殊的内部类型用于字符串字面量,并且STL也是如此。 - Potatoswatter

2

你在做什么?你的方法期望什么?

const char 存储更轻,但没有 std::string 强大,也不够安全。但是,如果你有很多 C APIs,它可能是更明智的选择。

std::string 是首选选项。


@JPvdMerwe:theatrus是正确的。如果你所做的只是将一个常量字符串传递给需要const char*的函数,那么使用std::string/.c_str()就没有意义了。一个const字符数组没有构造函数调用成本,可以直接传递给函数,这使得它比std::string更便宜地构造和传递给函数。 - CB Bailey
是的,对于字符串字面值,我完全同意,没有浪费处理器时间的必要。 - JPvdMerwe

1

我倾向于使用const std::string而不是const char *来表示字符串字面值。因为将字符串字面值传递给需要const std::string &的函数时,每次调用都会悄悄地创建一个新的字符串,而不仅仅是一个。但是,如果我主要与期望const char *的函数一起使用字面值,那么我会使用它。

我倾向于在API中使用std::string

当然,如果我使用Unicode,则使用std::wstringwchar_t


1
我曾经对Unicode做出了同样的假设,但这很有趣:http://utf8everywhere.org/。事实证明,wchar_t在Unicode历史上是一个简单时代的遗物,就像Win32 API是WCHAR本地化一样。如果你坚持使用UTF-8和std::string,生活可能会更好。 - terriblememory

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