Лекции по обектно-ориентирано програмиране


Предефиниране на функции елементи от базовия клас в производния клас



страница15/16
Дата25.07.2016
Размер0.95 Mb.
#6568
ТипЛекции
1   ...   8   9   10   11   12   13   14   15   16

28. Предефиниране на функции елементи от базовия клас в производния клас.

производният клас може да предефинира функции елементи на базовия клас; ако в производния клас се опише функция елемент със същото име както функция елемент на базовия клас, то версията на тази функция в производния клас предефинира версията от базовия клас; за да се направи достъпна версията на функцията от базовия клас за производния клас, трябва да се използва бинарната операция за разрешаване на област на действие ‘::’;


Примерна програма:

#include

#include

#include

#include

class Employee {

public:

Employee (const char *, const char *);



void print () const;

~Employee ();

private:

char *firstName, *lastName;

} ;

Employee::Employee (const char *first, const char *last)



{ firstName = new char [ strlen (first) + 1];

assert (firstName != NULL);

strcpy (firstName, first);

lastName = new char [ strlen (last) + 1];

assert (lastName != NULL);

strcpy (lastName, last);

}

void Employee::print () const



{ cout << firstName << ‘ ‘ << lastName; }

Employee::~Employee ()

{ delete []firstName; delete []lastName; }
class HourlyWorker : public Employee

{ public:

HourlyWorker (const char *, const char *, float, float);

float getPay () const;

void print () const;

private:


float wage, hours;

} ;


HourlyWorker::HourlyWorker (const char *first, const char *last,

float initHours, float initWage) : Employee (first, last)

{ hours = initHours; wage = initWage; }

float HourlyWorker::getPay () const

{ return wage*hours; }

void HourlyWorker::print () const

{ Employee::print ();

cout << “ - $” << setiosflags (ios::fixed | ios::showpoint)



<< setprecision (2) << getPay () << endl;

}

void main ()



{ HourlyWorker h ( “Иван”, “Петров”, 40, 7.50);

h.print ();

}
функцията елемент print на класа HourlyWorker е пример за предефинирана функция елемент на базов клас в производен клас;

функции елементи от базовия клас често се предефинират в производния клас за изпълняване на някои по-специфични действия; тези предефинирани функции понякога извикват версията на функцията от базовия клас, за да изпълнят част от новата задача;



29. Използване на конструктори и деструктори в производни класове.

при създаване на обект от производен клас, конструкторът на производния клас винаги отначало извиква конструкторите на базовите класове, след това конструкторите на обектите елементи на производния клас и най-накрая се изпълнява самият конструктор на производния клас;

при унищожаване на обект от производен клас, деструкторите се извикват в ред, обратен на този в който са извикани съответните конструктори;

редът, в който се извикват конструкторите на обектите елементи, е редът, в който те са описани в дефиницията на класа; на този ред не влияе последователността, в която са изброени инициализаторите на обектите елементи в заглавието на конструктора;

редът, в който се извикват конструкторите на базовите класове, е редът, в който тези класове са посочени в заглавието на производния клас; на този ред не влияе последователността, в която са посочени конструкторите на базовите класове в описанието на конструктора на производния клас;

в конструктора на производния клас при явно извикване на конструкторите на базовия клас се използва списък от инициализатори на елементи; ако такъв списък не се опише, конструкторът на производния клас неявно ще извика конструкторите с аргументи по премълчаване на базовия клас; ако производният клас няма конструктор, то вграденият конструктор по премълчаване на производния клас ще извика конструкторите по премълчаване на базовия клас;


Примерна програма:
#include

class Point {

public:

Point (float = 0.0, float = 0.0);



~Point ();

protected:

float x, y;

} ;


Point::Point (float a, float b)

{ x = a; y = b;

cout << “Конструктор на Point: “ << ‘[‘ << x << “, “ << y << ‘]’ << endl;

}

Point::~Point ()



{ cout << “Деструктор на Point: “ << ‘[‘ << x << “, “ << y << ‘]’ << endl; }

class Circle : public Point

