为什么使用默认构造函数构造std :: string对象时,其行为会有所不同?

我尝试了以下程序:

#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;
}

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

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

hheyong 回答:为什么使用默认构造函数构造std :: string对象时,其行为会有所不同?

  

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

因为您遇到的是未定义的行为

std::string str;

使用0内存分配构造一个默认字符串。意味着通过std::string::operator[]进行修改将导致asses out of bounds undefined behaviour。因此,任何事情都可能发生。在您的情况下,长度返回0


  

[...]显然我已经使用下标运算符添加了字符   因为那会返回char参考,所以我知道这是合法的。

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

  

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


作为可能的解决方法,您可能想先std::string::resize来访问元素。

#include <string>

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

std::string::push_back每个字符插入字符串。

#include <string>

std::string str;
str.push_back('o');
str.push_back('k');
// ... now it has defined behaviour
,

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

  

为什么长度返回为0

它以0开始,您没有做任何添加(例如push_back+=)。但是话又说回来,由于您之前所做的是未定义的行为,因此此处可能会发生任何事情。

  

此外,我没有任何异常。

您可以尝试使用std::string::at来代替,尝试时会抛出std::out_of_range异常。

,

您未向空字符串!abc.Equals()添加任何内容。相反,您尝试编辑空字符串中不存在的元素。 str的下标运算符不会自动添加元素。 (与std::string不同)此外,不能保证下标运算符会引发某些异常。如果需要安全下标操作,则可以使用std::map函数。

您可以使用std::string::at运算符将某些内容附加到字符串中。

+=
本文链接:https://www.f2er.com/3125970.html

大家都在问