Объекты классов могут на протяжении всего своего существования использовать различные ресурсы - динамически выделенная память, файлы, сетевые подключения и тд. В этом случае в C++ применяется так называемый принцип/идиома RAII (resource acquisition is initialization). RAII предполагает, что получение ресурса производится при инициализации объекта. А освобождение ресурса производится в деструкторе объекта.
Пример, использующий RAII:
#include <iostream> class IntArray{ public: IntArray(unsigned size) : data{ new int[size] } {} // выделяем память в конструкторе ~IntArray(){ if(data){ std::cout<<"Freeing memory..."<< std::endl; delete[] data; // освобождаем память в диструкторе } } // Удаляем конструктор копирования и оператор присваивания IntArray(const IntArray&) = delete; IntArray& operator=(const IntArray&) = delete; // оператор индексирования для доступа к элементам int& operator[](unsigned index) { return data[index]; } // возвращаем инкапсулированный ресурс int* get() const { return data; } // передаем ресурс другогому объекту int* release(){ int* result = data; data = nullptr; return result; } private: int* data; }; int main(){ const unsigned count {5}; // количество элементов IntArray values{count}; // создаем объект, который управляет ресурсом // изменяем элементы динамического массива for (unsigned i {}; i < count; ++i){ values[i] = i; } // выводим элементы динамического массива на консоль` for (unsigned i {}; i < count; ++i){ std::cout<<values[i]<<"\t"; } std::cout<<std::endl; }
При этом важно, чтобы ресурс (в данном случае динамическая память) освобождался только один раз. Для этой цели в классе удалены конструктор копирования и оператор присваивания, что позволяет избежать ситуации, когда два объекта хранят указатель на одну и ту же область динамической памяти и соответственно потом в деструкторе будут пытаться освободить эту память.
IntArray(const IntArray&) = delete; IntArray& operator=(const IntArray&) = delete;
Применение кода, написанного выше:
int main(){ const unsigned count {5}; // количество элементов IntArray array{count}; // создаем объект, который управляет ресурсом // изменяем элементы динамического массива for(unsigned i {}; i < count; ++i){ array[i] = i; } // получаем указатель int* data = array.release(); // теперь функция main обязана освободить память for(unsigned i {}; i < count; ++i){ std::cout<<data[i]<<"\t"; } std::cout << std::endl; //освобожадем память delete[] data; }