массивы — сделать переменную класса доступной в других областях? Переполнение стека

В конструкторе класса я создаю массив с необходимым размером, как это:

ArrayClass::ArrayClass(int size)
{
Number* nmbr = new Number[size];
}

а также

ArrayClass::ArrayClass()
{
Number* nmbr = new Number[2];
}

У меня тоже это указано в шапке как

Number* nmbr;

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

2

Решение

Попробуйте объявить переменную nmbr в объявлении класса, а не в конструкторе.
Пример:

class ArrayClass

{

private:

Number *nmbr;

public:

ArrayClass();

ArrayClass(int size);

~ArrayClass()

}

ArrayClass::ArrayClass(int size)

{

this->nmbr = new Number[size];

}

ArrayClass::ArrayClass()
{

this->nmbr = new Number[2];

}

ArrayClass::~ArrayClass()
{

delete this->nmbr;

}
2

Другие решения

Не создавайте новую переменную. nmbr у вас конструкторы отличаются друг от друга и того что в шапке.

Если вы должны использовать глобальный (трижды подумайте об этом), объявите его как externопределите его в одном TU и просто используйте

 nmbr = new ArrayClass[2];

в ваших конструкторах.

Не забудьте почистить память или про правило трех.

6

Вероятно, проще всего увидеть здесь проблему, если поместить весь код в одном месте.

Number *nmbr;

class ArrayClass {
Number *nmbr;
public:

ArrayClass() {
Number *nmbr = new Number[2];
}
};

Здесь у вас есть три совершенно разные переменные в трех разных областях. Каждый «скрывает» любую переменную с тем же именем во внешней области видимости.

Это также означает, что при инициализации nmbr в вашем конструкторе вы только инициализация переменной, которая является локальной для самого конструктора. Когда ctor вернется, этот указатель будет отброшен, а выделенная вами память будет утечка. Одинаково плохо, ArrayClass::nmbr то, что вы (почти наверняка) хотели инициализировать, еще не инициализировано.

nmbr это за пределами класса почти одинаково, но немного безопаснее с одной стороны: поскольку оно глобальное, оно будет инициализироваться нулями; поскольку это указатель, это означает, что он будет инициализирован как нулевой указатель (поэтому он не указывает на какие-либо данные, но, по крайней мере, его легко проверить и знать, что это не так).

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

class Array {
Number *nmbr;
public:
Array() : numbr(new Number[2]) {}
};

Поскольку этот класс, кажется, выполняет удаленное владение (то есть он распределяет и владеет данными через указатель), вам необходимо следовать правилу пяти (обновление старого правила трех для C ++ 11) или, по строгим предпочтениям, использовать std::vector<Number> вместо этого, чтобы он мог следовать за «правило нуля».

1
По вопросам рекламы [email protected]