我现在正在阅读《The C++ Standard Library》。当我阅读字符串章节时,我遇到了一个问题。它告诉我们,如果内容是由 data() 导出的,则引用字符串字符的引用和指针可能会失效。
正如我们所知,data() 将字符串的内容作为字符数组返回,并且返回类型不是有效的 C 字符串,因为没有附加 '\0' 字符。
但是为什么 data() 会使引用和指针失效呢?
有人可以为我翻译吗?非常感谢!
调用data
自身不会,const
之后调用可变方法(非)可能会使前一个指针无效。这是因为当您修改字符串时,内部 char 数组可能会被更改或重新分配。
在 C++03 中,没有要求内部字符串表示必须是一个连续的缓冲区。它还被允许与另一个字符串共享内部结构(例如,使用引用计数)。
因此,调用data()
或c_str()
可能会强制字符串重构其内部数据,以便能够返回指向 char 缓冲区的指针。
一个例子,假设 C++11(这样data()
保证是空终止的):
string s = "abc" ;
const char* p = s.data() ;
cout << p << endl ;
s = "ABCDE" ;
cout << p << endl ;
第二个分配给s
invalidates p
,因为s
可能(在这里,它可能会)重新分配其内部缓冲区。所以最终的结果cout
是不确定的。它可能会打印“abc”或“ABCDE”,或者它可能会将苹果酒喷到你的耳朵里。
我正在阅读最新的 C++11 草案,但找不到任何支持此类声明的内容:
21.4.1 pt 6:引用 basic_string 序列元素的引用、指针和迭代器可能会因该 basic_string 对象的以下用途而失效:
— 作为任何标准库函数的参数,将非常量 basic_string 的引用作为参数。
— 调用非常量成员函数,除了 operator[]、at、front、back、begin、rbegin、end 和 rend。
第一点的脚注:
例如,作为非成员函数 swap() (21.4.8.8)、operator>>() (21.4.8.9) 和 getline() (21.4.8.9) 的参数,或作为 basic_string::swap 的参数()
data()
成员函数已声明const
,因此它不应使任何内容无效。