3

圈复杂度为理解给定函数的难易程度或包含错误的潜力提供了一个粗略的衡量标准。在我读过的实现中,通常所有基本的控制流构造(if、case、while、for 等)都会将函数的复杂度增加 1。在我看来,圈复杂度旨在确定“通过程序源代码的线性独立路径的数量”虚拟函数调用也应该增加函数的圈复杂度,因为在运行时将调用哪个实现的模糊性(调用在路径中创建另一个分支执行)。

但是,如果函数包含等效的 switch 语句(每个“case”关键字一个点,实现相关虚函数的层次结构中的每个类一个 case 关键字),对函数进行相同的惩罚,感觉过于苛刻,因为虚函数调用通常被认为是更好的编程实践。

虚函数调用的圈复杂度成本应该是多少?我不确定我的推理是反对将圈复杂度作为度量的效用,还是反对使用虚函数或不同的东西。

编辑:在人们的回应之后,我意识到它不应该增加圈复杂性,因为我们可以认为虚函数调用等同于对包含大量 switch 语句的全局函数的调用。即使该函数会得到一个坏分数,它在程序中只存在一次,而直接用 switch 语句替换每个虚拟函数调用会导致多次成本。

4

4 回答 4

5

圈复杂度通常不适用于函数调用边界,而是函数内度量。因此,虚拟调用不计入非虚拟静态函数调用。

于 2009-03-18T19:32:52.477 回答
2

虚函数调用不会增加圈复杂度,因为“将调用哪个实现的歧义”在函数调用之外。一旦设置了对象值,就没有歧义了。我们确切地知道将调用哪些方法。

BaseClass baseObj = null;
// this part has multiple paths & add to CC
if (x == y)
     baseObj = new Derived1();
else
     baseObj = new Derived2();

// this part has one path and does not add to the CC
baseObj.virtualMethod1();
baseObj.virtualMethod2();
baseObj.virtualMethod3();
于 2009-03-18T19:39:52.273 回答
1

虚函数调用也应该增加函数的圈复杂度,因为在运行时调用哪个实现的模糊性

啊,但它在运行时并不模棱两可(除非你正在做元编程/猴子补丁);它完全由接收器的类型/类别决定。

于 2009-03-18T19:45:12.587 回答
0

我不是圈复杂度的忠实拥护者,但在这种情况下,您正在调用一个函数。它将做大致相同的事情(除非类层次结构设计真的搞砸了),但根据调用它的不同会有一些变化。事情是,如果你调用任何函数,你可以根据你传入的参数获得一些不同的行为,这不计入 CC 中。

因此,我完全忽略了这个成本。

于 2009-03-18T19:42:57.350 回答