以下是一个类的经典示例,其中包含两个用于其字段的getter:
class point
{
int x_, y_;
public:
point(int x, int y) : x_(x), y_(y) {}
int x() const
{
return x_;
}
int y() const
{
return y_;
}
};
int main()
{
point p(1, 2);
std::cout << p.x() << ", " << p.y() << '\n';
}
有人可能认为打印输出流的点应该由operator<<
的重载提供,但是假设客户想要以他自己喜欢的格式打印或者做一些与x完全不同的事情。年。然后他显然需要以某种方式到达x和y字段,对吧?
面向对象编程的基本原则是“告诉,不要问”。也就是说,理想情况下,我应该告诉我的对象用x和y字段做某事而不是要求它们。这让我想到了以下想法:
class point
{
int x_, y_;
public:
point(int x, int y) : x_(x), y_(y) {}
template<typename Fun>
void operator()(Fun fun) const
{
fun(x_, y_);
}
};
int main()
{
point p(3, 4);
p([](int x, int y){
std::cout << x << ", " << y << '\n';
});
}
这在C ++ 98中太笨拙了,但是现在我们有了lambda,这对我来说似乎是可行的。这个方法实际上比第一个带有吸气剂的版本更合理,还是我有点过于热情?
你怎么看?它有多广泛适用?有什么我想念的吗?可以改进吗?答案 0 :(得分:4)
这在C ++ 98中太笨拙了
实际上,它很容易(至少在c ++ 03中):
class point
{
int x_, y_;
public:
point(int x, int y) : x_(x), y_(y) {}
template<typename Fun>
void operator()(Fun fun) const
{
fun(x_, y_);
}
};
void foo(int,int)
{
}
int main()
{
point p(3, 4);
p(&foo);
}
可以改进吗?
是:删除getter并将x和y放在公共部分:
struct point
{
int x;
int y
};
答案 1 :(得分:3)
p([](int x, int y){
std::cout << x << ", " << y << '\n';
});
IMO,不得不围绕某些代码编写lambda,而不仅仅是编写代码仍然是样板。
拥有单个访问器与此之间的唯一区别是,类可以假定值始终一起访问。这可能提供了生成这些值的新方法,如果每个值都必须单独生成,那么这些值是不可能的(例如,一次请求2个值可能要便宜得多,而不是对一个值进行2次请求)
后者对于许多类(例如Point)来说并非如此,因为更复杂的使用费用并没有真正的好处。