我有一个类-本质上是一堆字段的结构(例如,类似于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"功能,而是剥夺了用户的灵活性:值得吗?

我想在这里您太过极端了,因为分配无法正常工作,您可能会发现在最常见的操作中使用类的实例时遇到了麻烦(您可以创建它们的数组,但是以后不能对数组进行排序)。

因此,我建议您仅防止分配以外的任何修改。这足以轻松维护类不变式。

10-07 16:29
查看更多