Стенли Липпман - Язык программирования C++. Пятое издание
- Название:Язык программирования C++. Пятое издание
- Автор:
- Жанр:
- Издательство:Издательский дом Вильямс
- Год:2014
- Город:Москва
- ISBN:978-5-8459-1839-0
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стенли Липпман - Язык программирования C++. Пятое издание краткое содержание
Вы держите в руках новое издание популярного и исчерпывающего бестселлера по языку программирования С++, которое было полностью пересмотрено и обновлено под
. Оно поможет вам быстро изучить язык и использовать его весьма эффективными и передовыми способами. В соответствии с самыми передовыми и современными методиками изложения материала авторы демонстрируют использование базового языка и его стандартной библиотеки для разработки эффективного, читабельного и мощного кода.
С самого начала этой книги читатель знакомится со стандартной библиотекой С++, ее самыми популярными функциями и средствами, что позволяет сразу же приступить к написанию полезных программ, еще не овладев всеми нюансами языка. Большинство примеров из книги было пересмотрено так, чтобы использовать новые средства языка и продемонстрировать их наилучшие способы применения. Эта книга — не только проверенное руководство для новичков в С++, она содержит также авторитетное обсуждение базовых концепций и методик языка С++ и является ценным ресурсом для опытных программистов, особенно желающих побыстрей узнать об усовершенствованиях С++11.
Стенли Б. Липпман Жози Лажойе Барбара Э. Му • Узнайте, как использовать новые средства языка С++11 и стандартной библиотеки для быстрого создания надежных программ, а также ознакомьтесь с высокоуровневым программированием
• Учитесь на примерах, в которых показаны передовые стили программирования и методики проектирования
• Изучите принципы и узнайте почему язык С++11 работает именно так
• Воспользуйтесь множеством перекрестных ссылок, способных помочь вам объединить взаимосвязанные концепции и проникнуть в суть
• Ознакомьтесь с современными методиками обучения и извлеките пользу из упражнений, в которых подчеркиваются ключевые моменты, позволяющие избежать проблем
• Освойте лучшие методики программирования и закрепите на практике изученный материал
Исходный код примеров можно загрузить с веб-страницы книги на сайте издательства по адресу: http://www.williamspublishing.com
Язык программирования C++. Пятое издание - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Здесь создаются два экземпляра шаблона Numbers: версия average_ precision— экземпляр Numbersс заменой параметра Ттипом int; версия lots_of_precision— экземпляр Numbersс заменой параметра Т типом long double.
Упражнение 16.17. Каковы (если есть) различия между параметром типа, объявленным с ключевым словом typenameи ключевым словом class? Когда должно использоваться ключевое слово typename?
Упражнение 16.18. Объясните каждое из следующих объявлений шаблона функции и укажите, допустимы ли они. Исправьте все найденные ошибки.
(a) template void f1(T, U, V);
(b) template T f2(int &T);
(c) inline template T foo(T, unsigned int*);
(d) template f4(T, T);
(e) typedef char Ctype;
template Ctype f5(Ctype a);
Упражнение 16.19. Напишите функцию, получающую ссылку на контейнер и выводящую его элементы. Используйте переменную size_typeи функцию-член size()контейнера для контроля цикла, вывода элементов.
Упражнение 16.20. Перепишите функцию из предыдущего упражнения так, чтобы использовать для контроля цикла итераторы, возвращаемые функциями begin()и end().
16.1.4. Шаблоны-члены
У класса (обычного или шаблона класса) может быть функция-член, которая сама является шаблоном. Такие члены называются шаблонами-членами (member template). Шаблоны-члены не могут быть виртуальными.
В качестве примера обычного класса, у которого есть шаблон-член, определим класс, подобный стандартному типу функции удаления (deleter), используемой указателем unique_ptr(см. раздел 12.1.5). Как и у стандартной функции удаления, у данного класса будет перегруженный оператор вызова функции (см. раздел 14.8), который, получив указатель, выполняет для него оператор delete. В отличие от стандартной функции удаления, новый класс будет также выводить сообщения при каждом запуске. Поскольку создаваемую функцию удаления предстоит использовать с любым типом, сделаем оператор вызова шаблоном:
// класс объекта функции, вызывающий оператор delete для указателя
class DebugDelete {
public:
DebugDelete(std::ostream &s = std::cerr): os(s) { }
// подобно любым шаблонам функции, тип Т выводится компилятором
template void operator()(Т *p) const
{ os << "deleting unique_ptr" << std::endl; delete p; }
private:
std::ostream &os;
};
Как и любой другой шаблон, шаблон-член начинается с собственного списка параметров шаблона. У каждого объекта класса DebugDeleteесть переменная-член типа ostreamдля вывода и функция-член, которая сама является шаблоном. Этот класс можно использовать вместо оператора delete:
double* p = new double;
DebugDelete d; // объект, способный действовать как оператор delete
d(p); // вызывает DebugDelete::operator()(double*), удаляющий p
int* ip = new int;
// вызывает operator()(int*) для временного объекта DebugDelete
DebugDelete()(ip);
Поскольку вызов объекта DebugDeleteудаляет переданный ему указатель, его можно также использовать как функцию удаления для указателя unique_ptr. Чтобы переопределить функцию удаления указателя unique_ptr, укажем тип функции удаления в скобках и предоставим объект типа функции удаления конструктору (см. раздел 12.1.5):
// удалить объект, на который указывает p
// создает экземпляр DebugDelete::operator()(int *)
unique_ptr p(new int, DebugDelete());
// удаляет объект, на который указывает sp
// создает экземпляр DebugDelete::operator()(string*)
unique_ptr sp(new string, DebugDelete());
Здесь указано, что у функции удаления pбудет тип DebugDeleteи что предоставлен безымянный объект этого типа в конструкторе p().
Деструктор класса unique_ptrвызывает оператор вызова типа DebugDelete. Таким образом, при каждом вызове деструктора класса unique_ptrсоздается также экземпляр оператора вызова класса DebugDelete. Таким образом, определения выше создадут следующие экземпляры:
// примеры создания экземпляров шаблонов-членов DebugDelete
void DebugDelete::operator()(int *p) const { delete p; }
void DebugDelete::operator()(string *p) const { delete p; }
Шаблон-член можно также определить и для шаблона класса. В данном случае у и класса, и у его члена будут собственные, независимые параметры шаблона.
В качестве примера снабдим класс Blobконструктором, который получает два итератора, обозначающих диапазон копируемых элементов. Поскольку желательно обеспечить поддержку итераторов в различных видах последовательностей, сделаем этот конструктор шаблоном:
template class Blob {
template Blob(It b, It e);
// ...
};
У этого конструктора есть свой собственный параметр типа шаблона, It, который он использует для типа двух параметров функции.
В отличие от обычных функций-членов шаблонов класса, шаблоны-члены являются шаблонами функций. При определении шаблона-члена вне тела шаблона класса следует предоставить список параметров шаблона для шаблона класса и для шаблона функции. Список параметров для шаблона класса располагается сначала, затем следует список параметров шаблона-члена:
template // параметр типа для класса
template // параметр типа для конструктора
Blob::Blob(It b, It е) :
data(std::make_shared>(b, e)) { }
Здесь определяется член шаблона класса, у которого есть один параметр типа шаблона Т. Сам член является шаблоном функции, имеющий параметр типа It.
Чтобы создать экземпляр шаблона-члена шаблона класса, следует предоставить аргументы для параметров шаблона и класса, и функции. Как обычно, аргументы для параметров шаблона класса определяются типом объекта, через который происходит вызов шаблона-члена. Так же как обычно, компилятор, как правило, выводит тип аргументов шаблона для собственных параметров шаблона-члена из аргументов, переданных при вызове (см. раздел 16.1.1):
int ia[] = {0,1,2,3,4,5,6,7,8,9};
vector vi = {0,1,2,3,4,5,6,7,8,9};
list w = {"now", "is", "the", "time"};
// создает экземпляр класса Blob
// и конструктор Blob с двумя параметрами типа int*
Blob a1(begin(ia), end(ia));
// создает экземпляр конструктора Blob с двумя параметрами
// типа vector::iterator
Blob а2(vi.begin(), vi.end());
// создает экземпляр класса Blob и конструктор Blob
// с двумя параметрами типа list::iterator
Blob a3(w.begin(), w.end());
При определении a1указывается явно, что компилятор должен создать экземпляр шаблона Blobс параметром типа int. Параметр типа для его собственных параметров конструктора будет выведен из типа результатов вызова функций begin(ia)и end(ia). Этим типом является int*. Таким образом, определение a1создает следующий экземпляр:
Интервал:
Закладка: