Вопрос

Я не раз сталкивался с этой проблемой:

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top