将字符串初始化为null与空字符串的区别

66
我的C++代码(如下所示)中,如果一个字符串被初始化为空字符串,会有什么影响吗?
std::string myStr = "";
....some code to optionally populate 'myStr'...
if (myStr != "") {
    // do something
}

vs.无/空初始化:
std::string myStr;
....some code to optionally populate 'myStr'...
if (myStr != NULL) {
    // do something
}

这里有什么问题吗?

14
NULL(从概念上讲)是一个指针,应该只用作指针。std::string 不是一个指针,因此不应该将它们结合使用。另外,初始化是相同的:std::string 的构造函数将其设置为空字符串。 - MSalters
@MSalters 您好,我同意您的观点,但如果类型似乎不兼容,为什么编译器不会抛出错误呢?我使用的是VS 2010,它会默默地用NULL初始化std::string。 - Krishna Oza
1
@Surfing_SO:有一个字符串构造函数,它接受一个以零字符结尾的字符数组指针。你错误地没有传递这样的指针(NULL 指针不指向字符数组或任何其他东西)。这是未定义行为,在这种情况下可能会发生任何事情。 - MSalters
正如两者所提到的,“NULL”并不是它被初始化的确切方式。你的if语句能够工作的原因可能是编译器隐式地将两边转换为bool类型,然后执行比较,这并不是你真正想要的。 - CommanderHK
可能是一个重复问题,参考如何允许std:string参数为空? - krlmlr
6个回答

85

std::string中有一个名为empty()的函数可供使用:

std::string a;
if(a.empty())
{
    //do stuff. You will enter this block if the string is declared like this
}
或者
std::string a;
if(!a.empty())
{
    //You will not enter this block now
}
a = "42";
if(!a.empty())
{
    //And now you will enter this block.
}

29

没有陷阱。 std::string 的默认构造是 ""。但您不能将字符串与 NULL 进行比较。您能做的最接近的方法是使用 std::string::empty 方法来检查字符串是否为空。


1
在构造std::string并将""赋值给它时,会产生额外的临时变量。 - vladon
@vladon 我不太确定你所指的临时变量是什么,或者分配如何相关。当astd :: string时,我不能在a = "";中看到临时变量,但问题不是关于它的。 - juanchopanza
std::string 的默认构造不是 "",而是 {}。默认构造避免了检查 char const*,发现它是空字符串,最终什么也不做的情况。这样更好。 - underscore_d

25
最佳选项:
 std::string subCondition;
这将创建一个空字符串。
这个:
std::string myStr = "";

进行复制初始化 - 从""创建一个临时字符串,然后使用复制构造函数创建myStr

额外奖励:

std::string myStr("");

使用直接初始化并使用string(const char*)构造函数。

要检查字符串是否为空,只需使用empty()方法。


std::string myStr = ""; 不会调用 string(const char*) 构造函数吗?你认为为什么会创建一个临时对象? - Andrew
@Andrew 很奇怪,对吧?https://dev59.com/f2gu5IYBdhLWcg3wln8O - Luchian Grigore
@Andrew,它几乎肯定不会被创建,因为标准明确允许实现不创建它。另一方面,即使构造了临时对象,代码也必须是合法的;也就是说,必须存在一个可访问的复制构造函数。 - James Kanze
2
@JamesKanze 是的,但那只是一种优化。你不能依赖它。理论上,会创建一个临时变量。 - Luchian Grigore
关于空字符串初始化的提示非常好,当人们创建新的CString时,这几乎是所有时间都会做的事情。 ;) - Andreas

8

I would prefere

if (!myStr.empty())
{
    //do something
}

此外,您不必写成std::string a = "";。您可以直接写std::string a; - 默认情况下它将为空。


7

空和“NULL”的概念是两个不同的概念。正如其他人所提到的,前者可以通过std::string::empty()实现,而后者可以通过boost::optional<std::string>实现,例如:

boost::optional<string> myStr;
if (myStr) { // myStr != NULL
    // ...
}

2

默认构造函数将字符串初始化为空字符串。这是表达同样意思的更经济的方式。

然而,与NULL的比较不太好。那是一种仍在普遍使用的旧语法,意思是另外一件事;一个空指针。它意味着没有字符串存在。

如果您想检查一个存在的字符串是否为空,请改用empty方法:

if (myStr.empty()) ...

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