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

Дружественные функции

Когда в проекте насчитывается большое число классов и реализована разветвленная иерархия наследования нередко возникают сложности в организации взаимодействия между конкретными классами. Например, оказывается что функциональность некоторых классов необходимо объединить, однако существующая схема наследования не позволяет этого сделать. В таких случаях на помощь приходит ключевое слово friend. Оно позволяет сделать два класса дружественными либо как минимум предоставить некоторой функции доступ к закрытым членам класса. Дружественные функции необходимы так же когда создается несколько классов с одинаковыми методами. Например: объекты класса А могут взаимодействовать с некоторым способом В с объектами класса С, а последние могут таким же способом взаимодействовать с объектами класса А. В таком случае для каждого из классов А и С необходимо описать свой метод В, однако их реализация будет одинаковой. В данной ситуации организация дружественной функции позволит избежать дублирования методов. Кроме того механизм дружественных функций позволяет скрывать структуру класса от сторонних разработчиков, которые могут привлекаться при реализации коллективного проекта. Дружественная функция определяется вне класса, но имеет доступ к закрытым членам класса.

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

Общая структура:

Class имя

{publick:

Friend прототип1;

Friend прототип2;

};

Class FuelTank

{publick:

Friend double need_to_file(FuelTank the Tank);

FuelTank (double the_capacity double the_level);

FuelTank();

Void input();

Void output();

};

Class A

{protected:

Int n;

Friend void IncN(A&a);

Publick:

A (int N);

{n=N;}

};

Void IncN(A&a);

{a.n++;}

Int main ()

{A a(10);

IncN(a);

Return 0;

}

Правило выбора- что лучше дружественная функция или просто член класса. Функцию-член класса следует использовать тогда, когда выполняемая этой функцией задача регулирует только один объект. В противном случае следует использовать дружественную функцию.

Методы одного класса можно сделать доступными в другом классе для этого его заголовок с дополнительным ключевым словом friend и префиксом, определяющим исходный класс, размещается в классе дружащим с первым.

Class

{public:

Void IncN(b&b);

};

Class B

{int n;

Public:

Friend void A::IncN (B&b);

B(int N) {n=N;}

};

Void a::IncN(b&b)

{b.n++;

};

Int main ()

{A a;

B b (10);

a.IncN (b);}

friend class имя;

class B

{int n;

Public:

Friend class A;

B(int n)

{n=N;}}

Реализовать иерархию наследования Base 1DerivedBase 2. В базовых классах определить целочисленную и вещественную матрицу соответственно. В производном классе реализовать перегруженные методы поиска сумма элементов находящихся выше главной диагонали- определить минимальный элемент среди них. Инициализацию осуществить с помощью конструктора. Просмотр текущего состояния с помощью виртуальной функции. Есть два класса. 1й определить матрицу и вывод. Во 2м для вещественного

Шаблоны функции. Шаблоны классов. Библиотека стандартных шаблонов stl

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

При реализации шаблона необходимо осуществить всего одно описание функции, а компилятор будет автоматически генерировать объектные коды функции в зависимости от типа

Описание шаблона начинается с ключевого слова- template<>

Каждому формальному параметру должно предшествовать ключевое слово class( template <class T>, template <class Element Type>

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

Template <class T>

Void printArray (t*array, const int count)

{for (int i=0;i<count;i++)

Cout<<array[i]<<” “;

Cout<<endl;

}

Main

{const{int aCount=5, bCount=7, cCount=6;

Int a[aCount]={1,2,3,4,5};

Float b[bCount]={1.1,1.2,1.3,…};

Char c[cCount]=”Hello”;

Paint Array (a, aCount);

Paint Array (b,bCount);

Paint Array (c, cCount);

Return 0;}

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

Template <class StType> class Stack

{StType stek[size];}

Int tos;

Public:

Void init() {tos=0;}

Void push (StType oh);

StType pop();

};

Template <class StType>

Void stack <StType>::push (StType ob)

{if (tos ==size)

{cout<<” stek polon”;

Return;

}

Stek[tos]=ob;

Tos++;

}

Main()

{Stack<char>

S1,S2;

S1.Init();

S1.Init();

S1.push(‘a’);

..

Steck <double>d1;

……

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

Ядро библиотеки стандартных шаблонов образует три основопологающих элемента:контейнеры, алгоритмы, этелаторы. Эти элементы тесно взаимодействуют друг с другом

Контейнер- объект, предназначенный для хранения других объектов

Vector,list…

Помимо базовых контейнеров в библиотеке так же определены ассоциативные контейнеры, позволяющие с помощью ключей получать хранящиеся в них данные

В каждом классе-контейнере определяется набор функций для работы с данным конетйнером:Вставка удаление слияние.

Существует алгоритм для реализации, поиска, замены содержимого , сортировки и т.д.

Итераторы- объекты, которые по отношению к контейнерам играют роль указателей. Они позволяют осуществлять доступ к содержимому контейнера. Имеется пять типов итераторов:

  1. Произвольного доступа- используется для считования

  2. Двунаправленный- может проходить контейнер в двух направления

  3. Однонаправленный- только в одном направлении

  4. Только для записи

  5. Только для чтения

Приемущество библиотеки:

- код библиотеки отлажен, протестирован и работоспособен

-код библиотеки эффективен с точки зрения оперативной памяти и быстродействия

-предлагается унифицированный интерфейс

-при использовании сразу позволяет приступать к проектным решениям

-код легко переносится

-не приспособленность к работе со структурными типами данных

-низкая эффективность при решении частных задач

-не совсем подходящий интерфейс для работы со строками

-сложность в управлении с памятью

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

Исключительная ситуация

Язык С++ определяет стандарт обслуживание исключительных ситуаций в рамках ооп.

Исключительная ситуация- событие, которое генерируется при возникновении ошибки или сбоя в программе. Когда программа встречает не нормальную ситуацию на которую она не расчитана можно передать управление другой части программы, можно продолжить выполнение либо завершить работу.

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

Можно определить обработчик исключения, выполняющий необходимые действия перед завершением программы

С++ позволяет обслуживать только синхронные исключения, которые возникают внутри программы. Внешнее событие исключительными ситуациями не считаются

Блок кода, который может регулировать исключения начинается ключевым словом try { } и заключается в фигурные скобки

Если исключение обнаруживается внутри блока try происходит программное прерывание и выполняется следующая последовательность действий: