- •Введение в понятие класса
- •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)
Перегрузка функций и операций
В языке С++ возможна перегрузка функций-элементов, конструкторов и операций.
Функции-элементы класса могут быть перегружены; две или несколько функций могут иметь одно и то же имя, при условии, что списки их аргументов не совпадают. Компилятор следит за тем, чтобы вызывалась нужная функция, проверяя соответствие аргументов. Довольно обычной является перегрузка конструкторов.
Конструкторы играют специфическую роль в языке С++. Перегрузка конструкторов класса осуществляется просто объявлением конструкторов с различным набором параметров.
Пример
#include <iostream.h>
#include <stdio.h>
#include <time.h>
class timer {
int seconds;
public:
timer(void) {seconds=5;} // конструктор по умолчанию
timer(char *t) { seconds=atoi(t);} // время задается строкой
timer(int t) {seconds=t;} // Задание секунд целым числом
timer (int min, int sec) { seconds=60*min+sec;} // задание минутами и секундами
void run(void);
};
void timer::run(void)
{
clock_t t1,t2;
t1=t2=clock()/CLK_TCK;
while(seconds) {
if (t1/CLK_TCK+1<=(t2=clock())/CLK_tck)
{
seconds--;
t1=t2;
}
}
сout<<”\a”; // сигнал
}
void main(void)
{
timer a(10), b(“20”), c(1,10),d;
сout<<”Подождите 10 секунд…\n”;
a.run(); // 10 секунд
сout<<”Подождите 20 секунд…\n”;
b.run(); // 20 секунд
сout<<”Подождите 1 минуту 10 секунд…\n”;
с.run(); // 1 минута 10 секунд
сout<<”Подождите 5 секунд…\n”;
d.run(); // 5 секунд
}
Язык С++ позволяет определять и применять к вашему классу обозначения операций. Эта особенность, называемая перегрузкой операций, дает классу возможность вести себя подобно встроенному типу данных. Можно перегружать для классов любые из следующих операций
+ |
- |
* |
. |
% |
^ |
& |
| |
! |
= |
< |
> |
+= |
-= |
/= |
%= |
^= |
&= |
|= |
<< |
>> |
>>= |
<<= |
= = |
!= |
<= |
>= |
&& |
|| |
++ |
-- |
[] |
Чтобы перегрузить операцию, нужно определить, что эта значит относительно класса, к которому она будет применяться. Для этого создается специальная функция-операция (operator function), которая определяет действие этой операции.
Основная форма функции-операции, являющейся функцией-членом класса
Тип имя-класса::operator #(список аргументов)
{
// операторы, определяющие действие
}
тип – тип возвращаемого значения;
# - конкретный знак операции.
Часто возвращаемое значение того же типа, что и класс, хотя возможен и другой тип значения. Функция операции может быть или членом класса или дружественной функцией (есть отличия).
Пример. Перегрузка операций + и = относительно класса vector, который определяет трехмерный вектор в эвклидовом пространстве. Операция сложения векторов выполняется как сложение соответствующих координат
#include <iostream.h>
class vector {
int x,y,z; // координаты
public:
vector operator +(vector t);
vector operator =(vector t);
void show(void);
void assign(int mx, int my, int mz);
};
// перегрузка операции +
vector vector::operator + (vector t)
{
vector temp;
temp.x=x+t.x;
temp.y=y+t.y;
temp.z=z+t.z;
return temp;
}
// перегрузка операции =
vector vector::operator = (vector t)
{
vector temp;
x=t.x;
y=t.y;
z=t.z;
return *this;
}
void vector::show(void)
{
cout<<x<<” “<<y<<” “<<z<<endl;
}
void vector::assign(int mx, int my, int mz)
{
x=mx; y=my; z=mz;
}
void main(void)
{
vector a,b,c;
a.assign(1,2,3);
b.assign(4,5,6);
a.show();
b.show();
c=a+b; // использование перегруженной операции +
c.show();
c= a + b + c;
c.show();
c = b = a;
c.show();
b.show(); }
Как видно, каждая функция-операция имеет только один параметр, в то время как сами функции определяют бинарные операции. Другой аргумент неявно передается с использованием this-указателя. Строка temp.x=x+t.x; аналогична строке temp.x=this->x+t.x;, т.е. х ссылается на this->x. Здесь this ассоциируется с объектом, предшествующим знаку операции. Объект справа от знака операции передается как параметр функции. Если используются функции-члены, то не нужны параметры для унарных операций и требуется лишь один параметр для бинарных операций. Во всех случаях объект, активизирующий операцию, передается в функцию-операцию неявно через указатель this.
Можно также перегрузить операции ++ и --. Это унарные операции. Добавим в пример следующие конструкции:
class vector {
int x,y,z; // координаты
public:
vector operator +(vector t);
vector operator =(vector t);
vector operator++(void); // префиксная операция
vector operator++(int); // постфиксная операция
void show(void);
void assign(int mx, int my, int mz);
};
vector vector::operator ++(void)
{ // префиксная
x++; y++; z++;
return *this;
}
vector vector::operator ++(int)
{ // постфиксная
vector tmp;
tmp=*this;
x++; y++; z++;
return tmp;
}
void main(void)
{
vector a,b,c;
a.assign(1,2,3);
b.assign(4,5,6);
a.show();
b.show();
c=a+b; // использование перегруженной операции +
c.show();
c= a + b + c;
c.show();
c = b = a;
c.show();
b.show();
с++; // использование постфиксной операции
c.show();
++с; // использование префиксной операции
c.show();
}
Данная реализация постфиксной операции содержит важное качество постфиксной операции ++, а именно она увеличивает значение координат вектора на единицу, но возвращает старое значение объекта.