Visual C + +: Мислимо шаблонно, Комерція, Різне, статті

Новачкові, освоювали небудь мову програмування, раз у раз трапляються такі поняття як «процедурне програмування», «модульне програмування», «об’єктно-орієнтоване програмування»; поступово він починає проникати в їх суть. Термін «узагальнене програмування» куди більш рідкісний. Що ж це таке, які можливості воно нам надає? Спробуємо відповісти на це питання.

Концепція узагальненого програмування передбачає використання типів даних як параметри. При розробці алгоритму, який може працювати з безліччю типів і структур даних, використовується якийсь абстрактний тип, який згодом параметрізіруєтся. Такий підхід забезпечує простий спосіб введення різного роду загальних концепцій і позбавляє нас від написання вручну спеціалізованого коду. У мові програмування С + + узагальнене програмування реалізується за допомогою шаблонів. Шаблони бувають двох типів: шаблони класів і шаблони функцій. Розглянемо кожен із них. Шаблон класу має наступний вид:

template class ім’я_класу {/ * Тіло класу * /};
 
Префікс template вказує, що оголошений шаблон і що аргумент Т буде використаний в оголошенні як тип. Зверніть увагу, що Т – не обов’язково ім’я класу, він може бути будь-яким типом даних. Ім’я шаблону класу, за яким слід тип, поміщений в кутові дужки, є ім’ям класу, і його можна використовувати так само, як і імена інших класів. Об’єкт даного класу створюється наступним чином:

Ім’я_класу <Тип> ім’я_змінної;
 
Члени шаблону класу оголошуються і визначаються точно також, як і для звичайного класу. Якщо в шаблоні необхідно параметризованих кілька типів, то їх потрібно перерахувати через кому в кутових дужках, наприклад, template .

Шаблони функцій мають велике значення при написанні узагальнених алгоритмів. В якості альтернативи можна використовувати перевантаження імен функцій, але при цьому необхідно написати реалізацію функції для кожного типу даних, що призведе до додаткових накладних витрат. Шаблон функції визначається так:

template Тіп_результата Ім’я_функції (Тіпи_аргументов)
{
/ * Тіло функції * /
}
 
Аргумент Т може використовуватися як для оголошення локальних змінних, так і для визначення типів аргументів і типу результату. Виклик шаблону функції відбувається так само, як і виклик звичайних функцій, тільки після імені функції в кутових дужках необхідно вказати тип. Якщо можливо вивести тип аргументу шаблону функції за типами аргументів при її виклику, то дужки можна опустити.

Ну що ж, перейдемо від теорії до практики. Всі ми часто використовуємо при написанні програм масиви. Бувають випадки, коли розмір масиву заздалегідь невідомий. Тому доводиться виділяти під нього максимально необхідний обсяг пам’яті, що призводить до неефективного її використання. Напишемо шаблон класу, який буде об’єктної реалізацією одновимірного масиву, але, на відміну від простого масиву, його розмір можна буде збільшувати. Запускаємо Microsoft Visual C + + 6.0 і створюємо новий проект. Для цього вибираємо меню File> New. У діалоговому вікні New на закладці Projects в списку типів проекту вибираємо Win32 Console Application (рис. 1). Також зазначаємо ім’я та розміщення проекту. Нехай наш проект буде мати назву masiv. Натискаємо OK і в наступному діалоговому вікні вибираємо перемикач A simple application (рис. 2). Після цього натискаємо Finish і чекаємо, поки майстер закінчить створення нового проекту. Після цього відкриваємо файл masiv.cpp і замінюємо його вміст наступним кодом:

#include “stdafx.h”
#include <iostream.h>
template<class T>class Array
{
int n; / / Кількість елементів масиву
T * a; / / Внутрішня реалізація масиву
public:
  Array() 
  {
    n=5;   
    a=new T[n];
    for(int i=0; i<n; i++)
      a[i]=0;
  }
  Array(int n1)
  {
    n=index;
    a=new T[n];
    for(int i=0; i<n; i++)
      a[i]=0;
  }
  Array(const Array& mas)
  {
    n=mas.n;
    a=new T[n];
    for(int i=0; i<n; i++)
      a[i]=mas.a[i];
  }
  ~Array()
  {
    delete[] a; 
  }
/ / Перенавантажуємо оператор присвоювання
  Array& operator=(const Array& mas)
  {
    if (this!=&mas)
    {
      delete[] a;
      n=mas.n;
      a=new T[n];
      for(int i=0; i<n; i++)
        a[i]=mas.a[i];
    }
    return *this;
  }
/ / Повертаємо значення елемента масиву за заданим індексом
  T& operator[](int index){return a[index];}
/ / Повертаємо кількість елементів масиву
  int length(){return n;}
/ / Збільшуємо розмір масиву на значення col
  void resize(unsigned int col)
  {
    T* tmp = new T[n+col];
    for(int i=0; i<n; i++)
      tmp[i]=a[i];
    delete[] a;
    n+=col;
    a=tmp;
  }
};
int main(int argc, char* argv[])
{
/ / Тестуємо наш клас
  Array<int> m;
  m[0]=5;
  Array<double> m1;
  m1[0]=2.7+3.3;
  m1[1]=1.5+m1[0]*2;
  m1[3]=m1[0]+m1[1];
  cout<<m[0]<<endl;
  cout<<m1[0]<<endl;
  cout<<m1[1]<<endl;
  cout<<m1[3]<<endl;
  cout<<m1.length()<<endl;
  m1.resize(2);
  cout<<m1.length()<<endl;
  return 0;
}

     

В шаблоні класу Array ми описали всі види конструкторів і деструктор. Також перевантажили оператори присвоювання та індексу за допомогою функцій operator = і operator []. Зверніть увагу, що результатом функції operator [] є посилання на елемент масиву. Це зроблено для того, щоб можна було як отримати значення елемента масиву, так і привласнити йому якесь значення. Розмір масиву можна тільки збільшити. Для цього аргумент функції resize має тип unsigned int. Так як наш шаблон класу має невеликий розмір, реалізації всіх функцій описані усередині шаблону. Але функції можна реалізувати і поза класом. Наприклад, реалізація функції length поза шаблону класу буде виглядати так:

template<class T> int Array<T>::length()
{
  return n;
}
 
Як бачите, тип Т використовується в шаблоні класу нарівні з іншими типами даних. В процесі компіляції згенерує клас або класи, де Т буде замінений компілятором на конкретний тип. Версія шаблону для конкретного аргументу шаблону називається спеціалізацією, а сам процес генерації – інстанцірованіем шаблону. Таким чином, вся чорнова робота з написання спеціалізованого коду буде покладено на компілятор. Тепер наш масив цілком придатний для використання при написанні інших програм. При необхідності можна буде розширити його функціональність. Залишилося тільки протестувати наш шаблон. Натискаємо Ctrl + F5 і дивимося результати тесту, код якого описаний у функції main (рис. 3).


Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*