RPF*_*ltz 2 c++ events encapsulation vertex getter-setter
我的目标是在类中更改值时触发事件接收器.我的解决方案是使用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;
}
Run Code Online (Sandbox Code Playgroud)
我把getter的定义放在头文件中,因为这应该允许它们被内联.
我的问题是:有什么方法可以在更改值时自动调用函数,而不需要在头文件中包含函数定义?或者是否有可见性级别允许任何人读取数据,但只有类本身才能修改它?或者别的什么?
我知道另一种方法是手动调用更新函数,但这看起来很难看:
vertex.X = 5;
vertex.Update();
Run Code Online (Sandbox Code Playgroud)
先感谢您.
编辑:
到目前为止,我听到了一些很棒的答案.解决方案取决于您的目标:
但是,效率怎么样?
我刚刚为我之前推测的单独的读/写访问权限制定了一个很好的技巧:
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;
}
Run Code Online (Sandbox Code Playgroud)
如果您正在寻找的只是干净的,那么最简单的方法就是拥有一个"属性"对象,就像在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;
};
Run Code Online (Sandbox Code Playgroud)
(这些函数在SO上是内联的简洁,你可以根据需要将它们移出.)然后就可以了
Vertex v;
v.X = 4;
v.Y = 2.3443;
Run Code Online (Sandbox Code Playgroud)
每次分配值时,都会调用相应的回调.您还可以使用v.X和v.Y到位的地方,你会使用一个double,以及使他们的行为像正常的doubleS(除了事实,你必须执行-=,+=等等).