Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Реализация компараторов




Вызов объекта

Часто мы хотим, чтобы для какой-то задачи можно было применить и функцию, и объект заранее заданного класса. Например, в алгоритме STL std::for_each вызывается одна и та же функция для всех объектов контейнера. Мы хотим иметь возможность:

1. Вызвать для каждого элемента контейнера функцию с одним параметром, передав в качестве параметра элемент (самый простой вариант).

2. Вызвать для каждого элемента контейнера функцию с несколькими параметрами, передав в качестве одного из них элемент, а в качестве других – фиксированные значения.

3. Вызвать для каждого элемента контейнера метод его класса (возможно, с передачей дополнительных параметров). Хочется иметь возможность применить этот метод и для контейнера указателей, и для контейнера объектов.

4. Вызвать для каждого элемента контейнера метод объекта определенного класса (возможно, с передачей дополнительных параметров).

Это действительно возможно сделать. Дело в том, что шаблон std::for_each выглядит примерно так:

template <class IterType,

class FunctionType> inline

FunctionType for_each(IterType _First, IterType _Last, FunctionType _Func)

{

for (IterType iter = _First; iter!= _Last; ++iter)

_Func(*iter);

return (_Func);

}

И в роли _Func может быть объект любого типа FunctionType – лишь бы этот объект можно было скопировать внутрь функции и вызвать, передав ему в качестве параметра *iter.

Соответственно, _Func может быть как указателем на функцию, принимающую тип элемента контейнера, так и объектом класса, имеющего метод:

void operator()(ElementType&)

Этого достаточно. Например, если хочется вызвать функцию с несколькими параметрами, мы можем написать код:

class Printer

{

public:

Printer(std::istream& stream)

:Stream(stream)

{

}

 

void operator()(int a)

{

Print(Stream, a);

}

private:

std::istream& Stream;

};

 

Printer printer(stream1);

std::for_each(int_vector.begin(), int_vector.end(), printer);

Для каждого элемента контейнера будет вызван operator() класса Printer и, как следствие, функция Print с двумя параметрами – в качестве первого будет передан stream1, в качестве второго – элемент контейнера.

Техника вызова объекта позволяет нам реализовать специальные объекты, отвечающие, например, за сравнение элементов контейнера. Часто мы хотим отделить знание о способе сравнения от типа элемента. Для этого нам достаточно передавать контейнеру специальный объект – компаратор. Контейнер при необходимости сравнить элементы будет вызывать метод operator() объекта-компаратора (или функцию сравнения). Метод (или функция) должны принимать два объекта заданного типа и возвращать bool (результат сравнения). Подробнее см. [2, разд. 4.3].




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


Дата добавления: 2015-01-03; Просмотров: 321; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.012 сек.