{ public:

Circle (float = 0.0, float = 0.0, float = 0.0);

~Circle ();

private:


float radius;

} ;


Circle::Circle (float r, float a, float b) : Point (a, b)

{ radius = r;

cout << “Конструктор на Circle: “ << radius << ‘[‘ << x << “, “ << y << ‘]’

<< endl;

}

Circle::~Circle ()



{ cout << “Деструктор на Circle: “ << radius << ‘[‘ << x << “, “ << y << ‘]’

<< endl;

}

void main ()



{

{ Point p (1.1, 2.2); }

Circle circle1 (4.5, 7.2, 2.9);

Circle circle2 (10, 5, 5);

}
резултат от изпълнението:
Конструктор на Point: [1.1, 2.2]

Деструктор на Point: [1.1, 2.2]

Конструктор на Point: [7.2, 2.9]

Конструктор на Circle: 4.5[7.2, 2.9]

Конструктор на Point: [5, 5]

Конструктор на Circle: 10[5, 5]

Деструктор на Circle: 10[5, 5]

Деструктор на Point: [5, 5]

Деструктор на Circle: 4.5[7.2, 2.9]

Деструктор на Point: [7.2, 2.9]


конструкторите и операцията за присвояване не се наследяват от производните класове; въпреки това, конструкторите и операцията за присвояване на производните класове могат да извикват конструкторите и операцията за присвояване на базовите класове;

30. Множествено наследяване.

при простото наследяване, всеки производен клас се поражда само от един базов клас; йерархията при простото наследяване може да се изобрази чрез дърво; при множественото наследяване, производният клас се поражда от два или повече базови класа; йерархията при множественото наследяване може да се изобрази чрез ориентиран ацикличен граф; йерархията на наследяването може да бъде с произволна дълбочина в границите на физическите ограничения за конкретната система;


Примерна програма:
#include

class Base1 {

public:

Base1 (int x) { value = x; }



int getData () const { return value; }

protected:

int value;

} ;


class Base2 {

public:


Base2 (char c) { letter = c; }

char getData() const { return letter;}

protected:

char letter;

} ;

class Derived: public Base1, public Base2



{ friend ostream& operator<< (ostream &, const Derived &);

public:


Derived (int, char, float);

float getReal () const;

private:

float real;

} ;

Derived::Derived ( int i, char c, float f) : Base1 (i), Base2 (c)



{ real = f; }

float Derived::getReal () const

{ return real; }

ostream &operator<< (ostream &output, const Derived &d)

{ output << “Цяло: “ << d.value << endl

<< “Символ: “ << d.letter << endl

<< “Реално: “ << d.real << endl;

return output;

}

void main ()



{ Base1 b1(10), *base1Ptr; Base2 b2 (‘z’), *base2Ptr;

Derived d (7, ‘A’, 3.5);

cout << b1.getData() << endl

<< b2.getData() << endl

<< d << endl;

cout << d.Base1::getData() << endl



<< d.Base2::getData() << endl

<< d.getReal() << endl;

base1Ptr = &d;

cout << base1Ptr -> getData() << endl;

base2Ptr = &d;

cout << base2Ptr -> getData() << endl;

}
в примера класът Derived се поражда от два класа Base1 и Base2 чрез множествено наследяване – то се указва с ‘:’ след името на класа и следващ списък на базовите класове, разделени със запетаи;

конструкторът на Derived извиква конструкторите на всеки от своите базови класове Base1 и Base2 с използване на списък от инициализатори на елементи; както знаем, конструкторите на базовите класове се извикват в този ред, в който те са описани в заглавието на производния клас Derived;

тъй като функцията operator<< е приятелска за производния клас Derived, тя има пряк достъп до защитените елементи value и letter от базовите класове Base1 и Base2;

по-нататък възниква проблем - един обект от клас Derived съдържа функции с еднакви имена; това са наследените функции getData от базовите класове Base1 и Base2; този проблем се решава лесно с помощта на бинарната операция за разрешаване на област на действие;




Сподели с приятели:
1   ...   8   9   10   11   12   13   14   15   16




©obuch.info 2024
отнасят до администрацията

    Начална страница