Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ООП.doc
Скачиваний:
2
Добавлен:
14.07.2019
Размер:
399.36 Кб
Скачать

Void main()

{

Smart_ptr sPtr=new MyClass;

sPtr->method();

}

3)Проблема битых указателей

РЕШЕНИЕ:

Выходом из этой ситуации является реализация умного указателя с подсчетом ссылок.

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

ШАБЛОНЫ ФУНКЦИИ

Синтаксис:

Template <typename T>

Тип имя функции(параметры)

{

Тело;

}

В шаблонных функциях можно не указывать конкретный тип входных параметров , а обозначить их как подставляемые последствия .

В шаблонных функциях хотя бы один параметр должен быть типа T .

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

Описание шаблонных функций не приводит к генерации кода компилятора.

Для этого нужно указать конкретные типы данных вместо параметров шаблона.

Эти типы указываются неявно при вызове такой функции .

int n=Min(2,3)

double d=Min(2.3,4.5)

Компилятор проверяет , соответствует ли данный вызов описанию шаблона.

Если да , то генерирует код.

В данном случае компилятор сгенерирует код в функцию.

Неявных преобразований при вызове шаблонных функций не происходит.

То есть следующий вызов приведет к ошибке на этапе компиляции.

#include <iostream>

using namespace std;

template <typename T>

T Min(T x,T y)

{

return x<y?x:y;

}

Void main()

{

cout<<Min(2,4.6);

}

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

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

Template <typename T1,typename T2>

Void F(T1 x,T2 y)

{

…..

}

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

Шаблонные функции можно перегружать при этом перегрузка шаблона функции соответствует всем правилам перегрузки обычной функции.

#include <iostream>

using namespace std;

template <typename T1,typename T2>

void F(T1 x,T2 y)

{

cout<<"F(T1,T2)\n";

}

template<typename T>

void F(T x,T y)

{

cout<<"F(T,T)\n";

}

void F(int x,int y)

{

cout<<"f";

}

Void main()

{

F(2,3);

}

Возможна также одновременная перегрузка обычной функции и шаблонной.

template<typename T>

void F(T x,T y)

{

cout<<"F(T,T)\n";

}

void F(int x,int y)

{

cout<<"f";

}

В этом случае компилятор отдает предпочтение не шаблонной функции , а обычной.

То есть в случае следующего вызова F(2,3) , вызываться будет обычный вариант функции.

Иногда вместо ключевого слова typename встречается ключевое слово class .

Они абсолютно эквивалентны.

ШАБЛОНЫ КЛАССА

Template<typename>

Class имя класса

{

};

Также можно указывать несколько параметров типа <typename T1, typename T2>.

Создание объектов шаблонного класса.

Вложенное параметрическое объявление.

#include<iostream>

using namespace std;

template <typename T>

class Vector

{

...

};

Vector<Vector<int> > V;

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

С помощью ключевого слова typedef можно создать псевдоним.

Typedef Vector<int> VectorOfInt;

Каждый метод класса рассматривается как шаблонная функция.

То есть при определении тела метода за пределами класса необходимо использовать конструктор template .

#include<iostream>

using namespace std;

template <typename T>

class MyClass

{

public:

void method(const T &t);

};

template<typename T>

void MyClass<T>::method(const T& t)

{

}

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

#include<iostream>

using namespace std;

template <typename T>

class MyClass

{

public:

static int count;

};

int MyClass<int>::count=0;

int MyClass<double>::count=0;

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]