Лекции.Орг


Поиск:




Категории:

Астрономия
Биология
География
Другие языки
Интернет
Информатика
История
Культура
Литература
Логика
Математика
Медицина
Механика
Охрана труда
Педагогика
Политика
Право
Психология
Религия
Риторика
Социология
Спорт
Строительство
Технология
Транспорт
Физика
Философия
Финансы
Химия
Экология
Экономика
Электроника

 

 

 

 


Реализация smart-указателя




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

template <typename T>

struct Status { T *RealPtr; int Count;

};

template <typename T>

class Point

{ Status <T> *StatPtr;

Public:

Point (T * ptr = 0);

Point(const Point &);

~Point();

Point & operator =(const Point &);

T * operator->() const;

T & operator*() const;

void get_count() {cout<<StatPtr->Count<<endl;}

};

template<typename T>

Point<T>::Point(T * ptr)

{ if(!ptr)

StatPtr = NULL;

else

{ StatPtr = new Status <T>; StatPtr->RealPtr=ptr; StatPtr->Count = 1;

}

}

template <typename T>

Point<T>::Point(const Point & p): StatPtr(p.StatPtr)

{ if(StatPtr) StatPtr->Count++;

}

template <typename T>

Point<T>::~Point()

{ if(StatPtr)

{ StatPtr->Count--;

if(StatPtr->Count <= 0)

{delete StatPtr->RealPtr; delete StatPtr;

}

}

}

template <typename T>

T * Point <T>::operator->() const

{ if(StatPtr)

return StatPtr->RealPtr;

else return NULL;

}

 

 

template <typename T>

T & Point<T>::operator *() const

{ if(StatPtr) return *StatPtr->RealPtr;

else throw "Opps";

}

template <typename T>

Point<T> & Point<T>::operator =(const Point & p)

{ if(StatPtr)

{StatPtr->Count--;

if(StatPtr->Count <= 0)

{delete StatPtr->RealPtr; delete StatPtr;

}

}

StatPtr = p.StatPtr;

if(StatPtr) StatPtr->Count++; return * this;

}

struct Str

{ int a;

char c;

};

int main()

{ Point<Str> pt1(new Str); // генерация класса Point, конструирование

// объекта pt1, инициализируемого указателем

// на структуру Str, далее с объектом можно

// обращаться как с указателем

Point<Str> pt2=pt1,pt3; // для pt2 вызывается конструктор копирования,

// затем создается указатель pt3

pt3=pt1; // pt3 переназначается на объект указателя pt1

(*pt1).a=12; // operator*() получает this указатель на pt1

(*pt1).c='b';

int X=pt1->a; // operator->() получает this-указатель на pt1

char C=pt1->c;

return 0:

}

 

 

47.Свойства в С++.

В общем случае, свойство − это пара функций (public), одна из которых отвечает за установку компонент-данных (private) объекта, а другая за их считывание. Такое решение позволяет обеспечить инкапсуляцию данных. Необходимость использования свойств возникает тогда, когда при изменении некоторого параметра требуется произвести ещё некоторые действия.

Наиболее простой способ обеспечения инкапсуляции в C++ заключается в написании пары функций типа get_val() и put_val() для каждого параметра.

 

 

Модификатор _declspec получил дополнительный параметр «property». Это позволяет

в классе объявить «виртуальную» переменную и связать её с соответствующими

функциями.

class cls

{ int m;

public:

_declspec(property(get=get_val, put=put_val)) int V;

int get_val()

{ return m; }

void put_val(int v)

{ m = v; }

};

Мэин:

cls obj;

obj.V = 50; // при этом выполняется вызов put_val()

int k = obj.V; // при этом выполняется вызов get_val()

 

Основной недостаток:

Зависимость от компилятора. Нарушается инкапсуляция

 

Транзакции.

Транзакция может быть выполнена либо целиком и успешно, соблюдая целостность данных и независимо от параллельно идущих других транзакций, либо не выполнена вообще и тогда она не должна произвести никакого эффекта.

Пример: Необходимо перевести с банковского счёта номер 5 на счёт номер 7 сумму в 10 денежных единиц. Этого можно достичь, к примеру, приведённой последовательностью действий:

  • Начать транзакцию(прочесть баланс на счету номер 5; уменьшить баланс на 10 денежных единиц;сохранить новый баланс счёта номер 5;прочесть баланс на счету номер 7;увеличить баланс на 10 денежных единиц; сохранить новый баланс счёта номер 7
  • Окончить транзакцию

Эти действия представляют из себя логическую единицу работы «перевод суммы между счетами», и таким образом, являются транзакцией. Если прервать данную транзакцию, к примеру, в середине, и не аннулировать все изменения, легко оставить владельца счёта номер 5 без 10 единиц, тогда как владелец счета номер 7 их не получит.

____________________

template <class T1>

class A

{

T1 x;

public:

void set(T1 X){x=X;}

T1 get(){return x;}

void Show(){cout<<x<<endl;}

};

 

template <class T2>

class Tran

{

T2 *that; //текущее значение объекта класса A

T2 *prev; //предыдущее…

public:

Tran(){prev = NULL; that = new T2;}

Tran(const Tran &obj):that(new T2(*(obj.that))),prev(NULL){}//constr copy for A

~Tran() {delete prev; delete that;}

Tran &operator = (const Tran & obj);

void Show();

void Begin_Tran(); //начать

void Commit(); //закрепить

void Del_Tran(); //отменить

T2 *operator->();

};

template <class T2>

Tran <T2> & Tran <T2>::operator = (const Tran & obj)

{

if(this!=&obj) { delete that; that = new T2(*(obj.that)); } //prev не трогаем, чтобы

return *this; // можно было сделать откат

}

 

 





Поделиться с друзьями:


Дата добавления: 2016-07-29; Мы поможем в написании ваших работ!; просмотров: 436 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

Своим успехом я обязана тому, что никогда не оправдывалась и не принимала оправданий от других. © Флоренс Найтингейл
==> читать все изречения...

2397 - | 2213 -


© 2015-2025 lektsii.org - Контакты - Последнее добавление

Ген: 0.008 с.