Как я могу хранить в полученной информации, полученной при инициализации базового класса?

StackOverflow https://stackoverflow.com//questions/22016200

Вопрос

У меня есть ситуация, которая в качестве побочного эффекта придумывается с данными для инициализации базового класса, полученный класс рассчитывает часть информации, которая должна быть доступен через его интерфейс. Следующее дает представление о проблеме, используя логию в качестве информационной потребности:

class base {
public:
  base(some_initialization_data);
  // ... 
};

class derived : public base {
public:
  derived()
  : base(calc_init_data())
  {
  }

  bool condition_x_occurred() const
  {
    // How to get at the information obtained 
    // during the call to calc_init_data()? 
  }
private:
  static some_initialization_data calc_init_data()
  {
    // This piece of information will later be needed: 
    const bool condition_x_occurred = /* ... */;
    return some_initialization_data(condition_x_occurred);
  }
};
.

Проблема с этим заключается в том, что важная информация рассчитывается при инициализации базового класса, до того, как инициализированы собственные элементы данных класса. Таким образом, я должен не писать в элементы данных полученного класса еще. Хотя я уверен, что могу уйти с булевом, еще не официально созданным на любой платформе, который я столкнулся за последние 20 лет, я хотел бы избежать неопределенного поведения.

Обратите внимание, что информация о вопросе не имеет ничего общего с базовым классом, поэтому сохраняя его в базовом классе не является вариантом. Кроме того, информация не может быть сохранена в статическом элементе данных. У меня есть несколько представлений о том, как ревертировать код, чтобы я мог сделать это, но те, которые я мог бы придумать, все, кажется, довольно навязчивым для такой маленькой проблемы. Поэтому мне интересно, может ли один из вас придумать что-то простое?


Примечание : Поскольку мы на встроенной платформе мы застряли с GCC 4.1.2. Так строго C ++ 03 (включая TR1), но нет C ++ 11.

Это было полезно?

Решение

в C ++ 11, вы можете сделать что-то вроде:

class derived : public base {
public:
  derived() : derived(calc_init_data()) {}

  bool condition_x_occurred() const { return my_condition_x_occurred; }

private:
    derived(const std::pair<bool, some_initialization_data>& p) :
        base(p.second), my_condition_x_occurred(p.first)
    {}

  static std::pair<bool, some_initialization_data> calc_init_data()
  {
    // This piece of information will later be needed:
    const bool condition_x_occurred = /* ... */;
    return std::make_pair(condition_x_occurred, some_initialization_data(condition_x_occurred));
  }

private:
    bool my_condition_x_occurred;
};
.

в C ++ 03, вы можете изменить свой полученный класс к чему-то вроде:

class derived : public base {
public:
  static derived make_derived() { return derived(calc_init_data()); }

  bool condition_x_occurred() const { return my_condition_x_occurred; }

private:
    derived(const std::pair<bool, some_initialization_data>& p) :
        base(p.second), my_condition_x_occurred(p.first)
    {}

  static std::pair<bool, some_initialization_data> calc_init_data()
  {
    // This piece of information will later be needed:
    const bool condition_x_occurred = /* ... */;
    return std::make_pair(condition_x_occurred, some_initialization_data(condition_x_occurred));
  }

private:
    bool my_condition_x_occurred;
};
.

Другие советы

Если на вашем компиляторе вы можете использовать делегирующий конструктор:

struct derived_init
{
    bool data;
    some_initialization_data calc()
    {
        data = true;
        return some_initialization_data();
    }
};


class derived : public base {
public:
    derived()
        : derived(derived_init{})
    { }

    bool condition_x_occurred() const
    {
        return init_data.data;
    }
private:
    derived(derived_init init)
        : base(init.calc()), init_data(init)
    { }
    derived_init init_data;
};
.

С C ++ 03 вы можете использовать аргумент по умолчанию:

class derived : public base {
public:
    derived(derived_init init = derived_init{})
        : base(init.calc()), init_data(init)
    {
    }
private:
    derived_init init_data;
};
.

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