0

假设我正在使用一个实现 function 的库foo,我的代码可能如下所示:

void foo(const int &) { }

int main() {
    int x = 1;
    foo(x);
    std::cout << (1/x) << std::endl;
}

一切正常。foo但是现在假设由于某种原因在某一时刻被修改或重载。现在我们得到的可能是这样的:

void foo(int & x) {
    x--;
}
void foo(const int &) {}

int main() {
    int x = 1;
    foo(x);
    std::cout << (1/x) << std::endl;
}

巴姆。程序突然中断。这是因为我们实际上想要在该片段中传递的是一个常量引用,但是随着 API 的突然变化,编译器选择了我们不想要的版本,程序意外中断。

我们想要的实际上是这样的:

int main() {
    int x = 1;
    foo(static_cast<const int &>(x));
    std::cout << (1/x) << std::endl;
}

通过此修复程序,程序再次开始工作。但是,我必须说我在代码中没有看到很多这样的转换,因为每个人似乎都只是相信不会发生这种类型的错误。此外,这似乎是不必要的冗长,如果有多个参数并且名称开始变长,函数调用就会变得非常混乱。

这是一个合理的担忧吗?我应该怎么做?

4

1 回答 1

1

如果你改变一个接受 const 引用的函数,使它不再是一个 const,你很可能会破坏事情。这意味着您必须检查调用该函数的每个地方,并确保它是安全的。在这种情况下,进一步拥有两个具有相同名称的函数,一个具有 const 和一个不具有 const 绝对是一个糟糕的计划。

正确的做法是创建一个新函数,它x--使用与现有函数不同的名称来执行变体。

任何做这种事情的 API 供应商都应该受到严厉的体罚,如果在文档中有一个 BIG 通知说“我们已经改变了函数foo,它现在递减x,除非参数被强制转换为 const”,可能会稍微减少暴力。这是人们可以想象的最糟糕的二进制中断之一(就“很难找出问题所在”而言)。

于 2013-07-04T23:06:20.930 回答