Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Lect13

.pdf
Скачиваний:
6
Добавлен:
06.02.2016
Размер:
1.67 Mб
Скачать

Перегрузкапрефикснойформы инкрементаидекремента

Постфикснаяоперациявыполняетмодификацию объектаивозвращаетвременнуюконстантную копиюобъектадомодификации

Копиядолжнабытьконстантной,чтобынедопустить операцийвроде:

counter++ -= 3;

Синтаксиспостфикснойформыопераций:

Type const operator++(int)

Type const operator--(int)

Целочисленныйпараметрявляетсяфиктивнымислужит лишьдляразличияотпрефикснойформы

Сточкизренияздравогосмыслапостфиксную формуоперацийинкрементаидекрементаследует

основыватьнаихпрефикснойформе

41

 

Пример:счетчик

class Counter { public:

explicit Counter(unsigned maxValue,counter=0) :m_maxValue(maxValue), m_counter(counter){}

unsigned GetValue()const{return m_counter;} unsigned GetMaxValue()const{return m_maxValue;}

Counter& operator++() { ++m_counter;

if (m_counter>=m_maxValue){ m_counter = 0;

}

return *this;

}

Конструкторможет бытьпомечен как явный при помощи ключевого словаexplicit ,чтобызапретить возможностьегонеявного вызова вситуациях,вродеследующих:

CCounter counter(20, 5); counter=10;

эквивалентно:

CCounter counter(20, 5);

counter=CCounter(10, 0);

42

Пример:счетчик

//постфиксная форма инкремента

Counter const operator++(int) {

//создаем копию, выполняем префиксный

//инкремент, возвращаем копию

Counter tmpCopy(*this); ++*this;

return tmpCopy;

}

private:

unsigned m_maxValue, m_counter; };

43

Перегрузкаоперацийпотокового ввода-вывода

Перегрузкаоперацийформатированного ввода-выводавпотокиSTL неможетбыть выполненавнутрисамихклассовпотоков:

ВнесениемодификацийвSTL запрещено Стандартом

Объектыпотоковникоимобразомнесвязаныс пользовательскимитипамиданных

Дляперегрузкиоператоровввода-вывода следуетобъявлять ихвнекласса

Операторыформатированноговводавыводадолжнывозвращать ссылкунапоток

44

Выводпотокдлякласса"счетчик"

//выводим информацию о счетчике в виде

//[val/maxVal] в произвольный поток вывода template <class T>

std::basic_ostream<T>& operator<< (std::basic_ostream<T>& stream,

Counter const& counter) {

stream << "[" << counter.GetValue() << "/« << counter.GetMaxValue() << "]";

return stream;

}

45

Перегрузкачтенияизпотокадля

класса"счетчик"

template <class T> std::basic_istream<T>& operator>>

( std::basic_istream<T>& stream, Counter & counter){ std::streamoff pos = stream.tellg();

unsigned maxValue = 0; unsigned currentValue = 0; if ((stream.get() == '[')

&&(stream >> currentValue)

&&(stream.get() == '/')

&&(stream >> maxValue)

&&(stream.get() == ']')) {

counter = Counter(maxValue, currentValue); return stream;

}

46

Перегрузкачтенияизпотокадля класса"счетчик"

stream.seekg(pos);

stream.setstate(

std::ios_base::failbit | stream.rdstate()); return stream;

}

//Пример использования

int main(int argc, char* argv[]){ Counter c(10);

//Читаем в формате [counter/maxValue] cin >> c;

//Выводим в формате [counter/maxValue] cout << c;

return 0;

}

47

Умныеуказатели(Smart Pointers)

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

Перегрузкаопераций* и->,специфичных дляпростыхуказателей

Инкапсуляция семантикивладения ресурсомдляборьбысутечкамипамятии «висячими» ссылками

48

Примерумногоуказателя

class MyClassPtr { public:

MyClassPtr(MyClass * pMyClass):m_pMyClass(pMyClass){}

//деструктор автоматически

//удаляет управляемый объект

~MyClassPtr(){delete m_pMyClass;}

MyClass* operator->() { assert(m_pMyClass != NULL); return m_pMyClass;

}

49

Примерумногоуказателя

MyClass& operator*() { assert(m_pMyClass != NULL); return * m_pMyClass;

}

private:

//запрещаем копирование и

//присваивание указателей

MyClassPtr(MyClassPtr const&);

MyClassPtr& operator= (MyClassPtr const&);

MyClass *m_pMyClass; };

50

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]