Инициализировать постоянный вектор указателей - PullRequest
2 голосов
/ 28 января 2020

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

class foo
{
public:
  virtual void bar(void) = 0;
  virtual ~foo() {}
};

class derived1 : public foo
{
private:
  int data1;
public:
  void bar(void)
  {
    //implementation 1
  };
  derived1(int d) : data1(d) {}
  ~derived1() {}
};

class derived2 : public foo
{
private:
  int data2;
public:
  void bar(void)
  {
    //implementation 2
  }
  derived2(int d) : data2(d) {}
  ~derived2() {}
};

Каков наилучший способ инициализации вектора Тип const vector<foo*>? В настоящее время я делаю следующее:

const std::vector<foo*> v =
{   
  new derived1(a),
  new derived1(b),
  new derived2(c),
  new derived2(d)
};

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

Ps, мне не нужно беспокоиться о вызове delete на любом из указателей, поскольку приложению требуется эта информация для всей среды выполнения.

1 Ответ

2 голосов
/ 28 января 2020

Учитывая спецификатор const, эта память все еще динамически выделяется?

Да. std::vector выделяет внутренне и const или нет const не изменит это.

Каков наилучший способ инициализации вектора типа const vector<foo*>?

Наилучшее здесь действительно субъективно, но я обычно использую два хороших способа:

  • инициализация с использованием фигурных скобок std::initializer_list;
  • use IIFE (выражение для немедленного вызова функции);

Первое очевидно - вы уже используете его. Второй - обманщик, если вы никогда не использовали его:

const std::vector<int> vec = [someFlag]{
    std::vector<int> non_const;

    non_const.push_back(3);
    if (someFlag) {
        non_const.push_back(-1);
    }
    non_const.push_back(7);

    return non_const;
}(); // <= notice the call - ()

Обратите внимание, что в итоге вы получите const std::vector, который условно инициализирован (обратите внимание на if внутри лямбда). Хитрость заключается в том, чтобы использовать лямбду и локальный, не const вектор, чтобы pu sh некоторые значения в нем, а затем return его. Из-за обязательного удаления копии должно быть ровно одно сокращение std::vector. Компилятор может оптимизировать (и, вероятно, будет) любые векторные копии, поэтому большую часть времени будет иметь только одно std::vector создание.

...