Обнаружение ошибочной виртуальной функции - PullRequest
2 голосов
/ 10 февраля 2010

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

class A{
public:
  virtual ~A() {}
  virtual int longDescriptiveName(){ return 0; }
};

class B: public A{
public:
  virtual int longDescriptveName(){ return 1; } // Oops
};

Если функция чисто виртуальная, компилятор ловит ошибку. Но если это не так, это может быть ужасной ошибкой, чтобы выследить. Частично проблема заключается в том, что имена функций могут быть слишком длинными. Но мне все еще интересно, есть ли способ увидеть эти ошибки раньше?

Ответы [ 3 ]

2 голосов
/ 10 февраля 2010

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

virtual int longDescriptiveName() = 0
{
    return 0; 
}

Это заставляет производные классы переопределять его. Затем они могут вызвать реализацию базового класса в одиночку, если хотят только такого поведения.

Кроме того, вам необходимо убедиться, что иерархия наследования является плоской, а не многослойной, что, в общем, хорошо, так как наследование достаточно хрупкое, не складывая слои.

1 голос
/ 10 февраля 2010

Если вы компилируете с Microsoft Visual C ++ 2005 или новее, есть нестандартное расширение , позволяющее написать:

virtual int longDescriptveName() override { return 1; }

И компилятор будет жаловаться. Если вы компилируете также с другими компиляторами, вероятно, будет разумно создать #define, чтобы вы могли контролировать поведение.

0 голосов
/ 26 октября 2013

Старый вопрос 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);

до вы пишете еще 10 000 строк кода, которые используют ваши классы.

...