为什么用默认构造函数构造std::string对象时行为不同

Why std::string object when constructed with default constructor behaves differently?

本文关键字:对象 string 为什么 构造函数 默认 std      更新时间:2023-10-16

我尝试了以下程序:

#include <iostream>
#include <string>
int main ()
{
std::string str;
str[0] = 'o';
str[1] = 'k';
std::cout << str.length();
std::cout << "as a whole :";
std::cout << str << std::endl;
std::cout << "character by character :";
std::cout << str[0] << str[1] << std::endl;      
return 0;
}

我不明白为什么我不能使用对象变量将字符串作为一个整体打印,为什么长度返回为0,因为很明显,我已经使用下标运算符添加了字符,因为这会返回char引用,所以我知道这是合法的。

此外,我没有得到任何例外。就是这样。显然,std::string类的幕后发生了很多事情,我知道我错过了一些东西。有人能帮我吗?

您有一个长度为0的字符串,然后尝试使用下标运算符修改其内容。这是未定义的行为,所以在这一点上,没有特定的结果是可以保证的。如果您使用at(),它会暴露错误并引发异常。

为什么长度返回为0

它最初是0,您没有做任何添加操作(例如push_back+=(。但话说回来,由于你之前所做的是未定义的行为,任何事情都可能在这里发生。

此外,我没有得到任何类型的异常。

您可以改为尝试std::string::at,当您尝试时会抛出std::out_of_range异常。

我不明白为什么我不能打印整个字符串[…]…

因为您正在经历未定义的行为

这个

std::string str;

构造具有CCD_ 10内存分配的默认字符串。这意味着通过std::string::operator[]进行修改将导致未定义行为超出范围。因此,任何事情都有可能发生。在您的情况下,长度返回0


[…]很明显,我已经使用下标运算符添加了字符因为这会返回字符引用,所以我知道这是合法的。

,由于上述原因,您没有。作为参考,std::string::operator[]

返回对指定位置的字符的引用。不执行边界检查。如果pos>size((,则行为未定义


作为可能的修复,您可能希望在访问元素之前std::string::resize

#include <string>
std::string str;
str.resize(2);
str[0] = 'o';
str[1] = 'k';
// ... now it has defined behaviour

或者CCD_ 15的每一个charector到串中。

#include <string>
std::string str;
str.push_back('o');
str.push_back('k');
// ... now it has defined behaviour

您没有向空字符串str添加任何内容。相反,您正在尝试编辑空字符串中不存在的元素。std::string的下标运算符不会自动添加元素。(与std::map不同(此外,不能保证下标运算符会抛出一些异常。如果您想要安全的下标操作,您可以使用std::string::at函数。

可以使用+=运算符将某些内容附加到字符串中。

str += 'o';
str += 'k';