最近我把我的getter和setter写成(注意:真正的类在getter/setter中做更多的事情):
struct A {
const int& value() const { return value_; } // getter
int& value() { return value_; } // getter/setter
private:
int value_;
};
这允许我执行以下操作:
auto a = A{2}; // non-const object a
// create copies by "default" (value always returns a ref!):
int b = a.value(); // b = 2, is a copy of value :)
auto c = a.value(); // c = 2, is a copy of value :)
// create references explicitly:
auto& d = a.value(); // d is a ref to a.value_ :)
decltype(a.value()) e = a.value(); // e is a ref to a.value_ :)
a.value() = 3; // sets a.value_ = 3 :)
cout << b << " " << c << " " << d << " " << e << endl; // 2 2 3 3
const auto ca = A{1};
const auto& f = ca.value(); // f is a const ref to ca.value_ :)
auto& g = ca.value(); // no compiler error! :(
// g = 4; // compiler error :)
decltype(ca.value()) h = ca.value(); // h is a const ref to ca.value_ :)
//ca.value() = 2; // compiler error! :)
cout << f << " " << g << " " << h << endl; // 1 1 1
这种方法不允许我:
- 验证设置器的输入(这是一个很大的 BUT),
- 在 const 成员函数中按值返回(因为我希望编译器捕获对 const 对象的赋值:)
ca.value() = 2
。更新:请参阅下面的 cluracan 答案。
但是,我仍然经常使用它,因为
- 大多数时候我不需要那个,
- 这使我可以将类的实现细节与其接口分离,这正是我想要的。
例子:
struct A {
const int& value(const std::size_t i) const { return values_[i]; }
int& value(const std::size_t i) { return values_[i]; }
private:
std::vector<int> values_;
// Storing the values in a vector/list/etc is an implementation detail.
// - I can validate the index, but not the value :(
// - I can change the type of values, without affecting clients :)
};
现在的问题:
- 这种方法还有其他我没有看到的缺点吗?
- 人们为什么喜欢:
- 具有不同名称的 getter/setter 方法?
- 将值作为参数传递?只是为了验证输入还是有其他主要原因?