人们为什么写私人场getters返回非const参考
Why do people write private-field getters returning a non-const reference?
我们都可以就公共变量对封装和所有这些不利。但是,我注意到很多执行此类内容的代码:
class foo {
private:
int integer_;
string someString_;
// other variables
public:
int& integer() { return integer_; }
string& someString() { return someString_; }
// other "functions"
}
int main() {
foo f;
f.integer() = 10;
f.someString() = "something";
return 0;
}
我已经看到它在许多地方被使用,但我不明白为什么。基本上,它返回对数据的引用,从而将其直接暴露于外部。因此,从任何角度来看,都没有真正实现封装。
为什么通常使用?
有一个反复出现的咒语,应使用 getter/setter 函数来封装您的数据。因此
int& integer() { return integer_; }
,但这与简单写作没有太大不同:
class foo {
public: // <<<
int integer_;
string someString_;
// ...
};
好吧,它添加了一个函数调用,但是您无法控制客户端对参考的操作。
如果您真的想提供 getter 函数写作:
const int& integer() const { return integer_; }
相应的 setter 函数看起来像:
void integer(const int& value) {
integer_ = value;
}
我必须部分与 @πάνταῥεῖ和 @rakete1111的答案部分不同意,考虑到班级的定义是如何随着时间而变化的。
的确,这些方法通常是由刚刚听到"无暴露成员"咒语的人写的,但它们也可以具有合法的用途:
- getter方法可以修改 在返回参考之前,要在返回参考之前包含某种有效性检查或资源分配代码 - 直接访问数据成员不允许。虽然这意味着更改 class 的代码,但它不需要更改类用户代码。另外,如果在类标题中未公开Getter的实现,则可能不需要重新编译类用户代码。注意:这样做可能是其他一些不良设计选择的迹象。
- getter方法可能被子类(在这种情况下通常是虚拟方法)所覆盖的。
- Getter方法稍后可能会用原始数据成员类型的代理替换其返回类型,而不是对实际成员的引用 - 甚至可能不再存在。想想
vector<bool>
的工作原理;当您调用其operator[]
时,您将无法获得boolean&
,您将获得某种代理,当分配或分配到to时,会进行适当的位提取或设置。 - 非const getter不能用于非const实例。因此,实际上它确实限制了访问相对于直接暴露成员的访问。OP的示例类的作者是否实际上是一个不同的问题...
总结:"虚拟"非const-Reference getter可以是其他有意义的,代码的 stub 。
话虽如此,只要让Getter返回const引用或值,通常是一个好主意。或者只是在适当的情况下暴露该领域(也有一些)。
我会强烈劝阻返回 non-const 引用对私人变量的参考。不是因为它破坏了封装,而是因为它是不必要的:为什么不首先制作变量public
?
破坏封装不好,是的,但这并不意味着每个变量应为 private
。某些变量应从用户中读取和修改,因此使其成为public
是有意义的。例如,以std::pair
为例,它具有2个公共成员变量first
和second
。那不是不好的做法。
唯一没有意义的时间是当变量不应该写入时。那将是不好的,因为它实际上会打破封装并使整个程序难以调试。
该结构可用于调试目的。
如果您有公共变量,则无法轻松监视其用法。将其转换为一对私有变量和方法返回参考,将允许您放置断点和/或记录呼叫。
但是,单独的getter和setter可以更好地实现相同的目的,因此这只是与普通公共变量相比的优势。
我写了一次。我稍后计划返回并用将堆栈对象返回到可以施放到原始类型并通过原始类型分配给的东西的东西。这使我稍后返回并拦截所有作业以进行验证。
有些压倒性的Techinque。项目上的其他编码人员都无法理解。整个堆栈被撕掉了。
- 从函数返回const char*数组
- 为什么我不能在返回 const 的布尔函数中为类成员变量赋值?C++
- 从内部使用静态 std::string 的函数返回 const char * 是否安全?
- 从类方法返回 "const char*" 作为 std::string&
- 为什么const rvalue合格的std ::可选:: value()返回const rvalue参考
- 通过移动分配从算术运算符过载中返回const值
- 从本机代码返回"const char*"并在java中获取"字符串"
- 为什么我的C 函数拒绝返回const引用
- 通过参考返回和const函数返回const值的函数之间的差异
- 如果我返回const定义的对象,为什么const关键字被取消资格
- 返回const lvalue引用rvalue临时?为什么这项工作
- 内置类型的返回const值
- 返回 const std::string*& from a std::string *tab[11]
- 如何在静态方法中返回const类型
- 返回const引用和非常数成员函数调用
- 为什么不允许我将函数返回 const char* 的结果分配给 char*,bt 可以将字符串文字(常量)分配给 cha
- 在 C++ 中返回 const 字符串引用的字符串文本
- 为什么我们必须从一元前缀运算符重载返回 const 引用
- 在返回 const 错误的函数中传递值
- 为什么我可以将返回 'const T&' 的函数的返回值分配给 'T' 变量,而不是 'T&' 变量?