Регистрация Главная Сообщество
Сообщения за день Справка Регистрация
Навигация
Zhyk.org LIVE! Реклама на Zhyk.org Правила Форума Награды и достижения Доска "почета"

Ответ
 
Опции темы
Старый 05.12.2008, 17:04   #1
Заблокирован
 Старший сержант
Аватар для shagart
 
shagart у всех на слухуshagart у всех на слухуshagart у всех на слухуshagart у всех на слухуshagart у всех на слухуshagart у всех на слухуshagart у всех на слухуshagart у всех на слухуshagart у всех на слухуshagart у всех на слуху
Регистрация: 16.07.2008
Сообщений: 209
Популярность: 1335
Сказал(а) спасибо: 231
Поблагодарили 236 раз(а) в 134 сообщениях
Отправить сообщение для shagart с помощью ICQ Отправить сообщение для shagart с помощью Telegram Отправить сообщение для shagart с помощью Yahoo Отправить сообщение для shagart с помощью Skype™
 
По умолчанию Ведущие указатели (Master Pointers). Важные конструкторы

Если мы уж взялись заниматься умными указателями, то очень быстро придем к выводу, что неплохо ограничить их свободу так, чтобы два указателя не указывали на один объект. Далее я их называю ведущими указателями. Для этого нужно реализовать буквально три-четыре правила:
Порождение ведущего указателя порождает объект, уничтожение ведущего указателя уничтожает объект;
Копирование ведущего указателя создает точную копию объекта;
Присваивание ведущего указателя уничтожает предыдущий объект и ставит на его место копию нового объекта.

Если же мы хотим получить однозначное соответствие объекта и его ведущего указателя, то нужно запретить создание объекта, кроме как при помощи ведущего указателя, и запретить создание ведущего указателя, кроме как специальной функцией. Последнее в общем не обязательно, а первое весьма важно.

Такие простые, но замечательно полезные механизмы просто сами набираются на клавиатуре сначала в виде класса, а потом в виде шаблона класса (мы же не последний день на свете живем, пригодится еще).
Код:
class CThat
{
private:
	int i;
public:
	CThat (int _i=0):i(_i){};
	CThat (const CThat& _that):i(_that.i){};
	CThat& operator=(const CThat& _that)
	{
		if (this == &_that)
			return *this;
		i = _that.i;
		return *this;
	};
};

class MasterPointer
{
private:
  CThat* t;
public:
//	MasterPointer():t(new CThat){};
	MasterPointer(CThat _that=0):t(new CThat(_that)){};
	MasterPointer(const MasterPointer& mp):t(new CThat((*mp.t))){};
	~MasterPointer(){delete t;};
	MasterPointer& operator=(const MasterPointer& mp)
	{
		if (this!=&mp)
		{
			delete t;
			t= new CThat(*(mp.t));
		}
		return *this;
	};
};
Напоминать не надо, что this - это указатель на самого себя? Кстати и оказалось, что для реализации ведущего указателя класс указываемого объекта должен и сам иметь:
Конструктор без аргументов или с аргуметами, имеющими значения по умолчанию (default constructor) . Компилятор вам нарисует такой один, если вы не определите конструкторов вообще никаких. На вид это будет просто ежик чернобыльский. Попытка создать внутри функции (я имею в виду в стеке) массив таких объектов наплодит вам массив дегенератов (это вне семантики ведущих указателей, мы же договариваемся, что без ведущих указателей такие объекты вообще не существуют). Так что не рискуйте.
Конструктор копии. Если вы не определите его, то компилятор нарисует свой. ТАКОЕ компилятору можно позволять только в крайнем случае, или перед пенсией, ибо по сравнению с этим чудовищем упомянутый ранее ежик просто Киану Ривз.
Оператор присваивания. То же самое. Подробности можно узнать в любой книге по C++, или в киоске с видеокассетами в разделе "Ужасы".
Виртуальный деструктор. Ну это еще ничего. Если Вы его не определите, то компилятор не задушит Вас ночью. Но вообще... должны быть очень серьезные причины для того, чтобы деструктор не был виртуальным, если вы наследуете свой класс или собираетесь от него наследовать.

Кстати, пока я нахожусь в этой теме, хочу заметить, понятия "конструктор по умолчанию", "конструктор без аргументов" и "конструктор, генерируемый компилятором" легко спутать, если сразу не уяснить их отношения. Конструктор по умолчанию - это конструктор, который может быть вызван без указания агрументов. Он может иметь аргументы, но все они имеют значения по умолчанию. Конструктор без аргументов - тот, у которого аргументы вообще не определены. Конструкторы, генерируемые компилятором - два конструктора - без аргументов и копии - создаются только в том случае, если Вы не определили других конструкторов.

Вернемся же однако к коду. Я определил два конструктора без аргументов и один закомментировал. Оставленный конструктор меня больше устраивает, но он не годится для преобразования кода в шаблон. Поэтому в шаблоне используется первый. Оператор присваивания проверяет, не происходит ли присвоение самому себе. Это всегда важно, поскольку если не проверить, то следующим шагом мы уничтожим содержимое, так и не оставив себе ничего на память. Поскольку все вроде нормально, рисуем шаблон.
template <class T> class MP
Код:
{
private:
	T* t;
public:
	MP():t (new T){};
	MP(const MP<T>& mp):t(new T((*mp.t))){};
	~MP(){delete t;};
	MP<T>& operator=(const MP<T>& mp)
	{
		if (this!=&mp)
		{
			delete t;
			t= new T(*(mp.t));
		}
		return *this;
	};
};
ЖЕстко копипастю с ридмишек)))
  Ответить с цитированием
2 пользователя(ей) сказали cпасибо:
Ivan_32 (05.12.2008), Sergara93 (18.12.2008)
Ответ

Метки
важные конструкторы, ведущие, указатели


Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
[2Moons Online] Hack Pack by Master Zhyk Прочее 3 07.08.2009 13:16
[Руководство] Умные указатели shagart С/С++ 0 05.12.2008 16:52
[racing] Rally Master Pro Zhyk Гонки и прочие спортивные 0 22.06.2008 12:30

Заявление об ответственности / Список мошенников

Часовой пояс GMT +4, время: 22:47.

Пишите нам: [email protected]
Copyright © 2024 vBulletin Solutions, Inc.
Translate: zCarot. Webdesign by DevArt (Fox)
G-gaMe! Team production | Since 2008
Hosted by GShost.net