Массив в конструкторе - PullRequest
3 голосов
/ 10 ноября 2011

Что происходит в следующем коде?

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

Нет ли способа указать размер массива внутри конструктора?

class A {
  public:
   A() {
      b[3];
   }
  private:
    B b[];
};

Ответы [ 4 ]

4 голосов
/ 10 ноября 2011

B b[] здесь " гибкий элемент массива ", нестандартное расширение в вашем компиляторе (взято из C99), которое позволяет вам объявить неограниченный массив как последний член в типе. Это полезно только при выделении вашего объекта старомодным способом C (когда вы добавляете аргумент к malloc, чтобы освободить место для массива), и его следует избегать. В этом случае вы не не выделили никакой дополнительной памяти для массива, поэтому в вашем теле конструктора, когда вы пытаетесь получить доступ к чему-то, что происходит через 3 «элемента» после этого небытия, вы вызываете UB , Я проигнорирую расширение до конца моего ответа, так как оно действительно не имеет места в коде C ++.

Нет ли способа указать размер массива внутри конструктора?

Нет, нет.

Границы массива должны быть известны во время компиляции, поэтому ни в одном случае вы не знаете больше в своем теле ctor, чем в определении класса; Вы должны записать измерение в самом объявлении члена:

class A {
    B b[3];
};

Если измерение является величиной времени выполнения в вашей программе, вам нужно вместо этого сохранить указатель и в конструкторе указать его на динамический блок памяти:

class A {
  public:
   A() : b(new B[3]) {}
  ~A() { delete[] b; }
  private:
    B* b;   // same as `B b[]`! but far clearer
};

Вместо этого я предлагаю std::vector:

class A {
  public:
   A() : b(3) {}
  private:
    std::vector<B> b;
};
2 голосов
/ 10 ноября 2011

Да.Используя оператор new: b = new B[3];.Объявите b как B *b для этого.Конечно, вам нужно delete[] это в деструкторе.

Но лучше было бы использовать std::vector вместо массива, и тогда вам не нужно беспокоиться о предварительном выделении памяти.*

1 голос
/ 10 ноября 2011

C ++ не поддерживает типы с размером, определенным во время выполнения.Следовательно, у вас есть только опции, чтобы определить размер массива во время компиляции (возможно через нетипичный параметр шаблона) или переместить массив из объекта, сделав указатель b и выделив ему память с помощью new (илилучше, пусть стандартная библиотека сделает это за вас, используя vector).

0 голосов
/ 10 ноября 2011

Это невозможно - что вы ожидаете от sizeof (A)?Если вам действительно нужна такая функциональность, используйте динамическое распределение, то есть закрытую переменную-член B * b, b (new B [3]) в списке инициализатора конструкторов, и delete [] b;в деструкторе.

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