В конструкторе класса я создаю массив с необходимым размером, как это:
ArrayClass::ArrayClass(int size)
{
Number* nmbr = new Number[size];
}
а также
ArrayClass::ArrayClass()
{
Number* nmbr = new Number[2];
}
У меня тоже это указано в шапке как
Number* nmbr;
Хотя создание самого массива работает, я не могу получить к нему доступ за пределами конструктора. Кажется, что когда я покидаю конструктор, переменная освобождается из памяти. Как мне предотвратить это, чтобы я мог использовать переменную при вызове других функций в классе?
Попробуйте объявить переменную 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;
}
Не создавайте новую переменную. nmbr
у вас конструкторы отличаются друг от друга и того что в шапке.
Если вы должны использовать глобальный (трижды подумайте об этом), объявите его как extern
определите его в одном TU и просто используйте
nmbr = new ArrayClass[2];
в ваших конструкторах.
Не забудьте почистить память или про правило трех.
Вероятно, проще всего увидеть здесь проблему, если поместить весь код в одном месте.
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>
вместо этого, чтобы он мог следовать за «правило нуля».