Mutator通过引用返回

时间:2013-11-17 07:57:56

标签: c++ getter-setter

通过引用返回私有变量是否有任何错误?像:

int& data() {
    return _data;
}

它允许你做一些奇怪的事情,如:

std::cout << (test.data() = 60) << std::endl; // 60
print_int((test.data() = 70)); // 70
test.data() = 50;

我已经看到了不同的getter-setter的冗长变化,这似乎是精简的,虽然我感到尴尬的感觉它不赞成。

1 个答案:

答案 0 :(得分:2)

通过'私人变量',我认为你的意思是'私人成员“。这是完全合法的,虽然经常(但并不总是)糟糕的设计。

关于如何使用它的示例肯定是可疑的,并提出了getter方法实际上为了访问控制或封装而购买的问题。

假设您确实希望将某些内容传递给调用者,该调用者允许它通过该对象自己的方法来改变对象的内部状态,可能是因为出于某种原因需要不同的接口。更好的方法是返回对适配器对象的引用,该引用允许您间接操作该状态。

为什么这样?如果您需要多种类型的接口到同一状态,您可以将该状态封装在“核心”对象中,并且如果其他对象/代码期望不同的接口用于改变相同的状态,则可以使用备用接口提供适配器。

因为您保留了“对象墙”并且从未直接暴露内部状态,所以您仍可以自由更改对象中的表示。并且,您仍然可以强制执行对象所需的任何不变量和约束。您只需在更新对象时更新适配器类。您无需检查任何获取该适配器引用的调用方。

该替代模式的一个例子:

class barney_adaptor : public barney_interface
{
    // ... 
  public:
    barney_adaptor( int &intref_ ) : intref( intref_ ) { }

    // ... code that implements barney_interface
};

class fred
{
     int m_internal;

     barney_adaptor m_barney_adaptor;

   public:
     fred() : m_barney_adaptor( m_internal ) { };


     //... bunch of stuff elided
     barney_adaptor &as_barney() { return m_barney_adaptor; }
};

这种方法并不总是有意义的;通常最好只从你期望实现的任何接口继承。但是,这并不总是实用的,特别是如果您需要支持的各种接口具有冲突的方法名称。

但是,提供对私人成员的可变访问并不是一个好主意。它与将私有成员移动到班级的public:方面没有什么不同。