Рассмотрим этот простой базовый класс Foo
, имеющий функцию foo
, вызывающую чистую виртуальную функцию foo_
, задокументированную с помощью Doxygen:
class Foo
{
public:
/** \brief This function logs x and does the job */
void foo(double x);
protected:
/** \brief This function does the job */
virtual void foo_(double x) = 0;
};
void Foo::foo(double x)
{
std::clog << "'Foo::foo(double x)' is called with x = " << x << std::endl;
this->foo_(x);
}
У меня нет предварительных условий для документирования этого абстрактного класса.
Теперь рассмотрим производный класс Bar
, для которого существует предварительное условие для правильной работы:
class Bar : public Foo
{
public:
/**
* \brief This function does the job
* \pre x must be greater or equal to 0
*/
virtual void foo_(double x);
};
void Bar::foo_(double x)
{
assert(x >= 0.0 && "PRE: x can't be negative");
// Do the job
}
Теперь у меня есть предварительное условие для x, когда я вызываю foo_
, который вызывается foo
. Затем у меня есть предварительное условие для foo
в зависимости от конечного типа.
Некоторые вопросы :
- Должен ли я добавить предварительное условие в
Foo::foo
независимо от окончательного типа? Это выглядит логично, если пользователь никогда не знает окончательный тип, когда он использует класс. Но пользователь также может иметь другой классBaz
, производный отFoo
без каких-либо предварительных условий, и явно вызыватьBaz::foo(double)
с отрицательными значениями. Это не должно быть проблемой. - В моем представлении о полиморфизме класс
Foo
не должен ничего знать о своих потомках, тогда предусловия быть не может. Но пользователю материнского класса не обязательно знать дочерние элементы, чтобы использовать этот класс. Как разрешить это противоречие? - Есть ли особый (/лучший) способ задокументировать такие вещи с помощью Doxygen?
cos
иsqrt
, где первый может обрабатывать все аргументы, а второй — только положительные. Тогда не имеет смысла ограничивать аргумент базовым классом. С другой стороны, производный класс, который не может обрабатывать некоторые значения, не должен вызывать сбой программы, поэтому я бы не использовалassert
, а использовал более изящную обработку ошибок. - person Karsten Koop   schedule 07.06.2016