我的工作是完全重写用于GIS矢量数据处理的旧库。主类封装了一组建筑轮廓,并提供了检查数据一致性的不同方法。这些检查功能有一个可选参数,允许执行某些过程。
例如:
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);
}
但这迫使我打破const正确性,因为workerIntersections是一种非const方法。
如何分开检查和处理,避免代码重复并保持const正确性?
答案 0 :(得分:4)
正如您所说,您的建议会中断const-correctness
。
这是因为您的建议主要包括使用新的interface
而不是内部的redesign
包装现有代码。这种方法有严重的局限性,因为它直接受到底层块的影响。
相反,我建议您重新设计现有代码,然后在您需要的2个公共方法中打破checkIntersections
。 checkIntersections
将包含检查部分,processIntersections
将包含对checkIntersections
的调用以及基于checkIntersections
结果的处理代码。
答案 1 :(得分:1)
在这种特殊情况下,破坏正确性无关紧要。您(作为workerIntersections()
知道的作者,如果从processIntersections()
(非const函数)调用它将只执行非const操作。因此,实现{是安全的{ {1}}像这样:
checkIntersections()
当然,您必须确保std::vector<Point> checkIntersections() const
{
const_cast<TypeOfThis*>(this)->workerIntersections(0);
}
在使用workerIntersections()
调用时才真正执行const操作。
0
,主要是与遗留代码的互操作性,忽略了const的正确性。这正是你正在做的事情,所以只要你安全地做到这一点,你就可以使用const_cast
了。