Как можно поместить утверждения перед списком инициализации класса?

Можно ли утверждать что-то о параметрах конструктора класса до вызова списка инициализации?

class Foo
{
int m_lower;
int m_upper;
unsigned int m_delta;

public:
Foo(int t_lower, int t_upper) :
assert(t_lower < t_upper),  // Assert here, before initialisation of fields.
m_lower(t_lower),
m_upper(t_upper),
m_delta(t_upper - t_lower)
{
// Assert could be made here, but m_delta would have underflowed if t_upper < t_lower.
}
}

Преимущество утверждения перед списком инициализации будет заключаться в том, что требования для инициализации каждого поля могут быть выполнены немедленно, и их не нужно будет проверять потенциально несколько раз с каждой инициализацией, которая имеет одинаковые требования. Хотя инициализация m_delta может быть выполнена в init_delta метод инициализации, если несколько значений имеют одинаковое требование t_upper > t_lower тогда утверждение должно быть размещено в каждом из них (в случае, если предыдущее утверждение удалено). Если поместить его внутри самой функции конструкции, то инициализация одного или нескольких полей, возможно, уже потерпела неудачу (с чем-то более драматичным, чем недостаток).

Если он помещен в верхнюю часть списка инициализации, то после проверки контракт будет понятен пользователю и пометит ошибку до того, как возникнут какие-либо ошибки, такие как недопоставка в этом случае.

Вышеуказанный случай является лишь упрощенным примером проблемы. Я знаю, что есть лучшие способы решить конкретную проблему выше (abs () и т. Д.).

Спасибо за вашу помощь и советы!

2

Решение

Вы можете использовать оператор запятой:

  public:
Foo(int t_lower, int t_upper) :
m_lower(assert(t_lower < t_upper), t_lower),
m_upper(t_upper),
m_delta(t_upper - t_lower)
{
...
}

Операнды оператора запятой оцениваются слева направо, и в качестве результата используется правильное значение.

Обратите внимание, что порядок инициализации основан на порядке, в котором переменные-члены объявлены в классе, а не на порядке в списке инициализации. Так что вы должны поставить assert() вызов в инициализации первой переменной-члена.

3

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector