我发现,在编写C ++代码时,我花了很多时间编写访问器样板代码,例如:
class A
{
int x;
public:
auto x();
void set_x(decltype(x));
};
实现访问器的整个想法围绕能够拦截对它们的读写访问。我偶然发现了https://github.com/d-max/spots-dialog图书馆(我不是作者)。它真的让我想知道,如果,为了避免编写样板代码,可以/应该只写下这样的东西:
class A
{
public:
property<int> x;
A() {
x.setter([this](int){ /* setter code */ });
}
};
我的问题是:有哪些技术可以避免为getter和setter编写大量的样板代码?
答案 0 :(得分:1)
关于吸气剂和制定者是否一般都是邪恶的,有一些讨论full Java demo和here。
所以,我避免使用样板代码的策略:尽量避免使用getter和setter。当需要一些纯数据类时,我将(少数)字段声明为public。但在这些情况下,我尽量避免给他们任何其他逻辑,我尽量保持这些类。
另外,请阅读tell-not-ask,例如来自there。
答案 1 :(得分:0)
我猜你正在寻找这样的东西:
template <typename T>
class Property{
private:
T val;
std::function<void(T& v,const T& newV)> setFN = nullptr;
public:
void setter(decltype(setFN) newSetter){
setFN = newSetter;
}
void set(const T& newVal){
if(!setFN)
val = newVal;
else
setFN(val,newVal);
}
T get(){
return val;
}
};
所以基本上是一个模板类,它能够存储一个setter函数。如果存储了一个,则调用它,如果不存在,则仅使用operator=
(当然需要由T定义)。
用法:
int main() {
Property<int> x;
x.set(5);
std::cout << x.get() << std::endl;
x.setter([](int& v, const int& newV){std::cout << "Setter called\n"; v=newV;});
x.set(2);
std::cout << x.get() << std::endl;
return 0;
}
输出:
5
Setter called
2
以类似的方式实现getter功能很容易。