Добавил:
владимир Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ООП_С++ / Лабы / ООП_Лабораторная работа №5.doc
Скачиваний:
0
Добавлен:
17.08.2025
Размер:
261.12 Кб
Скачать

Передача параметров в базовый класс

До тех пор, пока конструкторы не имеют аргументов, от производно­го класса не требуется каких-либо специальных действий. Однако, когда базовый класс имеет конструктор с аргументами, производные классы должны явным образом обрабатывать эту ситу­ацию путем передачи базовому классу необходимых аргументов.

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

Пример3: Студенты и их оценки (упрощенный вариант).

Доступ к итоговым баллам по предмету

#include "stdafx.h"

#include <iostream>

#include <string>

using namespace std;

// базовый класс

class student

{ string name; // private-данные

protected: string adr; // protected-данные

// public область- до конца класса все элементы открытые

public: int age; // public-данные

student (string cname, string cadr, int cage): name(cname),adr(cadr),age(cage) {}

student (student& s)

{ name=s.name;

adr=s.adr;

age=s.age;

}

// методы доступа для пользователей класса

string getname() // передача указателя

{return name;} // во внешнюю

string getadr() // программу

{return adr;}

// внешний ввод данных

// запись текста в закрытую область

void setname (string n) {name=n;}

void setadr (string n) {adr=n;}

}; //--- конец определения базового класса

//--------------- Класс-наследник, тип наследования public

class itog: public student

{ int test; // private-данные

protected: int lab;

public: int bdz; //public область

itog(student& cstud, int ctest, int clab, int cbdz)

:student(cstud)

{test=ctest;

lab=clab;

bdz=cbdz;

}

itog(string cname, string cadr, int cage, int ctest, int clab, int cbdz)

: student(cname,cadr,cage)

{test=ctest;

lab=clab;

bdz=cbdz;

}

//--- методы для внешнего доступа

// передача данных во внешнюю программу (чтение)

int get_lab()

{return lab;}

int get_test ()

{return test;}

// Derived-метод

void set_itog(char* n, char* a, int g, int t, int l, int b)

{ getname()=n;

adr=a;

age=g;

test=t;

lab=l;

bdz=b;

}

}; //-- конец определения произв. класса

int _tmain(int argc, _TCHAR* argv[])

{student S("Иванов","Общежитие МИЭТ",20); // Base - пользователь

itog T1(S,3,4,5); // Derived - пользователь

S.age=27;

T1.set_itog("Петров","Зеленоград", 22, 25, 30, 12);

cout<< "Итоги для: "<<T1.getname() ;

cout<<", адрес " <<T1.getadr();

cout<<", возраст: "<<T1.age;

// доступ к своим данным

cout<<"\nБаллы : \n по тестам "<<T1.get_test();

cout<<"\n по лабам "<<T1.get_lab();

cout<< "\n по БДЗ "<<T1.bdz;

cout<< endl;

system ("pause");

return 0;

}

Пример 4: 3-х ступенчатая иерархия наследования: точка->окружность->цилиндр

Класс «окружность» - производный от класса «точка», а класс «цилиндр» - производный от класса «окружность».

Для класса «цилиндр»:

«окружность» - это непосредственный базовый

«точка» - косвенный базовый класс.

#include "stdafx.h"

#include <iostream>

using namespace std;

//-------------определение класса point (точка)

class point

{ int x; // private-данные

int y;

public:

//конструктор

point(int xx=0,int yy=0):x(xx),y(yy){}

//конструктор копирования

point(point& p){x=p.x;y=p.y;}

// работа с закрытыми данными

// запись данных

void putx_y (int xx,int yy){x=xx; y=yy;}

// чтение данных

int getx(){return x;}

int gety(){return y;}

// печать данных (точка)

void show ()

{ cout<<x<<'\t'<<y<<endl;}

};//------- конец определения класса point

//----- определение класса circ (окружность)

