Синтаксис действителен, но он не выполняет то, что вам нужно, потому что testPointer1()
работает с копией указателя, а не с самим указателем. Поэтому, когда вы назначаете адрес вновь выделенному объекту, он присваивается копии, а не исходному указателю a1
.
Из-за этого адрес теряется, и вы получаете утечку памяти. Кроме того, поскольку исходный указатель a1
никогда не изменялся, вы попытались разыменовать нулевой указатель, что плохо.
Я бы сказал, testPointer2()
- лучший способ сделать это, но если вы хотите, чтобы testPointer1()
работал, попробуйте это:
void testPointer1(A*& a)
{
a = new A();
a->num = 10;
}
Тип параметра указывает «ссылку на указатель на A
». Таким образом, вместо копии указателя будет передана ссылка на исходный указатель. Ссылка на C ++ - это псевдоним другого объекта. Поэтому, что бы вы ни делали для псевдонима, оно выполняется для исходного объекта.
Дополнительные примечания:
Обратите внимание, что скобки в new A();
действительно значимы, и их наличие или отсутствие имеет значение .
Также обратите внимание, что вы должны вручную delete
все new
'отредактировать объекты после того, как закончите с ними, иначе вы получите утечку. Как правило, вы должны обернуть указатель в его собственный класс и реализовать RAII или использовать умный указатель , такой как умные указатели Boost или auto_ptr
, для правильного управления памятью и безопасности исключений.
Если вы собираетесь установить значение num
при инициализации, почему бы не создать конструктор?
class A
{
public:
A(int n) : num(n) {}
int GetNum() const { return num; }
private:
int num;
};
void testPointer1(A*& a)
{
a = new A(10);
}
A* testPointer2()
{
return new A(10);
}
// auto_ptr example, see link in second note above
std::auto_ptr<A> testPointer3()
{
return auto_ptr<A>(new A(10));
}