Обнаружение ошибочной виртуальной функции

Я был пойман этой проблемой не раз:

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 строк кода, которые используют ваши классы.

Другие вопросы по тегам