我有一个类-本质上是一堆字段的结构(例如,类似于2-d点;但是对于这个问题,它只是一个合成的示例)-我只需要不可变的实例。显然,我可以将数据成员设为私有(private),并且仅具有getter方法:
class Point2d {
protected:
double x;
double y;
public:
Point2d(double _x, double _y) : x(_x), y(_y) {}
double getX() const { return x; }
double getY() const { return y; }
double norm() const { return x*x + y*y; }
}
但是,我在想也许这样做更好:
class Point2d {
public:
const double x;
const double y;
public:
Point2d(double _x, double _y) : x(_x), y(_y) {}
double norm() const { return x*x + y*y; }
Point2d operator=(const Point2d& p) = delete;
}
编辑:第三种选择是在单个变量的声明中仅使用
const
ness强制不变性,而类本身是可变的,即class Point2d {
public:
double x;
double y;
public:
Point2d(double _x, double _y) : x(_x), y(_y) {}
double norm() const { return x*x + y*y; }
}
// ...
Point2d magicalTransformation(const Point2d& p1, const Point2d& p2);
强制不变性的更合理方法是什么?
最佳答案
在设计灵活性和保证之间的等级时,总是会产生压力。强制执行数据成员的一致性(这会阻止分配)会产生非常严格的类:这会带来成本(灵活性的损失),但有什么好处呢?
当然,任何希望冻结实例的用户都可以使用const
这样做。因此,您没有给用户带来任何"new"功能,而是剥夺了用户的灵活性:值得吗?
我想在这里您太过极端了,因为分配无法正常工作,您可能会发现在最常见的操作中使用类的实例时遇到了麻烦(您可以创建它们的数组,但是以后不能对数组进行排序)。
因此,我建议您仅防止分配以外的任何修改。这足以轻松维护类不变式。