
- •Введение в понятие класса
- •Void queue::init(void)
- •Перегруженные функции
- •Int sqr_it(int I); // Прототипы
- •Перегрузка операций.
- •Наследование
- •Конструкторы и деструкторы
- •Int sloc,rloc;
- •Void qput(int); // Прототип
- •Int qget(void); // Прототип
- •Конструктор с параметрами
- •Конструктор копирования
- •Void input();
- •Void output();
- •Void ThreeAngle::input()
- •Void ThreeAngle::output()
- •Void main(void)
- •Дружественные функции
- •Замечание
- •Дружественные классы
- •Аргументы функций, задаваемые по умолчанию
- •Void main(void)
- •Void stringxy(char *str, int X, int y)
- •Структуры и классы
- •Объединения и классы
- •Void main()
- •Наследование классов
- •Конструкторы с параметрами при наследовании
- •Множественное наследование
- •Перегрузка функций и операций
- •Ключевое слово this
- •Перегрузка операций ввода/вывода. Инсерторы и экстракторы
- •Void main(void)
- •Vector a(1,2,3),b(4,5,6);
- •Void main(void)
- •Vector a(1,2,3),b(4,5,6);
- •Void main(void)
- •Vector a(1,2,3);
- •Дружественные функции-операции
- •Void main(void)
- •Void swap1(int *I, int *j)
- •Void swap(int a, int b)
- •Void swap1(int *I, int *j)
- •Void swap2(int &a, int &b)
- •Использование ссылочных переменных для перегрузки унарных операций
- •Перегрузка операции индексации [ ]
- •Использование виртуальных функций
- •Указатели на производные типы
- •Виртуальные функции
- •Замечания к использованию виртуальных функций
- •Пример использования виртуальных функций
- •Чистые виртуальные функции и абстрактные типы
- •Производные классы и их конструкторы и деструкторы
- •Void main()
- •Конструкторы и деструкторы при множественном наследовании
- •Void main()
- •Виртуальные базовые классы.
- •Операции динамического выделения памяти new и delete
- •Void main(void)
- •Void main(void)
- •Виртуальные деструкторы
- •Void main(void)
- •Void main(void)
- •Шаблоны классов и функций
- •Шаблоны функций
- •Void main(void)
- •Void main(void)
- •Шаблоны классов
- •Int sloc, rloc;
- •Void qput(t I);
- •Void main(void)
- •Статические члены класса
- •Локальные классы
- •Void f(void);
- •Void main(void)
- •Void f(void)
- •Вложенные классы
- •Void main(void)
Void main(void)
{
CL a;
cout<<a.c<<” “;
a=a+10;
cout<<a.c<<” “;
a=15+a;
cout<<a.c<<”\n“;
}
Прежде чем перейти к перегрузке унарных операций с помощью дружественных функций, необходимо познакомиться с еще одной особенностью языка С++, а именно ссылочными переменными (references).
Ссылки
По умолчанию С и С++ передают аргументы функции, используя вызов по значению (call by value). Передача параметра по значению влечет за собой создание копии аргумента. Эта копия используется функцией и может быть изменена, но исходное значение аргумента при этом не меняется. Когда необходимо, чтобы функция изменяла значение аргумента, то параметры объявляются как указатели с использованием символа *.
Пример:
Void swap1(int *I, int *j)
{
int tmp=*i;
*i=*j;
*j=tmp;
}
Вызов swap1(&i,&j); При таком способе меняются местами значения переменных.
При вызове этой функции использовались указатели на аргументы. Это способ вызова по ссылке, используемый в языке С. Однако в языке С++ имеется возможность сообщить компилятору о необходимости генерировать вызов по ссылке другим способом. Это достигается использованием перед именем параметра в объявлении функции символа &. Такой параметр называется ссылочным параметром (reference parameter). Рассмотрим пример определения функции, имеющей один ссылочные параметры.
void swap2(int &a, int &b)
{
int tmp=a;
a=b;
b=tmp;
}
С вызовом swap2(a,b);
Общий пример:
#include <iostream.h>
void swap (int a, int b); // неработающая версия
void swap1(int *a, int *b); // использование указателей
void swap2(int &a, int &b); // использование ссылок
main(void)
{
int a=7,b=9;
cout<<”до вызова функции swap()\n”;
cout<<”a=”<<a<<” b=”<<b<<”\n”;
swap(a,b);
cout<<”После вызова функции swap()\n”;
cout<<”a=”<<a<<” b=”<<b<<”\n”;
swap1(&a,&b);
cout<<”После вызова функции swap1()\n”;
cout<<”a=”<<a<<” b=”<<b<<”\n”;
swap2(a,b);
cout<<”После вызова функции swap2()\n”;
cout<<”a=”<<a<<” b=”<<b<<”\n”;
return 0;
}
Void swap(int a, int b)
{
int tmp=a;
a=b;
b=tmp;
}
Void swap1(int *I, int *j)
{
int tmp=*i;
*i=*j;
*j=tmp;
}
Void swap2(int &a, int &b)
{
int tmp=a;
a=b;
b=tmp;
}
Использование ссылочных переменных для перегрузки унарных операций
Операция ++ в программе не была перегружена дружественной функцией, так как перегрузка требовала использования ссылки. Теперь перегрузку можно осуществить следующим образом:
friend vector operator++(vector &op1)
{
op1.x++;
op1.y++;
op1.z++;
return op1;
}
Теперь в main() можно использовать d++, где d – объект типа vector. При использовании ссылочного параметра компилятор знает заранее, что он должен передать адрес при вызове функции.
Перегрузка операции индексации [ ]
Операция индексации рассматривается как бинарная операция, где первый операнд – объект класса, а второй операнд – целочисленный индекс. Перегрузка операции индексации позволяет работать с элементами объекта vector как с элементами массива. Для использования операции индексации класс vector построим следующим образом.
#include <iostream.h>
class vector {
int v[3]; // координаты
public:
vector(int a=0, int b=0, int c=0){ v[0]=a; v[1]=b; v[2]=c;}
vector operator +(vector t);
vector operator =(vector t);
int& operator[] (int i);
void show(void);
// перегрузка операции +
vector vector::operator + (vector t)
{
vector temp;
for (int i=0;i<3;i ++)
temp.v[i]=t.v[i]+v[i];
return temp;
}
// перегрузка операции =
vector vector::operator = (vector t)
{
vector temp;
for (int i=0;i<3;i ++)
v[i]=t.v[i];
return *this;
}
// перегрузка операции []
int& vector::operator[] (int I)
{
return v[i];
}
void vector::show(void)
{
for (int i=0;i<3;i ++)
cout<<v[i]<<” “;
cout<<endl;
}
void main(void)
{
vector v1(1,2,3),v2(10,11,12), v3;
v3 = v1 + v2;
for (int i=0;i<3;i ++)
cout<<v3[i]<<” “;
cout<<endl;
v3.show();
// перегрузка операции [] с возвращением ссылки позволяет написать
v1[0]=100; v1[1]=201; v1[2]=302;
v1.show();
}