Какова (или должна быть) цикломатическая сложность вызова виртуальной функции? - PullRequest
2 голосов
/ 18 марта 2009

Цикломатическая сложность предоставляет приблизительную метрику того, насколько сложно понять данную функцию или какой потенциал содержит ошибки. В реализациях, о которых я читал, обычно все базовые конструкции потока управления (если, case, while, for и т. Д.) Увеличивают сложность функции на 1. Мне кажется, учитывая, что цикломатическая сложность предназначена для определения «количество линейно независимых путей в исходном коде программы», которое вызывает виртуальная функция, должно также увеличить цикломатическую сложность функции из-за неоднозначности, реализация которой будет вызываться во время выполнения (вызов создает другую ветвь на пути исполнение).

Тем не менее, штрафование функции к тому же количеству, которое было бы, если бы оно содержало эквивалентный оператор switch (одна точка для каждого ключевого слова case, с одним ключевым словом case для каждого класса в иерархии, реализующей рассматриваемую виртуальную функцию), кажется чрезмерным сурово, потому что вызов виртуальной функции обычно считается гораздо лучшей практикой программирования.

Какова должна быть стоимость цикломатической сложности вызова виртуальной функции? Я не уверен, является ли мое рассуждение аргументом против полезности цикломатической сложности как метрики или против использования виртуальных функций или как-то иначе.

Редактировать: После ответов людей я понял, что это не должно увеличивать цикломатическую сложность, потому что мы можем считать вызов виртуальной функции эквивалентным вызову глобальной функции, которая содержит массивный оператор switch. Несмотря на то, что эта функция получит плохой результат, она существует в программе только один раз, тогда как замена каждого вызова виртуальной функции непосредственно на оператор switch приведет к многократным затратам.

Ответы [ 4 ]

5 голосов
/ 18 марта 2009

Цикломатическая сложность обычно не применяется через границы вызова функций, но является внутрифункциональной метрикой. Следовательно, виртуальные вызовы не считаются больше, чем не виртуальные вызовы статических функций.

2 голосов
/ 18 марта 2009

Вызов виртуальной функции не увеличивает цикломатическую сложность, потому что «неоднозначность, над которой будет вызвана реализация», является внешней по отношению к вызову функции. Как только значение объектов установлено, двусмысленности нет. Мы точно знаем, какие методы будут вызваны.

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();
1 голос
/ 18 марта 2009

виртуальные функции должны увеличиваться цикломатическая сложность функция также из-за неопределенность, реализация которой будет быть вызванным во время выполнения

Ах, но это не двусмысленно в время выполнения (если вы не делаете метапрограммирование / исправление обезьян); это полностью определяется типом / классом получателя.

0 голосов
/ 18 марта 2009

Я не большой поклонник цикломатической сложности, но в этом случае вы вызываете функцию. Он будет делать примерно то же самое (если только дизайн иерархии классов действительно не испорчен), с некоторыми вариациями в зависимости от того, что его вызывает. Дело в том, что если вы вызываете какую-либо функцию, вы можете получить различное поведение в зависимости от аргументов, которые вы передаете, и это не учитывается в CC.

Поэтому я бы полностью проигнорировал эту стоимость.

...