C ++: варианты инициализации класса-члена без неявного конструктора по умолчанию (больше ограничений в теле вопроса) - PullRequest
1 голос
/ 14 декабря 2010

boost::posix_time::time_duration имеет три перегрузки конструктора и не имеет неявного конструктора.Мне нужно сделать некоторые вычисления в классе, который имеет несколько time_duration членов, прежде чем я смогу их инициализировать.Все это подразумевает, что без конструктора по умолчанию у меня нет роскоши готовить входные данные для моих членов класса в моем конструкторе классов составления.

Шаблон может быть описан следующим образом (что является ошибочным):

class X {
public:
    x(int i,int j){}
};

class Y {
  x _x; 
public:
    y() {i = 1+1; j=1-1; _x(i,j);}
};

int main()
{
    return 0;
}

Я хотел бы получить некоторые подходящие способы построения Y (с мотивацией), где

  1. X не имеет конструктора по умолчанию.
  2. X не может быть изменен напрямую (но может быть разделен на подклассы).
  3. Сгенерированный код является детерминированным (нет ненужных дорогих конструкций malloc / vtables и т. Д.).
  4. критическая точка Класс Y имеет n X членов и m возможных вычислений.Где n > 1 и m > 1. Так важна элегантность.
  5. Важны вопросы модульного тестирования.

На данный моментЯ склоняюсь либо к подклассу, либо к вызову функций для выполнения вычислений и к вызову этих функций в списке инициализации (если это вообще возможно).Вы можете прокомментировать эти подходы: D.

1 Ответ

4 голосов
/ 14 декабря 2010

Извините, если я неправильно понял ваш вопрос, но разве Boost.Optional не является решением вашей проблемы?Это, вероятно, лучший способ достижения неинициализированного состояния по умолчанию без использования указателей и динамического выделения.

Однако, хотя это сработает, это, вероятно, не идеально.Мое решение выбора, вероятно, будет, если это возможно, переместить вычисления в свободных функциях в анонимное пространство имен:

namespace {
    x computeX()
    {
        int i, j = /* ... */;
        return x(i, j);
    }
}

y::y()
  : _x(computeX())
{
    /* ... */
}
...