Причины использования динамического хранилища включают (но, вероятно, не ограничиваются)
Когда это не имеет значения, всегда лучше создать объект, используя метод t3
. Не используйте динамическую память без необходимости. Но иногда это действительно необходимо (см. Причины выше).
Главное отличие в том, где он находится в памяти. «Версия без указателя» находится в стеке, что означает, что она будет недействительной после возврата из функции, в то время как «версия с указателем» находится в куче, что означает, что она будет жива и здорова, пока кто-то не вызовет delete
в теме. В общем, считается лучшей практикой помещать объекты в стек, когда это возможно, и только в куче, когда это необходимо. Хорошим примером необходимости объекта в куче может быть что-то вроде этого
Obj* f()
{
return new Obj();
}
: new Obj ()
создает объект Obj
в куче и возвращает указатель на него, который затем возвращается из функции.
Это, например, НЕ будет работать
Obj* f()
{
Obj o1;
return &o1; //BAD!!
}
Поскольку значение указателя & o1
ссылается на память в стеке, а функция f () удаляется из стека в этот момент, кто знает, что произойдет. Однозначно ничего хорошего.
Если вам нужно, чтобы объект пережил область действия, в которой он был создан, то одним из решений будет создание его в куче. В этом случае вам понадобится указатель. Есть и другие причины, это самая распространенная.
Еще одна причина использования указателей - это "исходящие" параметры. Конечно, вы можете использовать ссылки, но многие предпочитают использовать указатели, поскольку это позволяет избежать изменения параметра на сайте вызова. foo (var);
vs foo (& var);
Кроме того, указатели могут использоваться для передачи или возврата объекта, который может существовать или не существовать. Например: T * foo (); // возвращает указатель на объект или NULL, если его нет
.
Этот список можно продолжать и продолжать.
Обычная (но не обязательная) реализация заключается в том, что локальные переменные размещаются в стеке. Стек конечен, и возможно, что объект окажется слишком большим для размещения в стеке.
Если у вас есть очень большой объект (например, с очень большими буферами в качестве членов), вы можете не захотеть размещать его в стеке, поскольку стек пространство ограничено, в этом случае вы выделяете в куче с помощью оператора new.
Любой тип динамических структур данных (списки, двоичные деревья, стеки и т. Д.) Должен использовать указатели на объекты .