Программирование >>  Инициализация объектов класса, структура 

1 ... 273 274 275 [ 276 ] 277 278 279 ... 395


#include Queue.h

#include ldouble.h

содержит:

class LongDouble { ... };

ostream& operator<<( ostream &, const LongDouble & );

int main() {

конкретизация Queue<LongDouble> Queue<LongDouble> *qld = new Queue<LongDouble>;

конкретизация Queue<LongDouble>::remove() вызывает оператор вывода для LongDouble qld->remove();

...

вызывался оператор operator (), ассоциированный с классом LongDouble:

Место в программе, где происходит конкретизация шаблона, называется точкой конкретизации. Она определяет, какие объявления принимаются компилятором во внимание для имен, зависящих от параметров шаблона.

Точка конкретизации шаблона всегда находится в области видимости пространства имен и непосредственно предшествует объявлению или определению, которое ссылается на

Имена, зависящие от параметров шаблона, разрешаются во время его конкретизации.

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

Разработчик класса должен позаботиться о том, чтобы были видимы объявления всех не зависящих от параметров шаблона имен, употребленных в его определении. Если объявление такого имени не найдено, то определение шаблона считается ошибочным. Если бы перед определением функции-члена remove() в шаблоне класса Queue не были включены файлы iostream и cstdlib, то в выражении

cout << удалено значение: ;

и при компиляции вызова функции exit() были бы обнаружены ошибки.

Второй шаг разрешения имени необходим, если поиск производится среди функций и операторов, зависящих от типа, которым конкретизирован шаблон. Например, если шаблон класса Queue конкретизируется типом класса LongDouble (см. раздел 16.9), то желательно, чтобы внутри функции-члена remove() в следующем выражении

cout << retval << endl;



#include <iostream> #include <cstdlib>

namespace cplusplus primer {

template <class Type> class Queue { ... };

template <class Type> Type Queue<Type>::remove() {

...

либо воспользоваться using-объявлением:

Если имя Queue шаблона класса используется вне пространства имен cplusplus primer, то оно должно быть квалифицировано этим именем или введено с помощью using-объявления. Во всех остальных отношениях шаблон Queue используется так, как описано выше: конкретизируется, может иметь функции-члены, статические члены, вложенные типы и т. д. Например:

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

В предыдущем примере точка конкретизации Queue<LongDouble> находится перед main() , и при разрешении зависящих от параметров имен, которые используются в определении шаблона Queue, компилятор просматривает все объявления до этой точки. Аналогично при таком разрешении в определении remove() компилятор просматривает все объявления до точки конкретизации, расположенной после main() .

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

16.12. Пространства имен и шаблоны классов

Как и любое определение в глобальной области видимости, определение шаблона класса можно поместить внутрь пространства имен. (Пространства имен рассматривались в разделах 8.5 и 8.6.) Наш шаблон будет скрыт в данном пространстве имен; лишь в этом отличие от ситуации, когда шаблон определен в глобальной области видимости. При употреблении вне пространства имя шаблона следует либо квалифицировать его именем,



int main() {

using cplusplus primer Queue; using-объявление

сс1лается на шаблон класса в пространстве имен cplusplus primer Queue<int> *p qi = new Queue<int>;

p qi->remove();

Шаблон cplusplus primer ::Queue<int> конкретизируется, так как использован в выражении new:

.. = new Queue<int>;

p qi - это указатель на тин класса cplusplus primer::Queue<int>. Когда он применяется для адресации функции-члена remove() , то речь идет о члене именно этого конкретизированного экземпляра класса.

Объявление шаблона класса в пространстве имен влияет также на объявления специализаций и частичных специализаций шаблона класса и его членов (см. разделы 16.9 и 16.10). Такая специализация должна быть объявлена в том же пространстве имен, где и общий шаблон.

В следующем примере в пространстве имен cplusplus primer объявляются специализации типа класса Queue<char *> и функции-члена remove() класса

#include <iostream> #include <cstdlib>

namespace cplusplus primer {

template <class Type> class Queue { ... };

template <class Type>

Type Queue<Type>::remove() { ... }

объявление специализации

для cplusplus primer::Queue<char

template<> class Queue<char*> { ...

объявление специализации

для функции-члена cplusplus primer::Queue<double>::remove() template<> double Queue<double>::remove()

Queue<double>:

Хотя специализации являются членами cplusplus primer, их определения в этом пространстве отсутствуют. Определить специализацию шаблона можно и вне пространства имен при условии, что определение будет находиться в некотором пространстве, объемлющем cplusplus primer, и имя специализации будет квалифицировано его именем :



1 ... 273 274 275 [ 276 ] 277 278 279 ... 395

© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика