4

我的目标是在类中的值发生更改时触发事件接收器。我的解决方案是使用 get 和 set 函数。但是,我不希望在读取值时出现任何性能问题。在下面的课程中:

class Vertex {
 public:
  const double& GetX() { return _x; } // should inline automatically
  const double& GetY() { return _y; } // ' '                     ' '
  void SetX(const double& x); // complex stuff in source file
  void SetY(const double& y); // ' '                      ' '
 private:
  double _x, _y;
}

我将 getter 的定义放在头文件中,因为这应该允许它们被内联。

我的问题是:是否有任何方法可以在更改值时自动调用函数,而无需我在头文件中包含函数定义?或者是否存在允许任何人读取数据的可见性级别,但只有类本身可以修改它?或者也许是别的什么?

我知道另一种方法是手动调用更新函数,但这看起来很难看:

vertex.X = 5;
vertex.Update();

先感谢您。

编辑:

到目前为止,我已经听到了一些很棒的答案。解决方案取决于您的目标:

  • 简单:getter 和 setter;虽然不是很干净。
  • Clean:属性类(或代理);不过,实现运营商并不容易。

然而,效率呢?

我刚刚为我之前推测的单独的读/写访问权限制定了一个很好的技巧:

class Vertex {
 public:
  Vertex(double x, double y)
      : _x(x), _y(y), X(_x), Y(_y) { } // defined here for readability
  void SetX(double x) { _x = x; update(); } // defined here for readability
  void SetY(double y) { _y = y; update(); } // update would be the callback
  const double& X, Y;
 private:
  double _x, _y;
}
4

2 回答 2

10

如果您要寻找的只是干净,那么最干净的方法可能是拥有一个“属性”对象,例如在 C# 中:

template<typename T>
class Property {
public:
    Property(std::function<void(T)> callback) : data(), callback(callback) { }

    Property& operator=(const T& newvalue) {
        data = newvalue;
        callback(data);

        return *this;
    }

    operator T() const {
        return data;
    }

private:
    T data;
    std::function<void(T)> callback;
};

class Vertex {
public:
    Vertex() : X(&xcallback), Y(&ycallback) { }

    Property<double> X, Y;
};

(为了简洁起见,这些函数是内联的,如果需要,可以将它们移出。)然后你可以做

Vertex v;

v.X = 4;
v.Y = 2.3443;

并且每次分配值时,都会调用相应的回调。并且您可以使用v.Xandv.Y代替您使用 a 的任何地方,double因此它们的行为就像正常double的 s (除了您必须实现-=,+=等事实)。

于 2012-02-04T22:01:45.267 回答
0

不要过早优化。编写简单且易于理解/修改的代码,并且只有在您分析并看到确实存在瓶颈之后,才进行优化。

我会使用get/set方法,并在该方法上调用事件处理程序set

没有访问修饰符允许您读取数据,但仅限制对类的访问。

此外,您不需要在头文件中包含函数定义。额外跳转指令的成本在 99% 的时间里可以忽略不计。

于 2012-02-04T21:58:31.200 回答