- •1. Объектно-ориентированное программирование как методология проектирования программных средств.
- •1.2. Объект
- •Iarray a(10), b(25), c(45);
- •Int main(void)
- •2.1. Перегрузка имен функций
- •Int print(int);
- •Void print(int);
- •Void incr(int &aa)
- •Int (*matrix)[10];
- •Void main(void)
- •3.2 Объявление класса.
- •Имя_класса имя объекта;
- •Имя объекта. Имя элемента
- •Имя_объекта. Имя_метода( );
- •Имя класса *this;
- •Имя_класса (список формальных параметров)
- •Листинг 3.4
- •V_3d( double &X, double &y,double &z)
- •Void main(void)
- •Х:: х(const х&)
- •V_3d::v_3d(const v_3d& v1)
- •Void v_3d::print()
- •Сlass X
- •Void main (void)
- •4. Перегрузка операций
- •V_3d(double x1,double y1,double z1)
- •Void print();
- •Void main(void)
- •Void v_3d::print()
- •4.3.1. Использование дружественных функций при перегрузке операций
- •Void print();
- •Void main(void)
- •Void v_3d::print()
- •4.3.2.Особенности использования дружественных функций
- •Имя объекта. Имя_функции
- •Void f1( X& );
- •Void f2 ( X* );
- •Void main(void)
- •5. Производные классы
- •Int Bfunc( );
- •Int Xfunc( );
- •Int Efunc( X & x1 );
- •Istream
- •Iostream
- •Ifstream
- •С помощью манипуляторов – специальных операций, вставляемых непосредственно в поток вывода.
- •Int width( int w);
- •Int precision( int p);
- •Void main(void)
- •Void open(char* filename, int mode, int access);
- •If(!fout) {
- •7. Виртуальные функции
- •Circle a;
- •A.Build();
- •Virtual double a(double X)
- •Void main (void)
- •Void Graphics Object :: Build() { };
- •8.Шаблоны функций и классов
- •Void main(void)
- •Void Swap ( SwapType &X, SwapType &y)
- •Void main(void)
- •Int a, double b;
- •Int sloc,rloc;//начало и конец очереди
- •Void qput(t I); // помещение элемента в очередь
- •Int main(void)
- •1.Какой принцип ооп реализуется с помощью шаблонных функций и классов?
- •2.Когда целесообразно использовать шаблоны функций? Каков общий вид объявления шаблона функции?
4. Перегрузка операций
С ++ позволяет переопределять действие большинства операций так, чтобы они выполнялись над объектами созданного в программе типа (класса). Переопределение не может быть выполнено для следующих операций:
. - прямой выбор компонента структурированного объекта;
.* - обращение к компоненту через указатель на него;
:: - операция указания области видимости;
?: - условная операция;
sizeof - операция вычисления размера в байтах;
# и ## - препроцессорные операции.
Перегрузка операций выполняется с помощью операций - функций.
Синтаксис объявления прототипа операции – функции:
Тип_возвращаемого значения operator знак_операции
(список параметров операции-функции);
Если принять, что конструкция operator знак_операции есть имя некоторой функции, то прототип операции-функции подобен прототипу обычной функции языка С.
4.1. Перегрузка бинарных операций
Рассмотрим перегрузку бинарных операций на примере простой программы, показанной в листинге 4.1. В этой программе показана перегрузка операций сложения + и присваивания = в классе V_3d, содержащем координаты вектора в трехмерном пространстве.
Листинг 4.1
#include <iostream.h>
class V_3d
{
double x,y,z;
public:
//конструктор по умолчанию
V_3d(){x=0;y=0;z=0;};
//конструктор, принимающий параметры
V_3d(double x1,double y1,double z1)
{ x=x1; y=y1; z=z1; };
//вывод вектора
Void print();
// функция для перегрузки +
V_3d operator +(V_3d t);
// функция для перегрузки =
V_3d operator =(V_3d t);
};
Void main(void)
{
//создание обьектов а, b, d, s класса V_3d
V_3d a(2,3,5); //запускается конструктор с параметрами
V_3d b(5,6,5);
V_3d d,s; // запускается конструктор по умолчанию
cout << "координаты вектора a:\n";
a.print();
cout << "координаты вектора b:\n";
b.print();
d =a+b; //демонстрация перегруженной операции сложения векторов a и b
cout << "\n сумма векторов a и b :\n";
d.print();
s=a; // демонстрация перегруженной операции присваивания
cout << "\n координаты вектора s\n";
s.print();
}
//метод класса для вывода координат вектора
Void v_3d::print()
{
cout << "x= " << x << " y= " << y << " z= " << z <<"\n";
}
// определение функции - оператора +
V_3d V_3d::operator +(V_3d t)
{
V_3d c;
c.x=x+t.x; c.y=y+t.y; c.z=z+t.z;
return c;
}
// определение функции - оператора=
V_3d V_3d::operator =(V_3d t)
{
x=t.x;
y=t.y;
z=t.z;
return *this;
}
Эта программа выводит на экран следующие данные:
координаты вектора a:
x= 2 y= 3 z= 5
координаты вектора b:
x= 5 y= 6 z= 5
сумма векторов a и b :
x= 7 y= 9 z= 10
координаты вектора s
x= 2 y= 3 z= 5
Следует обратить внимание на то, что в приведенной программе обе функции-оператора имеют по одному параметру, несмотря на то, что они перегружают бинарный оператор. Это связано с тем, что при перегрузке бинарного оператора один аргумент - указатель this передается функции оператору неявно. Так, строка
d=a+b;
эквивалентна следующему явному вызову операции - функции:
d = a. operator + ( b );
this =&a, т.е. с левым операндом перегруженной бинарной операции по умолчанию связывается указатель this.
Вывод.
При перегрузке бинарной операции именно объект слева от знака операции вызывает функцию-оператор. Объект, стоящий справа от знака операции, передается функции.
4.2. Перегрузка унарных операций
Можно перегрузить унарные операции, такие, как ++ или --. При перегрузке унарных операций с помощью функций – методов класса функция-оператор не имеет параметров. Унарная операция выполняется над объектом, осуществляющим вызов функции-оператора путем неявной передачи указателя this.
Пусть имеется следующее определение класса:
class V_3d
{
int x,y ,z ;
public:
// прототип функции-оператора для перегрузки префиксной операции инкремента
V_3d operator ++ ( );
// прототип функции-оператора для перегрузки постфиксной операции инкремента
V_3d operator ++( int );
// прототипы других функций
//........
}
Где int - фиктивный параметр, указываемый для постфиксной операции, чтобы можно было отличить префиксную операцию от постфиксной, он никак не указывается при вызове.
Определение функции для перегрузки префиксной операции инкремента:
V-3d V_3d :: operator ++( )
{
x ++ ;
y ++ ;
z ++ ;
//возвращает this - указатель на объект, для которого вызвана эта функция-оператор
return *this ;
}
Если затем в программе будет создан объект класса V_3d:
V_3d c ;
То возможно следующее увеличение с:
++ c;
Определение функции для перегрузки постфиксной операции инкремента:
V_3d V_ 3d :: operator ++( int )
{
V_3d tmp ;
tmp = *this ;
x ++;
y ++;
z ++;
// Возвращает старое значение объекта.
return tmp ;
}
Замечание для постфиксной операции:
она увеличивает значение элементов-данных объекта на единицу, но возвращает старое значение объекта.
4.3 Друзья классов
В разделе 3.3 было показано, что механизм управления доступом позволяет выделить общедоступные (public), защищенные (protected) и собственные (private) элементы классов. Защищенные элементы доступны внутри класса и в производных классах. Собственные элементы локализованы в классе и недоступны извне. С помощью общедоступных элементов реализуется взаимодействие класса с любыми частями программы.
Имеется еще одна возможность расширить интерфейс класса. Ее обеспечивают дружественные функции.
Дружественной функцией класса называется функция, которая, не являясь методом класса, имеет право доступа к private и protected элементам класса.
Функция не может стать другом класса “без его согласия”. Для получения прав друга функция должна быть описана в теле класса со спецификатором friend.
