为啥即使对于“写入时复制”的 const 成员函数也返回代理类?
Posted
技术标签:
【中文标题】为啥即使对于“写入时复制”的 const 成员函数也返回代理类?【英文标题】:Why return a proxy class even for const member function for "copy on write"?为什么即使对于“写入时复制”的 const 成员函数也返回代理类? 【发布时间】:2019-01-29 08:24:30 【问题描述】:在More Effective C++中,给出如下代码
const String::CharProxy String::operator[] (int index) const
return CharProxy(const_cast<String&>(*this), index);
String::CharProxy::operator char() const
return theString.value->data[charIndex];
我们为什么不直接返回一个 char 而不是使用 const_cast 并稍后将 CharProxy 转换为 char?
【问题讨论】:
我想这样做的目的是允许获取一个指向底层字符的指针。 【参考方案1】:如果我在你的情况下没有错的话,还有 non const 版本既可以读/写字符,也可以像 Real Fresh 所说的那样获取字符的指针/引用.
那么自然而然地为 const 版本提供相同的功能,允许读取字符(当然不是写入)并获取字符的指针/引用(常量)。
std::vector std::string 等
【讨论】:
所以即使其他人修改了字符串,我们仍然会得到更新的字符。但实际上,当有人通过非常量 CharProxy 修改它时,就会发生 String 的副本。也许重点是 const 和非常量运算符 [] 的统一接口。【参考方案2】:这样做是为了使绑定到[]
的返回值的String::const_reference
(即const String::CharProxy
)不会在其他地方修改特定的String
时突然变得悬空。
您可以定义突变使所有引用无效,但这意味着您的 String
类将无法用于广泛的通用代码,并且是“远处的幽灵行动”。例如。你有代码 A 首先从 String
获取一个可变引用,然后代码 B 获取一个 const 引用,然后 A 通过它的引用发生变异。现在代码 B 的引用已经失效,它无法事先检查是否会发生这种情况。
注意,代理通过值返回char
,所以没有引用可以转义。
【讨论】:
这个更简单的解决方案似乎也可以,并且不存在悬空引用。char String::operator[] (int index) const return value->data[index];
以上是关于为啥即使对于“写入时复制”的 const 成员函数也返回代理类?的主要内容,如果未能解决你的问题,请参考以下文章
为啥这个 const auto 变量在 range-for 循环中为类的 const 成员函数编译?