gpt4 book ai didi

c++ - 迭代器和引用计数字符串

转载 作者:可可西里 更新时间:2023-11-01 18:29:40 25 4
gpt4 key购买 nike

如果我们考虑使用引用计数的 std::string 实现,请考虑以下场景:

int main()
{
string english = "Hello";
string german = english; //refcnt = 2
string german2 = german;

/* L1 */ german[1] = 'a';
/* L2 */ *(german2.begin() + 1) = 'A';

cout << english << endl << german << endl << german2 << endl;
return 0;
}

L1 和 L2 中发生了什么?引用计数是否被破坏并执行了深拷贝?我想是的,但我担心的是如果发生这种情况,做一个简单的:

cout << german[1] << endl; 

或者一个简单的:

cout << *(german.begin()) << endl;

在非常量上下文中会执行不必​​要的深拷贝。我对吗?实现如何处理这个细节?

最佳答案

你是对的,将在所有四个示例(L1、L2 和下面的两个)中创建一个拷贝,即使对于后两个,它是不必要的。

不幸的是,当调用 operator[] 的非常量版本或取消引用非常量迭代器时,实现无法判断生成的非常量引用是否将用于修改对象, 所以它必须谨慎行事并制作拷贝。

C++11 添加的函数 cbegin()cend()到字符串和其他返回 const 迭代器的容器,即使在非 const 对象上调用也是如此。这有助于缓解问题。我不知道 operator[] 的类似解决方案。

注意:让 operator[] 或迭代器的 operator*() 返回代理类型,正如其他一些回答者所建议的那样,并不是真正的选择,因为它违反了容器要求,其中之一是这些函数返回实际引用. (这就是为什么现在每个人都同意 vector<bool> 是一个错误 - 它以这种方式使用代理)。

(当然,如果您正在编写自己的引用计数类,没有什么能阻止您使用代理类型来实现这一点。)

关于c++ - 迭代器和引用计数字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11148355/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com