- •Обзорные лекции по курсу
- •1.Концепции и методология объектно-ориентированного программирования
- •2.Классы. Конструкторы и деструкторы
- •Void set_a(int num);
- •Void AnyClass::get_a()
- •Int AnyClass::set_a(int num)
- •Конструкторы и деструкторы. Список инициализации элементов
- •Void Show();
- •Int main()
- •Void Show();
- •Int main()
- •Статические члены класса
- •3. Простое и множественное наследование
- •Int GetX(){return X;}
- •Int GetY(){return у;}
- •Int GetX(){return X;}
- •Int GetY(){return y;}
- •Void ShowX(){cout « GetX() « ' ' ;}
- •Void ShowY(){cout « GetY()« ' ';}
- •OutCoord(int _x, int _y): Coord(_x, _y){}
- •Int GetX() {return X;}
- •Int GetY(){return y;}
- •Void ShowX(){cout « GetX() « ' ';}
- •Void ShowY(){cout « GetY()« ' ';}
- •Void ShowX(){cout « Coord::GetX() « ' ';}
- •PrintMsg(int _x, int _y, char* msg): Coord(_x, _y), SaveMsg(msg){}
- •Void set_a(int num);
- •Void AnyClass::get_a()
- •Int AnyClass::set_a(int num)
- •Void Show();
- •Int main()
- •Int GetX() {return X;}
- •PrintMsg(int _x, int _y, char* msg): Coord(_x, _y), SaveMsg(msg){}
- •Упражнения для самопроверки
Int GetX() {return X;}
Int GetY(){return y;}
void SetX(int _x){x = _x;}
void SetY(int _y){y = _y;}
};
class OutCoord: public Coord
{
public:
OutCoord(int _x, int _y): Coord(_x,_y){}
int GetX(){return ++x;}
int GetY(){return ++y;}
Void ShowX(){cout « GetX() « ' ';}
Void ShowY(){cout « GetY()« ' ';}
};
main()
{
OutCoord* ptr;
ptr = new OutCoord(10,20); //Создание объекта в куче
ptr->ShowX() ;
ptr->ShowY();
cout « "\n";
delete ptr; //Удаление объекта из кучи
return 0;
}
В этом случае функции-члены ShowY () и ShowX () объекта ptr используют для получения значений данных-членов переопределенные варианты функций базового класса GetX () и GetY (). В результате на экран программа выведет инкрементированные значения заданных координат.
Иногда возникает необходимость вызвать функцию-член базового класса, а не ее переопределенный вариант, это можно сделать с помощью операции разрешения области видимости, применяемой в форме:
<имя_класса>: :<имя_члена>
Это дает возможность компилятору "видеть" за пределами текущей области видимости. Особенно часто это приходится делать при переопределении функций-членов. Переопределяемая функция-член может вызывать соответствующую функцию-член базового класса, а затем выполнять некоторую дополнительную работу (или наоборот). Например, в предыдущем примере можно было переопределить функцию GetX () следующим образом:
int
OutCoord::GetX()
{
int z;
//Вызов переопределенной функции
z = Coord::GetX();
return ++z;
}
Точно так же можно было бы использовать операцию разрешения области видимости для квалификации вызываемой перегруженной функции в ShowX ():
Void ShowX(){cout « Coord::GetX() « ' ';}
Производный класс сам может служить в качестве базового класса для некоторого другого класса. При этом исходный базовый класс называется косвенным базовым классом для второго базового класса.
Множественное наследование
Если у производного класса имеется несколько базовых классов, то говорят о множественном наследовании. Множественное наследование позволяет сочетать в одном производном классе свойства и поведение нескольких классов.
Следующий пример демонстрирует множественное наследование.
#include <iostream.h>
#include <conio.h>
#include <string.h>
class Coord
{
int x, y;
public:
Coord(int _x, int _y){x = _x; у = _y;}
int GetX() {return x;}
int GetY() {return y;}
void SetX(int _x){x = _x;}
void SetY(int _y){y = _y;}
};
class SaveMsg
{
char Message[80];
public:
SaveMsg(char* msg){SetMsg(msg);}
void SetMsg(char* msg) {strcpy(Message, msg);}
void ShowMsg() {cout « Message;}
};
class PrintMsg: public Coord, public SaveMsg
{
public:
PrintMsg(int _x, int _y, char* msg): Coord(_x, _y), SaveMsg(msg){}
void Show();
};
void
PrintMsg::Show()
{
gotoxy(GetX() , GetY());
ShowMsg();
}
main()
{
PrintMsg * ptr;
ptr =new PrintMsg(10, 5, "Множественное ");
ptr->Show() ;
ptr->SetX(25);
ptr->SetY(5);
ptr->SetMsg("наследование");
ptr->Show();
delete ptr;
return 0;
}
В этом примере класс Coord отвечает за хранение и установку значений координат на экране, класс SaveMsg хранит и устанавливает сообщение, а класс PrintMsg, являющийся производным от них, выводит это сообщение на экран в заданных координатах. Этот пример демонстрирует также, как осуществляется передача параметров конструкторам базовых классов. При множественном наследовании, как и при простом, конструкторы базовых классов вызываются компилятором до вызова конструктора производного класса. Единственная возможность передать им аргументы — использовать список инициализации элементов. Причем порядок объявления базовых классов при наследовании определяет и порядок вызова их конструкторов, которому должен соответствовать порядок следования конструкторов базовых классов в списке инициализации. В данном случае класс PrintMsg содержит такое объявление о наследовании:
class PrintMsg: public Coord, public SaveMsg
Этому объявлению соответствует следующий конструктор: