Файл: Pobegaylo_A._C_Cplus_dlya_studenta.pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 13.12.2020

Просмотров: 4319

Скачиваний: 28

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

Глава 19. Шаблоны классов 

271 

int main() 

  Demo<int> d(10); 
  cout << add(d, d.get()) << endl;    // 20

 

 
  return 0; 

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

what

  приведен  в  лис-

тинге 19.12. 

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

Листинг 19.12. Функция друг шаблона класса 

#include <iostream> 
using namespace std; 
 
template <class T> class Demo 

  T t; 
public: 
  Demo(T _t): t(_t) {} 
  friend T what(const Demo<T> &d) { return d.t; } 
}; 
 
int main() 

  Demo<int> a(10); 
  cout << what(a) << endl;  // печатает 10 


background image

Часть II. Язык программирования С++ 

272 

  Demo<double> b(5.5); 
  cout << what(b) << endl;  // печатает 5.5 
 
  return 0; 

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

friend

, но параметры этих шаблонов не являются 

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

Листинг 19.13. Шаблон функции друг шаблона класса 

#include <iostream> 
using namespace std; 
 
template <class T> class Demo 

  int n; 
  T t; 
public: 
  Demo(T _t, int _n): t(_t), n(_n) {}; 
  T get() { return n; } 
  template <class S> friend S sum(Demo<S> *d, S s); 
}; 
template <class S> S sum(Demo<S> *d, S s) { return d->n + s; } 
 
int main() 

  Demo<int> d(10, 10); 
  cout << sum<double>((Demo<double>*)&d, d.get()) 
       << endl;  // 20 
  return 0; 


background image

Глава 19. Шаблоны классов 

273 

19.9. Шаблоны класса  
и наследование 

Шаблоны  классов  можно  использовать  в  построении  иерархии 
классов.  Но  в  этом  случае  следует  принимать  во  внимание,  что 
имя  каждой  специализации  шаблона  класса  включает  также  ар-
гументы этого шаблона, заключенные в угловые скобки. 
Например, в листинге 19.14 приведена иерархия классов, которая 
включает шаблонные классы. 

Листинг 19.14. Иерархия классов, включающая шаблонные классы 

#include <iostream> 
using namespace std; 
 
template <class S, class T> struct Base 

  S s; 
  T t; 
}; 
template <class S, class T, class R> 
struct Derived: Base<S, T> 

  R r; 
}; 
struct Demo: Base<int, double> 

  char* p; 
}; 
int main() 

  Derived<int, double, char*> a; 
  a.s = 10; 
  a.t = 1.5; 
  a.r = "aaa"; 
 
  Demo d; 
  d.s = 20; 


background image

Часть II. Язык программирования С++ 

274 

  d.t = 2.5; 
  d.p = "bbb"; 
 
  Base<int, double> &b = d; 
  cout << b.s << ' ' << b.t << endl;  // 20 2.5 
 
  return 0; 

19.10. Шаблоны класса  
как параметры шаблонов функций 

Шаблон  класса  может  быть  параметром  шаблона  функции.  На-
пример, в листинге 19.15 приведен пример определения шаблона 
функции 

foo

, параметром которой является шаблон класса. Заме-

тим, что параметр (тип) 

S

  шаблона  класса,  который  является  па-

раметром шаблона функции, используется только в списке пара-
метров шаблона и не может использоваться в заголовке или теле 
функции. 

Листинг 19.15. Шаблон функции, параметром которого  
является шаблон класса 

#include <iostream> 
using namespace std; 
 
template <class T> class Demo 

  T t; 
public: 
  Demo(const T& _t): t(_t) {} 
  T foo() { return t; } 
}; 
template <class R, template<class S> class T> R foo(Demo<T> d) 

  return d.foo(); 
}; 


background image

Глава 19. Шаблоны классов 

275 

int main() 

  Demo<int> d(10); 
  cout << foo<int>(d) << endl;  // 10 
 
  return 0; 

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

foo

  из  листинга  19.15  может 

быть определен следующим образом: 

template <class R, template<class S = int> class T> R 
foo(Demo<T> d) 

    return d.foo(); 
}; 

19.11. Шаблоны класса  
как параметры шаблона класса 

Шаблон  класса  может  быть  также  параметром  шаблона  класса. 
Но  в  этом  случае  при  определении  шаблона  класса  запрещается 
использовать ключевые слова 

struct

 и 

union

Например,  в  листинге  19.16  приведен  пример  определения  шаб-
лона  класса 

Demo

,  параметром  которого  является  шаблон  класса 

Box

. Как и в случае с шаблоном функции заметим, что параметр 

(тип) 

S

  шаблона  класса,  который  является  параметром  шаблона 

класса,  используется  только  в  списке  параметров  шаблона  и  не 
может использоваться в теле класса при определении его членов. 

Листинг 19.16. Шаблон класса, параметром которого является 
шаблон класса 

#include <iostream> 
using namespace std; 


Смотрите также файлы