Lect14
.pdfШаблонныеоператоры
Оператор– частныйслучайфункции,и онтакжеможетбытьшаблонным
Пример– разработатьдлякласса «Счетчик»шаблонныеоператоры<< и >> дляработыс классамистандартных потоковSTL
11
Класс"Счетчик"
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;
}
12
Класс"Счетчик"
Counter const operator++(int) { Counter tmpCopy(*this); ++*this;
return tmpCopy;
}
private:
unsigned m_maxValue, m_counter; };
13
Перегрузкаоперациипотокового выводадлякласса"Счетчик"
//выводим информацию о счетчике в виде
//[counter/maxValue]
//в произвольный поток вывода
template <class T> std::basic_ostream<T>& operator<< ( std::basic_ostream<T>& stream,
Counter const& counter) {
stream << "[" << counter.GetValue() << "/" << counter.GetMaxValue() << "]";
return stream;
}
14
Перегрузкаоперациичтенияиз
потокадлякласса"Счетчик"
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() == ']')) {
15
Перегрузкаоперациичтенияиз потокадлякласса"Счетчик"
counter = CCounter(maxValue, currentValue); return stream;
}
stream.seekg(pos); stream.setstate(std::ios_base::failbit
| stream.rdstate());
return stream;
}
16
Примерперегрузкиоперации+
template<typename T>
long operator+(const bigint& x, const T& y);
bigint a; a = a + 42;
// Явное инстанцирование
a = operator+<long>(a, 42);
17
Шаблоныклассов
Подобношаблонамфункцийпрограммисту можетпонадобитьсяиметьшаблоныклассов
◦ Онизадаютспособыпостроенияотдельных классов,подобнотому,какклассзадаетспособ построенияотдельныхобъектов
Шаблонныеклассыширокоиспользуютсяв библиотекахSTL иBOOST,например,для реализацииконтейнеровиумных указателей
Исходныйкодметодовшаблонногокласса такжедолженбытьдоступенизвсехединиц
компиляции,гдеониспользуется
18
Шаблоныклассов
template <class T> |
|
class Array { |
|
public: |
|
Array(){...} |
|
virtual ~Array(){...} |
|
unsigned GetLength()const{...} |
|
void Push(T const& item){...} |
|
T& operator[](unsigned index){...} |
|
T const& operator[](unsigned index)const{...} |
|
void Resize(unsigned newSize){...} |
|
Array(Array const&){...} |
|
Array operator=(Array const&){...} |
|
private: |
|
T * m_pItems; |
|
unsigned m_size; |
19 |
}; |
|
Шаблоныклассов
int main() { Array<int> intArray; intArray.Push(3); intArray.Push(4); intArray[0] = 2; intArray.Resize(1);
Array<std::string> stringArray; stringArray.Push("Hello"); stringArray.Push("World"); stringArray[0] = ("Goodbye");
return 0;
} |
20 |