Как ограничить несколько векторов C ++ одним и тем же размером? - PullRequest
3 голосов
/ 04 января 2012

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

class stuff {
  int size;
  float *abc;
  float *def;
  // etc.
 };

Для упрощения управления памятью этого класса(и много других классов, имеющих похожую разметку), я хотел бы использовать стандартные контейнеры.Однако я должен сохранить ограничение выравнивания, предоставляемое массивами C (и векторами), потому что эти данные будут передаваться во многих функциях C.

Моя проблема в том, что каждый вектор имеет свой собственный размер, который является избыточными может привести к ошибкам, если по тем или иным причинам один изменит свой размер, а не другие.

Есть ли способ заставить массивы / векторы / whatevers всегда иметь одинаковый размер?

Ответы [ 4 ]

4 голосов
/ 04 января 2012

Это, возможно, один из случаев, когда имеет смысл создать собственный класс для управления памятью (без бизнес-логики, только память).

Вы, конечно, можете сформулировать этот класс вокруг векторов:

#define CHECK_CLASS_INVARIANT() \
  ClassInvariant inv##__LINE__ (*this); (void) inv##__LINE__;

class Foo {
public:
  size_t size() const { return _a.size(); }

  float* getA() { return &_a[0]; }
  float* getB() { return &_b[0]; }

  void push(float a, float b) {
    CHECK_CLASS_INVARIANT()
    _a.push_back(a);
    _b.push_back(b);
  }

private:
  struct ClassInvariant {
    ClassInvariant (Foo& f): _f(f) {}
    ~ClassInvariant () { assert(_f._a.size() == _f._b.size()); }

    Foo& _f;
  }; // struct ClassInvariant

  std::vector<float> _a;
  std::vector<float> _b;
};

Мы всегда проверяем инвариант класса (в методах мутирования), чтобы убедиться, что он всегда применяется.

Примечание: здесь небольшой поток, если_b.push_back(b); throws, затем _a был расширен, а _b - нет, это может быть обработано в блоке try / catch ИЛИ, как метко заметил SteveJessop, (1) предварительно зарезервировав достаточно места в обоих векторах и (2) pushв них.

1 голос
/ 04 января 2012

Как насчет сохранения вектора пар поплавков?

1 голос
/ 04 января 2012

Не существует общего и явного способа ограничения векторов. Ограничение нужно будет применять как инвариант ваших алгоритмов; всякий раз, когда вы push_back данные для одного вектора, также подтолкнуть его к другому. (Обязательно сохраните векторы private.

0 голосов
/ 04 января 2012

Я не уверен на 100%, что понимаю вашу проблему, но похоже, что вы хотите что-то вроде этого:

template<int SIZE> class stuff {
  float abc[SIZE];
  float def[SIZE];
  // etc.
 };

С этим нет проблем с управлением памятью - вы можете создатькласс «вещи» в стеке или куче, и ему не нужен деструктор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...