在非常相似的方法之间共享代码



我的工作是完全重写一个用于GIS矢量数据处理的旧库。main类封装了一组建筑轮廓,并提供了检查数据一致性的不同方法。这些检查功能有一个可选参数,允许执行某些过程。

例如:

std::vector<Point> checkIntersections(int process_mode = 0);

此方法测试某些建筑轮廓是否相交,并返回相交点。但是,如果您传递一个非null参数,该方法将修改轮廓以删除交叉点。

我认为这很糟糕(在调用站点,不熟悉代码库的读者会认为一个名为checkSomething的方法只执行检查,不修改数据),我想改变这一点。我还想避免代码重复,因为检查和处理方法大多相似。

所以我在想这样的事情:

// a private worker
std::vector<Point> workerIntersections(int process_mode = 0)
{
// it's the equivalent of the current checkIntersections, it may perform
// a process depending on process_mode
}

// public interfaces for check and process
std::vector<Point> checkIntersections()  /* const */
{
workerIntersections(0);
}

std::vector<Point> processIntersections(int process_mode /*I have different process modes*/)
{
workerIntersections(process_mode);
}

但这迫使我打破常量的正确性,因为workerIntersections是一种非常量方法。

如何将检查和处理分开,避免代码重复并保持常量正确性?

正如您所指出的,您的建议将破坏const-correctness。这是因为您的建议本质上包括用新的interface包装现有代码,而不是内部的redesign。这种方法有严重的局限性,因为它直接受到底层块的影响。

相反,我建议您重新设计现有的代码,并将checkIntersections分解为您需要的两个公共方法。checkIntersections将包括检查部分,processIntersections将包括对checkIntersections的调用和基于checkIntersections的结果的处理代码。

在这种特殊情况下,破坏常量正确性应该无关紧要。您(正如workerIntersections()的作者所知,如果从processIntersections()(一个非常量函数)调用它,它只会执行非常量操作。因此,像这样实现checkIntersections()是安全的:

std::vector<Point> checkIntersections() const
{
const_cast<TypeOfThis*>(this)->workerIntersections(0);
}

当然,您必须确保workerIntersections()在使用0调用时确实只执行const操作。

const_cast存在于该语言中是有原因的,主要是与忽略常量正确性的遗留代码的互操作性。这正是你正在做的,所以只要你安全地做,你就可以使用const_cast

最新更新