Определение массива в классе, но размер определяется в конструкторе - PullRequest
1 голос
/ 28 февраля 2012

Как я могу определить массив как член класса, в то время как его размер определяется где-то еще и фактически он передается конструктору.

Более подробно: Существует массив целых чисел, который определен как открытый член в классе.

class foo {
  public:
    int *arr[];
    int s;
};

Однако размер массива передается в конструкторе.

foo::foo()
        : s (array_size)
{
}

Каков правильный синтаксис таких действий?

Ответы [ 5 ]

3 голосов
/ 28 февраля 2012

Похоже, ваш класс пытается определить массив «указателей на int», а не массив int, как вы предлагаете. Однако классический ответ заключается именно в том, что вы используете «указатель на int», выделяете массив в конструкторе и освобождаете его в деструкторе. В первом приближении:

class foo
{
public:
    int *arr;
    int  s;
    foo(int sz) : s(sz) { arr = new int [s]; }
   ~foo()               { delete [] arr; }
};

Если вы собираетесь пойти по этому маршруту, вам также потребуется предоставить оператор присваивания и конструктор копирования (как мне напоминает Майк Сеймур - спасибо, Майк); Версии по умолчанию, которые компилятор напишет для вас, если вы не напишите их для себя, будут неправильными - ужасно неправильными. (ТАК вопрос «Что такое правило трех?» охватывает это.)

Тем не менее, это (вероятно) небезопасно, и вам будет лучше использовать std::vector<int> вместо простого указателя:

class foo
{
public:
    std::vector<int> arr;
    foo(int sz) : arr(sz) { }
};

Вам не нужно явно хранить размер; вектор делает это за вас.

3 голосов
/ 28 февраля 2012

Правильный способ сделать это - использовать STL и std::vector< int > для таких задач. Вот примерный план, который может вам подойти:

#include <vector>

...

class foo
{
    public:
        std::vector< int > arr_;

        ...

        foo(const int* numbers, int numberCount)
        : arr_(numbers, numbers+numberCount)
        {
        }

        ...

        int size() const
        {
            return arr_.size();
        }

        ...

        int& operator [] (int index)
        {
           return arr_.at(index);
        }
};

Дополнительную информацию о векторах можно найти здесь . Дополнительные предложения:

  • не делайте ваши переменные экземпляра общедоступными, если для этого нет веских причин.
  • Назовите переменные экземпляра как-то особенными (например, добавив _).
  • многим не нравятся классы с именами в нижнем регистре.
1 голос
/ 28 февраля 2012

Может быть, это не совсем то, что вы хотите, но я бы сделал это с параметром шаблона

template<int T>
class Foo
{
    public:
    int array[T];
    int s;
};

Вы создаете этот класс как

Foo<1024> * f = new Foo<1024> ();
1 голос
/ 28 февраля 2012

Ну, во-первых, не уверен, почему вы используете массив указателей на int, но кто я такой, чтобы ставить под сомнение ваш дизайн ... В любом случае, вы можете сделать это с помощью указателя и динамического выделения.Объявите ваш массив как ...

int **arr;

и инициализируйте его в ctor как ..

*arr = new int*[s];

Не забудьте очистить его на dtor с помощью delete[].Другой альтернативой является использование std::vector<int*>

0 голосов
/ 28 февраля 2012
class foo {
   public:
     std::vector m_vec;
     foo(uint32_t size) : m_vec(size) { }
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...