smart pointer c++ пример реализации

smart poiter из библиотеки Шаблоны STL, под названием auto_ptr
smart pointer, реализуется с помощью перегрузки селектора.

Умный указатель (smart pointer) — класс, имитирующий интерфейс обычного указателя и добавляющий к нему некую новую функциональность, например проверку границ при доступе или очистку памяти.

Иначе говоря, умные указатели - это объекты, в которых хранится указатель на настоящий объект и, как правило, счётчик числа обращений к объекту.

В классе также присутствует деструктор для настоящего объекта, который не вызывается извне, а только внутри smart pointer. Принцип таков, что, когда счётчик обращений к объекту равен 0, вызовется деструктор.

Например, есть массив указателей на объекты. Вы используете копию указателя на один объект где-нибудь ещё. Потом очищаете массив, удаляя при этом объекты, а "где-нибудь ещё" все ещё хранит указатель. Естественно, что, при доступе к нему происходит сбой программы, т.к. объект был удалён при очистке массива.

При наличии smart pointer, такого не произойдёт, т.к. при создании копии указателя внутренний счётчик увеличится на 1. Те будет равен двум - 1 для массива, и ещё 1 для копии. Теперь даже если мы удалим объект из массива, внутренний счётчик уменьшится на 1 и станет равным 1, т.е. копия может продолжать работать с объектом. После того как он станет ненужным, копия освобождает память от него и счётчик становится равным 0. Именно, в этот момент вызывается деструктор для оригинального объекта.

#include <iostream>
using namespace std;
class Temp
{
	int TEMP;	
	public:
		//конструктор
		Temp(){TEMP=25;}
		//функция показа на экран
		void TempFunction(){
			cout<<"TEMP = "<<TEMP<<"\n\n";
		} 
		//функция установки значения
		void TempSet(int T){
			TEMP=T;
		}
};
// Класс, реализующий умный указатель
class SmartPointer 
{
	// Инкапсулированный указатель
	Temp*ptr;
	//счётчик копий 
	int count_copy;

public:
	//конструктор
	SmartPointer (Temp*p=NULL){
		//записываем 0 при создании копий нет
		count_copy=0;
		ptr=p;
	}
	// конструктор копирования
	SmartPointer (const SmartPointer&obj){
		//создается копия - увеличиваем счётчик
		ptr=obj.ptr;
		count_copy++;		
	}
	//перегрузка оператора равно
	SmartPointer operator=(const SmartPointer&obj){
		//создается копия - увеличиваем счётчик
		ptr=obj.ptr;
		ptr=obj.ptr;
		count_copy++;
		//возвращаем сам объект для ситуации a=b=c
		return *this;
	}
	// уничтожение объекта
	~SmartPointer(){
		//если объект есть и копий нет
		if(ptr!=NULL&&count_copy==0){
			cout<<"\n~Delete Object\n";
			//уничтожаем объект
			delete[]ptr;
		}
		//в противном случае(уничтожается копия)
		else{
			//уменьшаем счётчик
			count_copy--;
			cout<<"\n~Delete Copy\n";
		}
			
	} 
	//старая добрая перегрузка селектора
	Temp* operator->(){
		return ptr;
	}

};

void main(){
	//создаем объект
	Temp*main_ptr=new Temp;
	//инициализируем этим объектом умный указатель
	SmartPointer PTR(main_ptr);
	//проверяем работу умного указателя
	PTR->TempSet(100);
	PTR->TempFunction();
	// создаем копию (работа конструктора копирования)
	SmartPointer PTR2=PTR;
}

Результат работы программы:
// работа с объектом через умный указатель
TEMP = 100
//уничтожение копии
~Delete Copy
//уничтожение самого объекта
~Delete Object