Студопедия

КАТЕГОРИИ:


Архитектура-(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)

Исключение ненужных инстанцирований функций-членов

Шаблоны

Включение

 

Виды включения: композиция и агрегация.

 

 

В C++ ключевое слово template используется для обеспечения параметрического полиморфизма. Он позволяет применять один и тот же исходный код к разным типам, причем тип является параметром тела кода.

Допустим у нас есть класс stack3, который реализует концепцию стека символов (char).

 

class stack3

{

public:

stack3();

void push(char c);

char pop();

bool is_empty()const;

bool is_full()const;

private:

enum{ max_len=100};

int top;

char s[max_len];

 

};

 

Функции реализованы следующим образом:

 

stack3::stack3():top(0){}

void stack3::push(char c){

assert(top<max_len);

s[top++]=c;

}

char stack3::pop(){

assert(top>0);

return s[--top];

}

bool stack3::is_empty()const {return top==0;}

bool stack3::is_full()const {return top==max_len;}

 

Мы можем использовать объекты этого класса следующим образом:

 

stack3 reverse_order(stack3 s){

stack3 tmp;

while(!s.is_empty()){

tmp.push(s.pop());

}

return tmp;

}

Пример шаблона класса:

template <class T> class stack4

{

public:

stack4(); //конструктор

void push(T c);

T pop();

bool is_empty()const;

bool is_full()const;

private:

enum{ max_len=100};

int top;

T s[max_len];

};

 

template<class T>stack4<T>::stack4():top(0){}

 

template<class T>void stack4<T>::push(T c){

assert(top<max_len);

s[top++]=c;

}

 

template<class T>T stack4<T>::pop(){

assert(top>0);

return s[--top];

}

 

template<class T>bool stack4<T>::is_empty()const {return top==0;}

 

template<class T>bool stack4<T>::is_full()const

{return top==max_len;}

 

Префикс template <class T> указывает, что объявлен шаблон (template), и что в объявлении на месте T будет указан фактический тип. T – имя типа, а не обязательно класса.

Имя шаблона класса, за которым следует тип, помещенный в угловые скобки <>, является именем класса (определяемого шаблона) и его можно использовать точно так же, как имена других классов:

stack4<char> sc;

stack4<int> si;

stack4<char*> sd;

Без использования шаблонов для реализации этого примера пришлось бы писать три определения классов, а с использованием шаблона – только одно определение шаблона.

 

Функция, работающая со стеком stack4<double>:

 

stack4<double> reverse_order(stack4<double> s){

stack4<double> tmp;

while(!s.is_empty()){

tmp.push(s.pop());

}

return tmp;

}

 

Шаблон функции, работающий с любым стеком:

 

template <class STACK> STACK reverse_order(STACK s){

STACK tmp;

while(!s.is_empty()){

tmp.push(s.pop());

}

return tmp;

}

 

 

 

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

 

stack4<char> sc;//генерируется 5 функций

stack4<int> si1, si2;// генерируется 5 функций

//(количество создаваемых объектов не играет роли)

stack4<char> sd;//не генерируется новых функций, так как инстанцирование stack4<char> уже было выше

 

В нашем классе stack функции push и pop зависят от параметра шаблона, поэтому их генерирование необходимо. Так, функция push, сгенерированная для параметра char, работает не так, как функция push, сгенерированная для параметра int. В то же время функции is_empty и is_full от параметра шаблона не зависят. Функция is_empty для char абсолютно идентична функции is_empty для int. Для того, чтобы избежать генерирования лишних (полностью идентичных) функций, применяют следующий прием. Шаблонный класс создают производным от класса, не являющегося шаблоном. При этом в базовый класс помещают функции, не зависящие от параметра шаблона.

Применим данный прием для нашего стека:

 

class stack5_base

{

public:

stack5_base();

bool is_empty()const;

bool is_full()const;

protected:

enum{ max_len=100};

int top;

};

 

stack5_base::stack5_base()

:top(0)

{}

 

bool stack5_base::is_empty()const {return top==0;}

 

bool stack5_base::is_full()const {return top==max_len;}

 

 

template <class T> class stack5:public stack5_base

{

public:

void push(T c);

T pop();

private:

T s[max_len];

};

 

template<class T>void stack5<T>::push(T c){

assert(top<max_len);

s[top++]=c;

}

 

template<class T>T stack5<T>::pop(){

assert(top>0);

return s[--top];

}

 

 

Для нашего случая количество сгенерированных функций уменьшается до минимально необходимого:

 

//к этому моменту сгенерировано 3 функции для stack5_base

stack5<char> sc;//генерируются 2 функции

stack5<int> si1, si2;// генерируются 2 функции

//(количество создаваемых объектов не играет роли)

stack5<char> sd;//не генерируется новых функций, так как инстанцирование stack4<char> уже было выше

 

<== предыдущая лекция | следующая лекция ==>
Виртуальные функции | Стандартная библиотека
Поделиться с друзьями:


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


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



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




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