W C++ mamy trzy możliwości życia obiektu:
- globalny / statyczny - zawsze i wszędzie dostępny
- zaalokowany dynamicznie - dostępny po alokacji przed dealokacją (new/delete lub malloc/free)
- lokalny - dostępny tylko w funkcji/metodzie.
Przykłady:
class klasa { public: int a; };
klasa obiekt;
klasa *foo()
{
obiekt.a = 5; // zawsze i wszędzie
return &obiekt; // poprawne
}
class klasa2 { public: static klasa obiekt; };
klasa klasa2::obiekt;
klasa *foo()
{
klasa2::obiekt.a = 5; // zawsze i wszędzie
return &klasa2::obiekt; // poprawne
}
klasa *foo2()
{
static klasa obiekt;
return &obiekt; // poprawne
}
klasa *foo()
{
return new klasa(); // poprawne
}
void foo2()
{
klasa *obiekt = foo();
obiekt->a = 5; // obiekt istnieje, więc możemy
delete obiekt; // obiekt już więcej nie istnieje, i nie powinniśmy trzymać do niego więcej wskaźników
obiekt = nullptr; // dla pewności, że wskaźnika do nieistniejącego dla nas obszaru już nie ma
}
-lokalny:
klasa *foo()
{
klasa obiekt;
obiekt.a = 5; // możemy, obiekt istnieje lokalnie
return &obiekt; // program się skompiluje (niektóre kompilatory będą wrzeszczeć, że zwracanie lokalnej zmiennej), ale jest to >błąd<
}
Więc to zależy, co oznacza raz utworzona. Bo raz utworzona może być lokalnie, globalnie, statycznie, lub dynamicznie.
Oczywiście istnieją smart pointery, które dynamicznie zaalokowaną pamięć zwolnią wtedy kiedy trzeba - unique_ptr, shared_ptr, ale jest to po prostu rodzaj wrappera.