Обнаружение виртуальной функции с ошибкой
-
19-09-2019 - |
Вопрос
Я не раз сталкивался с этой проблемой:
class A{
public:
virtual ~A() {}
virtual int longDescriptiveName(){ return 0; }
};
class B: public A{
public:
virtual int longDescriptveName(){ return 1; } // Oops
};
Если функция чисто виртуальная, компилятор обнаруживает ошибку.Но если это не так, это может быть ужасной ошибкой, которую нужно отследить.Частично проблема заключается в том, что имена функций могут быть слишком длинными.Но мне все еще интересно, есть ли способ увидеть эти ошибки раньше?
Решение
Одной из возможностей является малоиспользуемая чистая виртуальная функция с реализацией:
virtual int longDescriptiveName() = 0
{
return 0;
}
Это заставляет производные классы переопределять его.Затем они могут вызвать только реализацию базового класса, если им нужно только такое поведение.
Также вам необходимо убедиться, что ваша иерархия наследования плоская, а не многоуровневая, что в любом случае хорошо, поскольку наследование достаточно хрупкое и без нагромождения слоев.
Другие советы
Если вы компилируете с помощью Microsoft Visual C++ 2005 или новее, существует нестандартное расширение позволяющий написать:
virtual int longDescriptveName() override { return 1; }
И компилятор будет жаловаться.Если вы также компилируете с помощью других компиляторов, вероятно, будет разумно создать #define, чтобы вы могли контролировать поведение.
Старый некротизированный вопрос, но один из хороших способов — провести раннее тестирование, либо формально с помощью модульных тестов, либо более неформально, прежде чем вы начнете использовать свои классы.Другими словами, заранее проверьте следующее:
A test_a;
B test_b;
A& poly_a = test_a;
A& poly_b = test_b;
assert(poly_a.longDescriptiveName() == 0);
assert(poly_b.longDescriptiveName() == 1);
до вы пишете еще 10 000 строк кода, использующих ваши классы.