Информация о курсе в систематизированном виде излагаются основные понятия и описываются возможности языка C++. При этом основное внимание уделяется объяснению того, как теми или иными возможностями пользоваться



бет15/15
Дата16.07.2016
өлшемі1.19 Mb.
#204086
түріИнформация
1   ...   7   8   9   10   11   12   13   14   15

template

SmartPtr ::~SmartPtr()

{

if (refPtr != 0) {

refPtr->counter--;

if (refPtr->counter <= 0) {

delete refPtr->realPtr;

delete refPtr;

}

}

}

Реализация операций -> и * довольно проста:



template

T*

SmartPtr::operator->() const

{

if (refPtr != 0)

return refPtr->realPtr;

else

return 0;

}

template

T&

SmartPtr::operator*() const

{

if (refPtr != 0)

return *refPtr->realPtr;

else

throw bad_pointer;

}

Самые сложные для реализации – копирующий конструктор и операции присваивания. При создании объекта SmartPtr – копии имеющегося – мы не будем копировать сам исходный объект. Новый "интеллигентный указатель" будет ссылаться на тот же объект, мы лишь увеличим счетчик ссылок.



template

SmartPtr::SmartPtr(const

SmartPtr& s):refPtr(s.refPtr)

{

if (refPtr != 0)

refPtr->counter++;

}

При выполнении присваивания, прежде всего, нужно отсоединиться от имеющегося объекта, а затем присоединиться к новому, подобно тому, как это сделано в копирующем конструкторе.



template

SmartPtr&

SmartPtr::operator=(const SmartPtr& s)

{

// отсоединиться от имеющегося указателя

if (refPtr != 0) {

refPtr->counter--;

if (refPtr->counter <= 0) {

delete refPtr->realPtr;

delete refPtr;

}

}

// присоединиться к новому указателю

refPtr = s.refPtr;

if (refPtr != 0)

refPtr->counter++;

}

В следующей функции при ее завершении объект класса Complex будет уничтожен:



void foo(void)

{

SmartPtr complex(new Complex);

SmartPtr ptr = complex;

return;

}

18.5 Задание свойств класса

Одним из методов использования шаблонов является уточнение поведения с помощью дополнительных параметров шаблона. Предположим, мы пишем функцию сортировки вектора:

template

void sort_vector(vector& vec)

{

for (int i = 0; i < vec.size() -1; i++)

for (int j = i; j < vec.size(); j++) {

if (vec[i] < vec[j]) {

T tmp = vec[i];

vec[i] = vec[j];

vec[j] = tmp;

}

}

}

Эта функция будет хорошо работать с числами, но если мы захотим использовать ее для массива указателей на строки (char*), то результат будет несколько неожиданный. Сортировка будет выполняться не по значению строк, а по их адресам (операция "меньше" для двух указателей – это сравнение значений этих указателей, т.е. адресов величин, на которые они указывают, а не самих величин). Чтобы исправить данный недостаток, добавим к шаблону второй параметр:



template

void sort_vector(vector& vec)

{

for (int i = 0; i < vec.size() -1; i++)

for (int j = i; j < vec.size(); j++) {

if (Compare::less(vec[i], vec[j])) {

T tmp = vec[i];

vec[i] = vec[j];

vec[j] = tmp;

}

}

}

Класс Compare должен реализовывать статическую функцию less, сравнивающую два значения типа T. Для целых чисел этот класс может выглядеть следующим образом:



class CompareInt

{

static bool less(int a, int b)

{ return a < b; };

};

Сортировка вектора будет выглядеть так:



vector vec;

sort(vec);

Для указателей на байт (строк) можно создать класс



class CompareCharStr

{

static bool less(char* a, char* b)

{ return strcmp(a,b) >= 0; }

};

и, соответственно, сортировать с помощью вызова



vector svec;

sort(svec);

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



template Compare

{

static bool less(T a, T b)

{ return a < b; };

};

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



vector dvec;

sort >(dvec);

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



template >

void sort_vector(vector& vec)

{

for (int i = 0; i < vec.size() -1; i++)

for (int j = i; j < vec.size(); j++) {

if (C::less(vec[i], vec[j])) {

T tmp = vec[i];

vec[i] = vec[j];

vec[j] = tmp;

}

}

}

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



Литература

  1. Фридман А.Л.
    Язык программирования Си++
    Интернет-университет информационных технологий - ИНТУИТ.ру, 2004

  2. Фридман А.Л.
    Основы объектно-ориентированного программирования на языке Си++. Учебный курс
    Радио и связь, 1999

  3. Бьерн Страуструп
    Язык программирования C++, 3 издание
    Невский Диалект, 1999

  4. Мейерс С.
    Эффективное использование C ++. 50 рекомендаций по улучшению ваших программ и проектов
    ДМК, 2000

  5. Шилдт Герберт. Самоучитель С++ (2-ред)./Пер. с англ.-СПб.: BHV-Санкт-Петербург, 1997.-512с. (+дискета с примерами)

  6. Бруно Бабэ. Просто и ясно о Borland C++: Версии 4.0 и 4.5/ Пер. с англ. -М.:БИНОМ, 1994. - 400с.

  7. Клочков Д.П., Павлов Д.А. Введение в объектно-ориентированное программирование. / Учебно-методическое пособие. - Изд. Нижегор. ун-та, 1995. - 70с.

  8. Элиас М., Страуструп Б. Справочное руководство по языку С++ с комментариями. /Пер. с англ. -М.:Мир, 1992.- с.





Достарыңызбен бөлісу:
1   ...   7   8   9   10   11   12   13   14   15




©dereksiz.org 2024
әкімшілігінің қараңыз

    Басты бет