Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 08.03.2015, 01:23   #1
FIDE
Заблокирован
 
Регистрация: 02.08.2014
Сообщений: 30
Радость Реализация умных указателей

Всем привет. Учу С++, вот решил реализовать для себя умные указатели.Все работает нормально, утечек памяти нет. Но я хочу все-же что бы мой код проверили и сказали нет ли каких багов в моей реализации? Спасибо.
P.S Прошу не писать наподобие "Да нафиг оно надо? Есть готовое."
Код:
#include <iostream>
#include <conio.h>
#include <vld.h>//Visual Leak Detector для поиска утечек памяти

using namespace std;

class Temp
{
	int TEMP;    
public:
	Temp(){TEMP=25;}
	void TempFunction(){cout<<"TEMP = "<<TEMP<<"\n";} 
	void TempSet(int T){TEMP=T;}
};

template <typename T>//Реализация умного указателя
class SmartPointer
{
	T *ptr;
	int copy;
public:
	SmartPointer(T *p)
	{
		ptr=p;
		copy=0;
	}

	SmartPointer(const T &obj)
	{
		ptr=obj.ptr;
		copy=1;
	}

	SmartPointer operator=(const T &obj)
	{
		ptr=obj.ptr;
		copy=1;
	}

	~SmartPointer()
	{
		if (copy==0 && ptr!=NULL) 
		{
			delete ptr;
		}
	}

	T* operator ->()
	{
		return ptr;
	}

	T& operator*()
	{
		return *ptr;
	}

    
};

int main()
{
	SmartPointer <Temp> ptr(new Temp);
	ptr->TempSet(999);
	ptr->TempFunction();
	getch();
	return 0;
}
FIDE вне форума Ответить с цитированием
Старый 08.03.2015, 01:37   #2
Luuzuk
Форумчанин
 
Аватар для Luuzuk
 
Регистрация: 18.01.2012
Сообщений: 975
По умолчанию

Почитайте, сравните, сделайте выводы
http://wiki.dieg.info/smart_pointer
Благодарить в репутацию. Проклинать — туда же
Luuzuk вне форума Ответить с цитированием
Старый 08.03.2015, 14:05   #3
FIDE
Заблокирован
 
Регистрация: 02.08.2014
Сообщений: 30
По умолчанию

Будете смеяться, но я видел уже точно такой же код. Точь-в-точь. Но поскольку ничего не понял, решил сам написать умный указатель.
Код:
#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
Непонятно как деструктор работает...Почему delete[] а не просто delete?В общем принцип работы вообще тут непонятен мне...В перегруженном операторе присвоения одну строку 2 раза повторили - видимо ошиблись...
FIDE вне форума Ответить с цитированием
Старый 08.03.2015, 14:09   #4
FIDE
Заблокирован
 
Регистрация: 02.08.2014
Сообщений: 30
По умолчанию

Хотя в своем коде я вижу уже одну ошибку. Оператор = ничего не возвращает. Надо
Код:
SmartPointer operator=(const T &obj)
	{
		ptr=obj.ptr;
		copy=1;
                return *this;//На случай a=b=c
	}
FIDE вне форума Ответить с цитированием
Старый 08.03.2015, 14:20   #5
Luuzuk
Форумчанин
 
Аватар для Luuzuk
 
Регистрация: 18.01.2012
Сообщений: 975
По умолчанию

А то, что ваш код количество копий вообще не считает, в глаза не бросилось?

Цитата:
Почему delete[] а не просто delete
Ну представьте себе умный указатель на массив, и последствия освобождения его с помощью просто delete
Благодарить в репутацию. Проклинать — туда же
Luuzuk вне форума Ответить с цитированием
Старый 08.03.2015, 14:21   #6
FIDE
Заблокирован
 
Регистрация: 02.08.2014
Сообщений: 30
По умолчанию

Хм...А разве это обязательно? Задача сделать указатель который сам освободит память...
FIDE вне форума Ответить с цитированием
Старый 08.03.2015, 14:22   #7
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,709
По умолчанию

Для delete не нужна проверка на null.

Цитата:
Хм...А разве это обязательно? Задача сделать указатель который сам освободит память...
Почитайте, чем отличаются и для чего делались - auto_ptr, unique_ptr, shared_ptr, weak_ptr. Начать можете с http://rsdn.ru/article/cpp/smartptr.xml

Последний раз редактировалось p51x; 08.03.2015 в 14:25.
p51x вне форума Ответить с цитированием
Старый 08.03.2015, 14:27   #8
Luuzuk
Форумчанин
 
Аватар для Luuzuk
 
Регистрация: 18.01.2012
Сообщений: 975
По умолчанию

Цитата:
Задача сделать указатель который сам освободит память
и когда он должен это сделать?
Благодарить в репутацию. Проклинать — туда же
Luuzuk вне форума Ответить с цитированием
Старый 08.03.2015, 14:29   #9
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от FIDE Посмотреть сообщение
я хочу все-же что бы мой код проверили и сказали нет ли каких багов в моей реализации?

он у вас не может расшариваться. Значит счетчик копий вам не нужен.
Был бы нужен - нужно было бы использовать size_t, а не инт
_Bers вне форума Ответить с цитированием
Старый 08.03.2015, 14:31   #10
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Код:
SmartPointer(const T &obj)
	{
		ptr=obj.ptr;  //<--- WTF ???
		copy=1;
	}
код на выброс.

все не правильно.
_Bers вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Правильна ли такая реализация списка из указателей на базовый класс? Archet Общие вопросы C/C++ 14 18.01.2012 16:08
АТД: Реализация списка с использованием указателей Suslik963 Помощь студентам 1 17.11.2010 10:06
Ищу умных людей по с++ Maver1k[Kiev] Свободное общение 3 24.03.2010 10:22
прошу помощи у умных людей... lesimel C++ Builder 12 21.12.2009 09:09