class circ: public point

{// private-данные

int rad; // радиус

double p_circ; // длина окружности

double q_circ; //площадь круга

public:

// конструктор задает окружность по координатам и радиусу

// вызывает конструктор базового класса

circ ( int x=0,int y=0, int r=3): point(x,y)

{rad=r;

p_circ=2*3.14*rad;

q_circ=3.14*rad*rad;

}

// конструктор задает окружность по точке и радиусу

// вызывает конструктор копирования базового класса

circ ( point p, int r): point(p)

{ rad=r;

p_circ=2*3.14*rad;

q_circ=3.14*rad*rad;

}

// конструктор копирования

// Так как поля x,y – закрытые – доступ через методы класса

circ ( circ& c): point(c.getx(),c.gety())

{ rad=c.rad;

p_circ=2*3.14*rad;

q_circ=3.14*rad*rad;

}

// работа с закрытыми данными

int get_rad (){return rad;}

// печать данных (окружность)

void show ()

{ cout<<"circle : ";

cout<<"x="<<getx()<<'\t'<<"y="<<gety()<<'\t'<<"r="<<rad;

cout<<'\t'<<"p="<<p_circ<<'\t'<<"q="<<q_circ<<endl;}

};//----- конец определения класса circ

//----- определение класса cylinder (цилиндр)

class cylinder: public circ // класс circ является базовым для cylinder

{ // private-данные

int h; // высота

double s_Cyl; // площадь боковой поверхности

double v_Cyl; //объем цилиндра

public:

// конструкторы

// задать цилиндр по координатам, радиусу и высоте, данные передаются конструктору базового класса

cylinder ( int x=0,int y=0, int r=3,int hh=5): circ(x,y,r)

{h=hh;

s_Cyl=2*3.14*get_rad()*h;

v_Cyl=3.14*get_rad()*get_rad()*h;

}

// задать цилиндр по окружности и высоте , данные передаются конструктору копирования

cylinder ( circ c, int hh=5): circ(c)

{h=hh;

//закрытое поле rad в базовом классе circ – доступ через метод

s_Cyl=2*3.14*get_rad();

v_Cyl=3.14*get_rad()*get_rad();

}

// печать данных (цилиндр)

void show ()

{/* ко всем закрытым полям класса point и класса circ доступ через методы, к полям класса cylinder (как закрытым, так и открытым) доступ прямой*/

cout<<endl<<"----Cylinder----"<<endl;

cout<<"x="<<getx()<<'\t'<<"y="<<gety();

cout<<'\t'<<"r="<<get_rad()<<'\t'<<"h="<<h;

cout<<'\t'<<"s="<<s_Cyl<<'\t'<<"v="<<v_Cyl<<endl;}

};//----- конец определения класса Cylinder

int _tmain(int argc, _TCHAR* argv[])

{point p1(1,2),p2; // создание 2-х точек

cout<<"-------p1-----"<<endl;

p1.show(); // печать информации о точке

cout<<"-------p2-----"<<endl;

p2.show();

p2.putx_y(2,3); // запись информации в объект p2

p2.show();

circ s1(1,2,3),s2(p2,6); // создать 2 объекта типа "окружность"

cout<<"-------s1-----"<<endl;

s1.show(); // печать информации об окружности

cout<<"-------s2-----"<<endl;

s2.show();

cylinder c1,c2(0,10,15,50),c3(s2,9); // создать 3 объекта типа "цилиндр"

c1.show(); c2.show(); c3.show();

system("pause");

return 0;

}

Обратим внимание на функции show() в различных классах. Эти функции обеспечивают полиморфизм раннего связывания (на этапе трансляции программы).

Одинаковые по внешнему виду вызовы активизируют разные функции, но тип объекта, вызывающего функцию определяет из какого класса эта функция :

p2.show(); // печать точки

s1.show(); // печать окружности

c3.show(); // печать цилиндра

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