Главная страница
Навигация по странице:

  • Практическая работа № 1.23. Использование порождающих шаблонов

  • Методические указания по выполнению лабораторных и практических работ по мдк


    Скачать 3.25 Mb.
    НазваниеМетодические указания по выполнению лабораторных и практических работ по мдк
    Дата23.01.2023
    Размер3.25 Mb.
    Формат файлаpdf
    Имя файла37._MU_PZ_PM.01_MDK_01.01_Razrabotka_programmnyx_moduley(1)_remo.pdf
    ТипМетодические указания
    #899980
    страница11 из 24
    1   ...   7   8   9   10   11   12   13   14   ...   24

    Практическая работа № 1.22. Использование основных шаблонов
    Цель работы: область применения основных шаблонов
    Теоретический материал
    Любая структура данных и алгоритмы имеют дополнительную ценность, если они могут хранить и работать с данными различных типов. Такая универсальность (или что одно и то же, независимость от данных) может быть достигнута в Си++ различными способами:
    · в обычном Си (см. 9.3) «переход от типа к типу» и абстрагирование от конкретного хранимого типа возможно на основе преобразования типов указателей и использования указателя void*, олицетворяющего «память вообще». Совместно с механизмом динамического связывания возможно создание алгоритмов, в которых фрагмент, ответственный за работу с конкретным типом данных, передается через указатель на функцию;

    90
    · в Си++ на основе полиморфизма (виртуальных функций) возможно создание интерфейсных классов, способных объединять единым механизмом доступа различные классы.
    Если эти классы являются «обертками» известных типов данных, то независимость от типов хранимых данных можно обеспечить ссылками на интерфейсный класс.
    Однако приведенные выше способы не обеспечивают синтаксической совместимости, т.е. они реализуются как технологические приемы, а не как элементы языка. По аналогии с переопределением операций (см. 10.3) хотелось бы использование естественного синтаксиса, где вместо int, double и т.п. фигурировало бы абстрактное обозначение типа, например, T.
    Такое средство, позволяющее создавать заготовку функции или целого класса, в котором вместо конкретного имени типа данных будет фигурировать его символическое обозначение, называется шаблоном. В первом приближении смоделировать шаблон в обычном Си можно с использованием директив препроцессора для подстановки имен – define. Обозначив именами T и N тип и размерность массива, можно создать класс с использованием этих имен везде, где это необходимо.
    //-------------------------------------------------------105-01.cpp
    // Имитация шаблона в обычном Си
    #define T int // Параметры заданы через подстановку имен
    #define N 100 // Тип элементов и размерность массива struct Array{
    T Data[N]; int k; // Текущее кол-во элементов
    Array(){ k=0; } // Конструктор - массив пуст void add(T &v){ // Добавление элемента if (k>=N) return;
    Data[k++]=v;}
    T remove(int m){ // Удаление элемента по номеру
    T foo; if (m>=k) return foo; foo=Data[m]; for(int i=m;i Data[i]=Data[i+1]; k--; return foo; }
    }; void main(){
    Array A; int B[10]={6,2,8,3,56,7,89,5,7,9}; for (int i=0;i<10;i++) A.add(B[i]); cout << A.remove(2) << endl; }
    Чтобы применить ее для другого типа данных, нужно отредактировать директиву define, заменив, например, имя int на double. Но все же основным недостатком этой модели является однократность ее использования. В Си++ текстовая заготовка класса позволяет из одного описания создавать множество классов, отличающихся типом используемых объектов и размерностями данных.
    Итак, шаблон можно определить как текстовую заготовку определения класса с
    параметром, обозначающим тип используемых внутри переменных. Сразу же, не дожидаясь описания синтаксиса, отметим особенности трансляции шаблона:
    · шаблон является описанием группы классов, отличающихся используемым типом данных;
    · при создании (определении) объекта шаблонного класса указывается тип данных, для которого он создается;
    · при определении объекта шаблонного класса конкретный тип подставляется в шаблон вместо параметра и создается текстовая заготовка экземпляра класса, которая транслируется и дает собственный оригинальный программный код;
    · и только затем происходит трансляция определения самого объекта.

    91
    Самое главное, в отличие от обычных объектов, объект шаблонного класса требует отдельного экземпляра класса для того типа, который обозначен в объекте.
    Замечание: при чтении транслятором шаблона заголовка класса и шаблонов встроенных в него функций и методов их трансляция не производится. Это происходит в другое время: при трансляции определения объекта шаблонного класса генерируется текстовая заготовка экземпляра класса. Отсюда некоторый нюансы:
    · чтобы проверить, как транслируется шаблон, нужно описать хотя бы один объект шаблонного класса;
    · весь шаблон, в том числе и шаблоны методов, следует размещать в заголовочном файле проекта;
    · на каждый тип данных – параметр шаблона создается отдельный класс и в сегменте команд размещается программный код его методов.
    Следующим примером попробуем «убить двух зайцев». Во-первых, пояснить довольно витиеватый синтаксис шаблона, а во-вторых, выделить особенности реализации структур данных и использованием технологии ООП. Основной принцип шаблона, добавление к имени класса
    «довеска» в виде имени – параметра (например, vector). Это имя обозначает внутренний тип данных, который может использоваться в любом месте класса: как указатель, ссылка, формальный параметр, результат, локальная или статическая переменная. Во всем остальном шаблон не отличается от обычного класса. Само имя шаблона (vector) теперь обозначает не один класс, а группу классов, отличающихся внутренним типом данных.
    //------------------------------------------------------105-02.cpp
    //----- Шаблон СД - динамический массив указателей template T> class vector{ int sz,n; // Размерность ДМУ и кол-ко элементов
    T **obj; // Массив указателей на параметризованные public: // объекты типа T
    T *operator[](int); // оператор [int] возвращает указатель на
    // параметризованный объект типа T operator int(); // Возвращает текущее количество указателей int append(T*); // Добавление указателя на объект типа T int index(T*); // Поиск индекса хранимого объекта vector(int); // Конструктор

    vector(){ delete []obj; } // Деструктор
    };
    Данный шаблон может использоваться для порождения объектов-векторов, каждый из которых хранит указатели объекты определенного типа. Имя класса при этом составляется из имени шаблона vector и имени типа данных (класса), который подставляется вместо параметра Т. vector a; vector b; extern class time; vector


    написать администратору сайта