A *a = new A();
Создает ли это указатель или объект?
Я начинаю С++, поэтому хочу понять эту разницу.
A *a = new A();
Создает ли это указатель или объект?
Я начинаю С++, поэтому хочу понять эту разницу.
Оба: вы создали новый экземпляр A
(объект) и создали указатель на него под названием A
.
Вы можете разделить его на два утверждения:
A *a; // Declare `a` of type: pointer to `A`
a = new A(); // create a new instance of `A` and
// assign the resulting pointer to `a`
Это создает объект типа A
в куче и сохраняет указатель на него в A
(который хранится в стеке).
P.S. Не забудьте вызвать delete a
, когда вы закончите с ним, чтобы A
можно было уничтожить, а его память вернулась в кучу. Еще лучше, превратите A
в интеллектуальный указатель.
Он создает и то, и другое.
Он создает объект типа A*
в стеке и объект типа A
в куче.
Эквивалентно
A *a;
a = new A();
Он будет создавать как объект, так и указатель.
Сначала вызывается новый A(), и если у вас есть конструктор по умолчанию, он вызывает этот конструктор и инициализирует этот объект со значениями по умолчанию, иначе он будет инициализироваться с помощью значений defaul. Поскольку мы используем новый keywork, тогда он будет выделять память для объекта A в кучу. New
используется для динамического выделения памяти в куче. New
возвращает начальный адрес объекта.
После этого указатель типа A, который будет иметь адрес объекта A(), возвращаемого оператором New
.
Как говорили другие, он создает и то, и другое. Но объект A создается в свободном хранилище, и теперь вам нужно запомнить его вручную delete
. Помните, что любая функция в С++ может генерировать исключение, если оно не объявлено как noexcept
. Итак, теперь не только вы должны помнить delete
, когда не генерируется исключение, теперь вам также нужно будет представить все пути, которые может принять код, и написать соответствующие блоки try-catch
для ручного delete
вашего объекта.
То, что вы делаете, называется голым новым, и это простой способ стрелять в ногу.
К счастью, у С++ 11 есть решение этой проблемы: умные указатели. Рассмотрим семантику вашего указателя, будет ли она принадлежать одному объекту или разделена между несколькими? В первом случае вам понадобится std::unique_ptr
:
#include <memory>
std::unique_ptr<A> a(new A{});
Теперь вам не нужно вызывать delete
, управление памятью позаботится о вас. В последнем случае вам понадобится std::shared_ptr
#include <memory>
std::shared_ptr<A> a(new A{});
Но определение в точках последовательности С++ может не гарантировать, что этот способ создания интеллектуальных указателей всегда будет безопасным, не вдаваясь в подробности:
std::shared_ptr<A>(new A{new B, new C});
Может возникнуть утечка памяти, чтобы избежать этого, используйте std::make_shared
#include <memory>
auto a = std::make_shared<A>(); // a now holds a shared_ptr to A
К сожалению, при завершении С++ 11 комитет забыл о std::make_unique
. Это должно быть исправлено в С++ 14:
#include <memory>
auto a = std::make_unique<A>(); // a now holds a unique_ptr to A
Он создает оба.
Сначала вы создаете объект типа A, а затем сохраняете указатель на него
Для получения дополнительной информации о указателях, пожалуйста, просмотрите здесь
объект и указатель. Объект должен иметь указатель для ссылки, однако у вас может быть один объект, на который указывает несколько указателей.