A。通过返回引用,以下使用相同函数获取getter和setter的技巧有多么有用/麻烦?
B。在getter和setter的情况下,将const添加到函数声明结尾的做法有多好?
#include <iostream>
class A
{
int varReadWrite_;
int varReadOnly_;
int varRestricted_;
public:
A() : varReadOnly_(25) {}
virtual ~A() {}
int& varReadWrite() { return varReadWrite_; }
int varReadOnly() { return varReadOnly_; }
int varRestricted() { return varRestricted_; }
void setVarRestricted(int i); //throwable
};
int main(int argc, char *argv[])
{
A a;
a.varReadWrite() = 45;
std::cout << a.varReadOnly() << a.varReadWrite() << std::endl;
return 0;
}
原因,我选择这个设计的原因是:
使用boost fusion map也是shown here
的有趣可能性更新
Const引用成员对于对变量的只读访问很有意思,例如
class A {
int mA;
public:
int& a;
A(int a_ = 0) : mA(a_), a(mA) {}
};
实际上,这需要额外的努力来编写副本和移动构造函数,这对我来说是一个可接受的折衷。
Cpp Reference Copy Construtor says
如果 ... T具有无法复制的非静态数据成员(已删除),则类T的隐式声明或默认复制构造函数被定义为已删除,不可访问或模棱两可的复制构造函数);
答案 0 :(得分:3)
一个。通过返回引用,以下使用相同函数获取getter和setter的技巧有多么有用/麻烦?
建议不要回复对内部成员的引用 ,因为这样您可以轻松访问其他人,这样他们就可以在不使用对象类API提供的任何方法的情况下更改对象内部状态。因此,很难跟踪代码中的这种变化。通常,只能通过属于类API的方法来更改对象的内部状态。
B中。在getter和setter的情况下,将const添加到函数声明结尾的做法有多好?
如果您参考为以下方法添加const:
void PrintState() const
然后一般来说这对setter来说没有意义。在这种情况下,Const意味着此方法不会更改对象状态。所以这是一个承诺,你给调用者说:我不会通过这个调用改变对象状态。一般来说,这是一个非常好的做法,因为它可以帮助您在设计过程中考虑您的方法,看看哪一个真正修改了对象状态。此外,这是一个防御性的编程 它是递归的:如果你通过引用(通过指针或引用)将这个对象传递给某个方法,他就不能调用const方法,除非这个方法也被标记为const。因此,这可以防止错误地更改对象状态。
答案 1 :(得分:2)
访问者(a.k.a get
ters和set
ters)与拥有公共成员变量一样好/笨,如you've just violated encapsulation and lied yourself。将它们混合在一个函数中会更糟糕,因为调用者可以保留返回的引用,打开该洞以获得比上面链接中描述的更微妙的错误。
其次,将const
添加到成员函数声明中可以保护您免受set
ters的攻击,但不能保护get
ters。无论如何,更好地规划你的设计:)。