16.5. Статические члены шаблонов класса

16.5. Статические члены шаблонов класса

В шаблоне класса могут быть объявлены статические данные-члены. Каждый конкретизированный экземпляр имеет собственный набор таких членов. Рассмотрим операторы new() и delete() для шаблона QueueItem. В класс QueueItem нужно добавить два статических члена:

static QueueItemType *free_list;

static const unsigned QueueItem_chunk;

Модифицированное определение шаблона QueueItem выглядит так:

#include cstddef

template class Type

class QueueItem {

// ...

private:

void *operator new( size_t );

void operator delete( void *, size_t );

// ...

static QueueItem *free_list;

static const unsigned QueueItem_chunk;

// ...

};

Операторы new() и delete() объявлены закрытыми, чтобы предотвратить создание объектов типа QueueItem вызывающей программой: это разрешается только членам и друзьям QueueItem (к примеру, шаблону Queue).

Оператор new() можно реализовать таким образом:

template class Type void*

QueueItemType::operator new( size_t size )

{

QueueItemType *p;

if ( ! free_list )

{

size_t chunk = QueueItem_chunk * size;

free_list = p =

reinterpret_cast QueueItem Type *

( new char[chunk] );

for ( ; p != &free_list[ QueueItem_chunk - 1 ]; ++p )

p- next = p + 1;

p- next = 0;

}

p = free_list;

free_list = free_list- next;

return p;

}

А реализация оператора delete() выглядит так:

template class Type

void QueueItemType ::

operator delete( void *p, size_t )

{

static_cast QueueItemType * ( p )- next = free_list;

free_list = static_cast QueueItemType * ( p );

}

Теперь остается инициализировать статические члены free_list и QueueItem_chunk. Вот шаблон для определения статических данных-членов:

/* для каждой конкретизации QueueItem сгенерировать

* соответствующий free_list и инициализировать его нулем

*/

template class T

QueueItemT *QueueItemT::free_list = 0;

/* для каждой конкретизации QueueItem сгенерировать

* соответствующий QueueItem_chunk и инициализировать его значением 24

*/

template class T

const unsigned int

QueueItemT::QueueItem_chunk = 24;

Определение шаблона статического члена должно быть вынесено за пределы определения самого шаблона класса, которое начинается с ключевого слово template с последующим списком параметров . Имени статического члена предшествует префикс QueueItem::, показывающий, что этот член принадлежит именно шаблону QueueItem. Определения таких членов помещаются в заголовочный файл Queue.h и должны включаться во все файлы, где производится их конкретизация. (В разделе 16.8 мы объясним, почему решили делать именно так, и затронем другие вопросы, касающиеся модели компиляции шаблонов.)

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

// ошибка: QueueItem - это не реальный конкретизированный экземпляр

int ival0 = QueueItem::QueueItem_chunk;

int ival1 = QueueItemstring::QueueItem_chunk; // правильно

int ival2 = QueueItemint::QueueItem_chunk; // правильно

Упражнение 16.7

Реализуйте определенные в разделе 15.8 операторы new() и delete() и относящиеся к ним статические члены screenChunk и freeStore для шаблона класса Screen, построенного в упражнении 16.6.

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

5.4.4 Статические Члены

Из книги C++ автора Хилл Мюррей

5.4.4 Статические Члены Класс – это тип, а не объект данных, и в каждом объекте класса имеется своя собственная копия данных, членов этого класса. Однако некоторые типы наиболее элегантно реализуются, если все объекты этого типа могут совместно использовать (разделять)


5.4.4 Статические Члены

Из книги Справочное руководство по C++ автора Страустрап Бьярн

5.4.4 Статические Члены Класс – это тип, а не объект данных, и в каждом объекте класса имеется своя собственная копия данных, членов этого класса. Однако некоторые типы наиболее элегантно реализуются, если все объекты этого типа могут совместно использовать (разделять)


5.5.4 Объекты Класса как Члены

Из книги Язык программирования С# 2005 и платформа .NET 2.0. [3-е издание] автора Троелсен Эндрю

