setter

时间:2015-09-26 08:05:55

标签: c++ return-by-reference

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;
}

原因,我选择这个设计的原因是:

  1. 易于访问显式只读或显式可写变量。
  2. 受限制(我不知道还有什么要称之为),变量,在分配之前需要清理和过滤 - 这些变量可能需要一个明确的设置器。
  3. 使用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的隐式声明或默认复制构造函数被定义为已删除,不可访问或模棱两可的复制构造函数);

2 个答案:

答案 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。无论如何,更好地规划你的设计:)。