Обнаружение ошибочной виртуальной функции
Я был пойман этой проблемой не раз:
class A{
public:
virtual ~A() {}
virtual int longDescriptiveName(){ return 0; }
};
class B: public A{
public:
virtual int longDescriptveName(){ return 1; } // Oops
};
Если функция чисто виртуальная, компилятор ловит ошибку. Но если это не так, это может быть ужасной ошибкой, чтобы выследить. Частично проблема заключается в том, что имена функций могут быть слишком длинными. Но мне все еще интересно, есть ли способ увидеть эти ошибки раньше?
3 ответа
Одна возможность - малоиспользуемая чисто виртуальная функция с реализацией:
virtual int longDescriptiveName() = 0
{
return 0;
}
Это заставляет производные классы переопределять его. Затем они могут вызвать реализацию базового класса в одиночку, если хотят только такого поведения.
Также вам нужно убедиться, что иерархия наследования является плоской, а не многослойной, что, в общем, хорошо, так как наследование достаточно хрупкое, не складывая слои.
Если вы компилируете с Microsoft Visual C++ 2005 или новее, есть нестандартное расширение, позволяющее написать:
virtual int longDescriptveName() override { return 1; }
И компилятор будет жаловаться. Если вы компилируете также с другими компиляторами, возможно, будет разумно создать #define, чтобы вы могли контролировать поведение.
Старый вопрос necro'd, но один хороший способ - это тестировать заранее, либо формально с помощью модульных тестов, либо более неформально, прежде чем вы начнете использовать свои классы. Другими словами, проверьте рано на этом:
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);
прежде чем писать еще 10000 строк кода, которые используют ваши классы.