在 C++ 中,字符串的这两种不同初始化有什么区别?

what's the difference between these two different initialization for a string in c++?

本文关键字:初始化 什么 区别 两种 C++ 字符串      更新时间:2023-10-16

源代码

#include <iostream>
#include <string>
using namespace std;
int main(){
    std::string s{'a', 'b', '', 'c'};
    std::string s1="abc";
    cout<<s.size()<<" "<<s<<endl;
    cout<<s1.size()<<" "<<s1<<endl;
    return 0;
}

,输出为

4 abc
2 ab

我想知道为什么这种现象会发生,并且C 中这两种类型的初始化之间是否有任何区别?谢谢。

对于s,您正在匹配接受字符启动器列表的构造函数:此处的列表中的(9)。string类使您可以从任意数据中构造字符串,这些数据可能包括嵌入式NUL,就像在这种情况下一样。初始评估列表知道自己的长度,因此string捕获了所有字符。

对于s1,匹配的构造函数是(5)在上述列表中,该列表接受const char*-编译器让Char数组在调用该构造函数之前向这种指针提供了衰减,这意味着构造函数没有知识阵列的长度。取而代之的是,它假设您是故意使用Asciiz Nul终止的弦乐惯例(如" C"字符串中的),并通过数据扫描以找到第一个NUL,考虑到终结者。因此,在字符串中只捕获了2个字符。

请注意,您可以用...

明确捕获4个字符
std::string s1 { "abc", 4};

...与列表中的构造函数(4)匹配。

rakete1111的评论以下说明了另一种创建此类字符串的新方法: auto s1 = "abc"s;

原因是std :: strings不是一类对象,它们是标准库对象,必须遵守C 语法的规则。与字符串文字不同,这是一类构造。

一个std :: string允许嵌入nuls,因此,当将其初始化为数组时,它会看到整个数组。当它初始化为字符串字面时,它会看到一个char *,并且它检测字符串末端的唯一方法是搜索null。