Hej! Oczywiście, że jest taka możliwość, ale wszystko po kolei. Zacznijmy od tego, że w bloku numer 3 doprowadzasz do wycieku pamięci, ponieważ nie używasz operatora delete, dla wcześniej zaalokowanego obiektu operatorem new.
Operatory te powinny być używane jako para - to na barkach programisty leży odpowiedzialność za zwolnienie pamięci - pamiętaj o tym.
Chcesz alokować dynamicznie pamięć, tj. przy pomocy operatora new, a później nie dbać o ich usunięcie - jest to jak najbardziej możliwe - możesz użyć inteligentnych wskaźników. Widzisz, destruktor klasy Vector, wywołuje zapewne instrukcję delete, która ma za zadanie usunąć pamięć, zaalokowaną dla tablicy elementów [vector to kontener korzystający z dynamicznego przydziału pamięci]. Ta z kolei wywołuje destruktory obiektów, które są w nim przechowywane. Niestety destruktor wskaźnika prostego nie używa na nim instrukcji delete, z prostego względu - możesz do niego przypisać jakikolwiek adres - nawet zmiennej, która nie została dynamicznie zaalokowana.
Aby zapewnić, że obiekty posiadają destruktor, który wywułuje instrukcję delete, możemy skorzystać z inteligentnych wskaźników - np. shared_ptr, unique_ptr, bądź weak_ptr. Oczywiście pamiętając, że możemy aplikować do ich konstruktorów tylko i wyłącznie adresy otrzymane przez new. Tutaj artykuł [LINK]
Klasy te, posiadają przeciążone operatory, które pozwalają korzystać z nich niemal jak ze zwykłych wskaźników. Musisz mieć jednak na uwadze, że są to klasy, dlatego są troszeczkę mniej wydajne niż ręcznie stosowane new/delete.
Informacje znajdziesz w artykule, poza tym polecam opis i przykłady z ksiązki C++ Biblioteka Standardowa.
Przykładowy kod może wyglądać tak:
#include <iostream>
#include <vector>
#include <memory> //dla klasy unique_ptr
//Klasa "Krzykacza, ktorej uzyje, zeby pokazac, ze pamiec jest zwalniana
class MyClass {
int id;
public:
MyClass(int id_) : id(id_) {
std::cout << "CONSTRUCTOR: " << id << std::endl;
}
~MyClass() {
std::cout << "DESTRUCTOR: " << id << std::endl;
}
//metoda, zeby pokazac, ze unique_ptr pozwala operowac jak na zwyklym wskazniku za pomoca operatora ->
void introduce() {
std::cout << "OBJECT WITH ID: " << id << std::endl;
}
};
int main() {
//Tworzenie vectora i umieszczenie w nim 3 obiektow za pomoca dynamicznej alokacji
//uzywam emplace_back, ktora wywoluje konstruktor unique_ptr z argumentem adresu zwroconego przez new
//wynika to stad, ze unique_ptr nie posiada operatora przypisania, dla argumentu (const unique_ptr&), z ktorego korzysta vector
std::vector<std::unique_ptr<MyClass>> myVector;
myVector.emplace_back(new MyClass(1));
myVector.emplace_back(new MyClass(2));
myVector.emplace_back(new MyClass(3));
//Uzycie metody 2 elementu vectora, za pomoca wskaznika
std::cout << "\n\nWywoluje metode: " << std::endl;
myVector[1]->introduce();
std::cout << "\n\n";
return 0;
}
W razie pytań pisz - powyższy kod działa w standardzie C++11, bo wraz z nim dostarczono inteligentne wskaźniki o których mówiłem. Pozdrawiam!