5.5.4 Объекты Класса как Члены Рассмотримclass classdef (* table members; int no_of_members; // ... classdef(int size); ~classdef(); *);Очевидное намерение состоит в том, что classdef должен содержать таблицу длиной size из членов members, а сложность – в том, как сделать так, чтобы конструктор table::table() вызывался с параметром


8.5.1 Статические Члены

Из книги C++ для начинающих автора Липпман Стенли

8.5.1 Статические Члены Член данные класса может быть static; члены функции не могут. Члены не могут быть auto, register или extern. Есть единственная копия статического члена, совместно используемая всеми членами класса в программе. На статический член mem класса cl можно ссылаться cl:mem,


R.9.2 Члены класса

Из книги автора

R.9.2 Члены класса список-членов: описание-члена список-членов opt спецификация-доступа : список-членов optописание-члена: спецификации-описания opt список-описателей-членов opt ; определение-функции ; opt уточненное-имя


R.9.4 Статические члены

Из книги автора

R.9.4 Статические члены Для члена класса, представляющего данные или функцию, можно при описании класса задать спецификацию static. Для статического члена, представляющего данные, в программе существует только один экземпляр, которым владеют все объекты этого класса.


R.14.6 Функции-члены шаблонов типа

Из книги автора

R.14.6 Функции-члены шаблонов типа Функция-член шаблонного класса считается неявной шаблонной функцией, а параметры шаблона типа для ее класса - ее шаблонными параметрами. Приведем пример, в котором описаны три шаблона типа для функции:template‹class T› class vector { T* v; int


R.14.8 Статические члены и переменные

Из книги автора

R.14.8 Статические члены и переменные Для каждого шаблонного класса или функции, создаваемых по шаблону типа, образуется своя копия статических переменных или членов. Рассмотрим пример:template‹class T› class X { static T s; //…};X‹int› aa;X‹char*› bb;Здесь в классе X‹int› есть статический член


Статические члены System.Object

Из книги автора

Статические члены System.Object В завершение нашего обсуждения базового класса .NET, находящегося на вершине иерархии классов, следует отметить, что System.Object определяет два статических члена (Object.Equals() и Object.ReferenceEquals()), обеспечивающих проверку на равенство значений и ссылок


13.3. Функции-члены класса

Из книги автора

13.3. Функции-члены класса Функции-члены реализуют набор операций, применимых к объектам класса. Например, для Screen такой набор состоит из следующих объявленных в нем функций-членов:class Screen {public:void home() { _cursor = 0; }char get() { return _screen[_cursor]; }char get( int, int );void move( int, int );bool checkRange( int, int );int


13.5. Статические члены класса

Из книги автора

13.5. Статические члены класса Иногда нужно, чтобы все объекты некоторого класса имели доступ к единственному глобальному объекту. Допустим, необходимо подсчитать, сколько их было создано; глобальным может быть указатель на процедуру обработки ошибок для класса или,


13.5.1. Статические функции-члены

Из книги автора

13.5.1. Статические функции-члены Функции-члены raiseInterest() и interest() обращаются к глобальному статическому члену _interestRate:class Account {public:void raiseInterest( double incr );double interest() { return _interestRate; }private:static double _interestRate;};inline void Account::raiseInterest( double incr ){_interestRate += incr;}Проблема в том, что любая функция-член


13.6.3. Указатели на статические члены класса

Из книги автора

13.6.3. Указатели на статические члены класса Между указателями на статические и нестатические члены класса есть разница. Синтаксис указателя на член класса не используется для обращения к статическому члену. Статические члены – это глобальные объекты и функции,


15.1.1. Члены и не члены класса

Из книги автора

15.1.1. Члены и не члены класса Рассмотрим операторы равенства в нашем классе String более внимательно. Первый оператор позволяет устанавливать равенство двух объектов, а второй – объекта и C-строки:#include "String.h"int main() {String flower;// что-нибудь записать в переменную flowerif ( flower == "lily" ) //


16.3. Функции-члены шаблонов классов

Из книги автора

16.3. Функции-члены шаблонов классов Как и для обычных классов, функция-член шаблона класса может быть определена либо внутри определения шаблона (и тогда называется встроенной), либо вне его. Мы уже встречались со встроенными функциями-членами при рассмотрении шаблона Queue.


16.3.1. Функции-члены шаблонов Queue и QueueItem

Из книги автора

16.3.1. Функции-члены шаблонов Queue и QueueItem Чтобы понять, как определяются и используются функции-члены шаблонов классов, продолжим изучение шаблонов Queue и QueueItem:template class Typeclass Queue {public:Queue() : front( 0 ), back ( 0 ) { }~Queue();Type& remove();void add( const Type & );bool is_empty() const {return front == 0;}private:QueueItem Type