Zkladn a odvoden triedy dedinos lenov zkladnej triedy

  • Slides: 56
Download presentation
Základné a odvodené triedy dedičnosť členov základnej triedy v odvodenej triede

Základné a odvodené triedy dedičnosť členov základnej triedy v odvodenej triede

Syntax: class B : návestie_prístupu A{ … } kde B je odvodená trieda zo

Syntax: class B : návestie_prístupu A{ … } kde B je odvodená trieda zo základnej triedy A návestie_prístupu je jedno z kľúčových slov: private (je náhradný spôsob) protected public Trieda B dedí členy triedy A. Dedičnosť je mechanizmus zdieľania premenných a funkcií medzi triedami podľa špecifickej relácie medzi triedami, ktorú určuje návestie_prístupu takto:

Spôsob dedenia typu public class B: public A{ … } • všetky premenné a

Spôsob dedenia typu public class B: public A{ … } • všetky premenné a funkcie z public časti základnej triedy (nadtriedy) sa dedia do public časti odvodenej triedy (podtriedy) • všetky premenné a funkcie z protected časti nadtriedy sa dedia do protected podtriedy • premenné a funkcie z private časti nadtriedy sa nededia To znamená: • každý objekt podtriedy obsahuje vlastnú kópiu všetkých dát deklarovaných v podtriede a všetkých zdedených dát nadtriedy • každému objektu podtriedy možno zaslať správu (volať funkciu) rovnakého mena ako má funkcia v public časti podtriedy alebo zdedenej public časti nadtriedy z funkcie akejkoľvek triedy • funkcie z protected časti, ktoré zdedil z nadtriedy a tie, ktoré boli v podtriede deklarované možno volať len z funkcií ďalšej podtriedy ak je táto odvodená ako public alebo protected

 class A{ private: int x; protected: float y; public: int z; void f();

class A{ private: int x; protected: float y; public: int z; void f(); }; class B: public A{ // zdedí do protected časti y public: // a do public časti z a f() void g(); }; void B: : g(){ // x= 1; nedovolené y= 2. 5; // OK z =3; } // OK main(){ B objectb; //objectb. y=2. 5; nedovolené objektb. f(); // OK objektb. g(); } // OK

Spôsob dedenia typu protected class B: protected A{ … } • všetky premenné a

Spôsob dedenia typu protected class B: protected A{ … } • všetky premenné a funkcie z public a protected častí základnej triedy (nadtriedy) sa dedia do protected časti odvodenej triedy (podtriedy) • premenné a funkcie z private časti nadtriedy sa nededia To znamená: • každý objekt podtriedy obsahuje vlastnú kópiu všetkých dát deklarovaných v podtriede a všetkých zdedených dát nadtriedy • každému objektu podtriedy možno zaslať správu (volať funkciu) rovnakého mena ako má funkcia v public časti podtriedy z funkcie akejkoľvek triedy • funkcie z protected časti, ktoré zdedil z nadtriedy a tie, ktoré boli v podtriede deklarované možno volať len z funkcií ďalšej podtriedy ak je táto odvodená ako public alebo protected

class A{ private: int x; protected: float y; public: int z; void f(); };

class A{ private: int x; protected: float y; public: int z; void f(); }; class B: protected A{ // zdedí do protected časti y, z a f() public: void g(); }; void B: : g(){ // x= 1; nedovolené y= 2. 5; // OK z =3; } // OK main(){ B objectb; //objectb. y=2. 5; nedovolené //objektb. f(); nedovolené objektb. g(); } // OK

Spôsob dedenia typu private class B: private A{ … } • všetky premenné a

Spôsob dedenia typu private class B: private A{ … } • všetky premenné a funkcie z public a protected častí základnej triedy (nadtriedy) sa dedia do private časti odvodenej triedy (podtriedy) • premenné a funkcie z private časti nadtriedy sa nededia To znamená: • každý objekt podtriedy obsahuje vlastnú kópiu všetkých dát deklarovaných v podtriede a všetkých zdedených dát nadtriedy • funkcie zdedené z nadtriedy možno volať len v rámci funkcií podtriedy

class A{ private: int x; protected: float y; int f(); public: int z; };

class A{ private: int x; protected: float y; int f(); public: int z; }; class B: private A{ // zdedí do private časti y, z a f() public: void g(); }; void B: : g(){ // x= 1; nedovolené int a = f(); // OK z =3; } // OK main(){ B objectb; //objectb. y=2. 5; nedovolené //objektb. z = 3; nedovolene

class A{ private: int x; protected: float y; int f(); int f(double); public: int

class A{ private: int x; protected: float y; int f(); int f(double); public: int z; }; class B: private A{ // zdedí do private časti y, z a f public: void g(); A: : f; // obe f deklarujeme ako public }; void B: : g(){ } main(){ B objectb; objectb. f(); objectb. f(3. 14);

Rozdielny prístup k členom triedy môžeme zosumarizovať nasledovne: Prístup public protected private Členy tej

Rozdielny prístup k členom triedy môžeme zosumarizovať nasledovne: Prístup public protected private Členy tej istej triedy áno áno Členy odvodenej triedy áno nie Nečleny áno nie Kde nečlen reprezentuje akúkoľvek referenciu mimo triedy ako napríklad z main( ) alebo z inej triedy alebo akejkoľvek funkcie.

#include <iostream. h> class CPolygon { protected: int width, height; public: void set_values (int

#include <iostream. h> class CPolygon { protected: int width, height; public: void set_values (int a, int b) { width=a; height=b; } }; class CRectangle: public CPolygon { public: int area ( ) { return (width * height); } }; class CTriangle: public CPolygon { public: int area ( ) { return (width * height / 2); } }; int main () { CRectangle rect; CTriangle trgl; rect. set_values (4, 5); trgl. set_values (4, 5); cout << rect. area() << endl; // result 20 cout << trgl. area() << endl; // result 10 return 0; }

Čo sa dedí zo základnej triedy? V princípe sa v odvodenej triede dedí každý

Čo sa dedí zo základnej triedy? V princípe sa v odvodenej triede dedí každý člen základnej triedy okrem • Konštruktora a deštruktora • Operátora =( ) • friends • Konštruktor a deštruktor sa nededia. • Náhradný konštruktor a deštruktor základnej triedy sa vždy volajú, keď je vytvorený alebo zrušený nový objekt odvodenej triedy. • Ak základná trieda nemá náhradný konštruktor alebo ak chcete aby bol volaný prekrytý konštruktor, keď je vytvorený nový odvodený objekt, môžete to špecifikovať v každej definícii konštruktora odvodenej triedy. • Konštruktory si môžu odovzdávať parametre. derived_class_name(parameters): base_class_name(parameters) {} konštruktor odvodenej triedy konštruktor základnej triedy

#include <iostream. h> class mother { public: Výstup: mother () { cout << "mother:

#include <iostream. h> class mother { public: Výstup: mother () { cout << "mother: no parametersn"; } mother: no parameters mother (int a) { daughter: int parameter cout << "mother: int parametern"; } }; mother: int parameter class daughter : public mother { son: int parameter public: daughter (int a) { cout << "daughter: int parameternn"; } }; class son : public mother { public: son (int a) : mother (a) { cout << "son: int parameternn"; } }; int main () { daughter eva (1); son daniel(1); return 0; }

Násobné dedenie • Pri násobnom dedení má trieda viac než jednu nadtriedu. • Trieda

Násobné dedenie • Pri násobnom dedení má trieda viac než jednu nadtriedu. • Trieda dedí premenné a funkcie so všetkých svojich nadtried. • Ak dve rôzne nadtriedy obsahujú člen rovnakého mena, do podtriedy sa zdedia oba tieto členy. Jednoznačný prístup k členu sa identifikuje cez nadtriedu, z ktorej je člen. class A{ main(){ public: C c 1; int a; c 1. a =1; int x; c 1. b =2; }; // c 1. x = 3; nedovolené class B{ c 1. A: : x = 3; public: c 1. B: : x = 3. 5; int b; } float x; }; class C: public A, public B{ };

Volanie konštruktorov • Pri deklarovaní objektu sa automaticky volá konštruktor triedy a náhradné konštruktory

Volanie konštruktorov • Pri deklarovaní objektu sa automaticky volá konštruktor triedy a náhradné konštruktory jej nadtried. Konštruktor nadtriedy sa vyvolá skôr než konštruktor podtriedy. • Pri násobnom dedení sa vyvolávajú v poradí deklarácie tried. • Konštruktory si môžu navzájom odovzdávať argumenty. #include <stdio. h> class A{ public: int a; A(int arg){a = arg; } }; class B{ public: int b; B(int arg){b = arg; } }; class C: public A, public B{ public: int c; C(int arg 1, int arg 2, int arg 3): A(arg 1), B(arg 3){c = arg 2; } };

 main(){ C object(1, 2, 3); printf(“n a= %d”, object. a); // a =1

main(){ C object(1, 2, 3); printf(“n a= %d”, object. a); // a =1 printf(“n b= %d”, object. b); // b =3 printf(“n c= %d”, object. c); // c =2 } Pozn. Ak je konštruktor triedy C deklarovaný nasledovne vznikne chyba, pretože sa implicitne volajú náhradné konštruktory podtried, ktoré neexistujú. class C: public A, public B{ public: int c; C(int arg 1){c = arg 1; } };

#include<stdio. h> class Person{ char *name; public: Person(){ name = “ no name”; }

#include<stdio. h> class Person{ char *name; public: Person(){ name = “ no name”; } Person(char *n){ name = n; } void print(); }; class Teacher : public Person{ int courses; static int Max. Courses; public: Teacher(){}; Teacher(char *teach_name): Person(teach_name){courses =0; }; bool assign(); void print(); };

 class Student : public Person{ public: Student(char * student_name): Person(student_name){}; void print(); };

class Student : public Person{ public: Student(char * student_name): Person(student_name){}; void print(); }; void Person: : print(){ printf(“%s ”, name); } void Teacher: : print(){ printf(“ n teacher name is: “); Person: : print(); } void Student: : print(){ printf(“ n student name is: “); Person: : print(); }

 main(){ Teacher t 1; // konštruktor bez parametra Teacher t 2(“Peter ”); //

main(){ Teacher t 1; // konštruktor bez parametra Teacher t 2(“Peter ”); // konštruktor s parametrom Student s(“Jozef ”); t 1. print(); t 2. print(); s. print(); } Výstup: teacher name is: no name teacher name is: Peter student name is: Jozef

Sumarizácia volania konštruktorov class D: public B 1. Ak D má konštruktory a B

Sumarizácia volania konštruktorov class D: public B 1. Ak D má konštruktory a B nie potom pri tvorbe objektu triedy D príslušným konštruktorom sa automaticky volá náhradný konst. triedy B. 2. Ak D nemá konštruktor a B má potom musí mať aj náhradný konstr. 3. Ak D aj B majú konštruktory, tak D konštruktor musí explicitne volať niektorý B konštruktor pri svojej deklarácii.

Deklarácia objektov v triedach (kompozícia) versus dedičnosť class A { int i; public: A(int

Deklarácia objektov v triedach (kompozícia) versus dedičnosť class A { int i; public: A(int ii) : i(ii) {} ~A() {} void f() const {} }; class B { int i; public: B(int ii) : i(ii) {} ~B() {} void f() const {} };

class C : public B { A a; // toto je dovolene len ak

class C : public B { A a; // toto je dovolene len ak je objekt inicializovaný public: // v definícii C konštruktora C(int ii) : B(ii), a(ii) {} ~C() {} // Calls ~A() and ~B() void f() const { // Redefinition a. f(); B: : f(); } }; void main() { C c(47); //A aa; error: no appropriate default construktor available }

 Poradie volania konštruktorov a deštruktorov #include <iostream> using namespace std; #define CLASS(ID) class

Poradie volania konštruktorov a deštruktorov #include <iostream> using namespace std; #define CLASS(ID) class ID { public: ID(int) { cout << #ID " constructorn"; } ~ID() { cout << #ID " destructorn"; } }; CLASS(Base 1); CLASS(Member 2); CLASS(Member 3); CLASS(Member 4); class Derived 1 : public Base 1 { Member 1 m 1; Member 2 m 2; public: Derived 1(int) : m 2(1), m 1(2), Base 1(3) {

 cout << "Derived 1 constructorn"; } ~Derived 1() { cout << "Derived 1

cout << "Derived 1 constructorn"; } ~Derived 1() { cout << "Derived 1 destructorn"; } }; class Derived 2 : public Derived 1 { Member 3 m 3; Member 4 m 4; public: Derived 2() : m 3(1), Derived 1(2), m 4(3) { cout << "Derived 2 constructorn"; } ~Derived 2() { cout << "Derived 2 destructorn"; } }; void main() { Derived 2 d 2; }

Base 1 constructor Member 2 constructor Derived 1 constructor Member 3 constructor Member 4

Base 1 constructor Member 2 constructor Derived 1 constructor Member 3 constructor Member 4 constructor Derived 2 destructor Member 4 destructor Member 3 destructor Derived 1 destructor Member 2 destructor Member 1 destructor Base 1 destructor

Prekrytie mien členov tiedy v poddtriedach // Hiding overloaded names during inheritance #include <iostream>

Prekrytie mien členov tiedy v poddtriedach // Hiding overloaded names during inheritance #include <iostream> #include <string> using namespace std; class Base { public: int f() const { cout << "Base: : f()n"; return 1; } int f(string) const { return 1; } void g() {} }; class Derived 1 : public Base { public: void g() const {} };

class Derived 2 : public Base { public: // Redefinition: int f() const {

class Derived 2 : public Base { public: // Redefinition: int f() const { cout << "Derived 2: : f()n"; return 2; } }; class Derived 3 : public Base { public: // Change return type: void f() const { cout << "Derived 3: : f()n"; } }; class Derived 4 : public Base { public: // Change argument list: int f(int) const { cout << "Derived 4: : f()n"; return 4; } };

int main() { string s("hello"); Derived 1 d 1; int x = d 1.

int main() { string s("hello"); Derived 1 d 1; int x = d 1. f(); d 1. f(s); Derived 2 d 2; x = d 2. f(); //! d 2. f(s); // string version hidden Derived 3 d 3; //! x = d 3. f(); // return int version hidden Derived 4 d 4; //! x = d 4. f(); // f() version hidden x = d 4. f(1); }

Pravidlá: -Ak je členská funkcia v odvodenej predefinovaná všetky ostatné preťažené funkcie zo základnej

Pravidlá: -Ak je členská funkcia v odvodenej predefinovaná všetky ostatné preťažené funkcie zo základnej triedy sú prekryté. -Ak sa zmení prototyp funkcie zo základnej triedy v odvodenej triede, všetky funkcie zo základnej triedy toho istého mena sú prekryté. Úlohy 1. Ukažte že v triedach Derive 2, Derived 3, Derived 4 je žiadna funkcia f ( ) zo základnej triedy nedostupná. 2. Pridajte do základnej triedy tri preťažené funkcie h( ) a ukážte že predefinovaním jednej z ních v odvodenej triede sú ostatné prekryté.

Opakované dedenie class A public: int x class C: public A class B: public

Opakované dedenie class A public: int x class C: public A class B: public A public: int x class D: public B, public C public: B: : x C: : x

 #include<stdio. h> class A{ public: int x; }; class B: public A{ };

#include<stdio. h> class A{ public: int x; }; class B: public A{ }; class C: public A{ }; class D: public B, public C{ //vďaka viacnásobnému dedeniu }; // sa x v triede D zdvojí nain(){ { D obj_d; obj_d. B: : x =1; obj_d. C: : x =2; printf(“n obj_d. B: : x = %d”, obj_d. B: : x); // obj_d. B: : x =1 printf(“n obj_d. C: : x = %d”, obj_d. C: : x); } // obj_d. C: : x =2

Virtuálne triedy #include<stdio. h> class A{ public: int x; }; class B: virtual public

Virtuálne triedy #include<stdio. h> class A{ public: int x; }; class B: virtual public A{ }; class C: virtual public A{ }; class D: public B, public C{ }; void main(){ { D obj_d; obj_d. x = 1; printf(“n obj_d. x = %d”, obj_d. x); // obj_d. x = 1 }

 Príklad 1 (jednoduchá dedičnosť) Zadanie: Implementujte triedu vozidlo, ktorá bude obsahovať dáta: počet

Príklad 1 (jednoduchá dedičnosť) Zadanie: Implementujte triedu vozidlo, ktorá bude obsahovať dáta: počet kolies vozidla, hmotnosť vozidla a funkcie na inicializáciu dát a získanie ich hodnôt. Funkciu, ktorá vypočíta hmotnosť vozidla pripadajúcu na jedno koleso. Implementujte odvodené triedy z triedy vozidlo: auto a nákladné auto, ktoré budú obsahovať ďalšie dáta : počet osôb a hmotnosť nákladu (pre nákladné auto) a funkcie na inicializáciu a získanie hodnôt týchto údajov. Trieda nákladné auto nech obsahuje funkciu, ktorá určí podiel nákladu k celkovej hmotnosti vozidla. V hlavnom programe vytvorte objekty pre všetky triedy a vypíšte: Hmotnosť vozidla, hmotnosť vozidla pripadajúcu na jedno koleso, počet cestujúcich, počet kolies, efektivitu nákladného auta v percentách.

Príklad keď spôsob dedenia je typu public: #include <iostream. h> class vehicle { protected:

Príklad keď spôsob dedenia je typu public: #include <iostream. h> class vehicle { protected: int wheels; float weight; public: void initialize(int in_wheels, float in_weight); int get_wheels(void) {return wheels; } float get_weight(void) {return weight; } float wheel_loading(void) {return weight/wheels; } }; class car : public vehicle { int passenger_load; public: void initialize(int in_wheels, float in_weight, int people = 4); int passengers(void) {return passenger_load; } };

class truck : public vehicle { int passenger_load; float load; public: void init_truck(int how_many

class truck : public vehicle { int passenger_load; float load; public: void init_truck(int how_many = 2, float max_load = 24000. 0); float efficiency(void); int passengers(void) {return passenger_load; } }; void vehicle: : initialize(int in_wheels, float in_weight){ wheels = in_wheels; weight = in_weight; } void car: : initialize(int in_wheels, float in_weight, int people){ passenger_load = people; wheels = in_wheels; weight = in_weight; } void truck: : init_truck(int how_many, float max_load){ passenger_load = how_many; load = max_load; }

float truck: : efficiency(void){ return load / (load + weight); } int main(){ vehicle

float truck: : efficiency(void){ return load / (load + weight); } int main(){ vehicle bicykel; bicykel. initialize(2, 12. 5); cout << "Bicykel ma " << bicykel. get_wheels() << " kolesa. n"; cout << "Vaha bicykla na jedno koleso je " <<bicykel. wheel_loading() << " kg. n"; cout << "Vaha bicykla je " << bicykel. get_weight() << " kg. nn"; car sedan; sedan. initialize(4, 3500. 0, 5); cout << "Sedan vezie " << sedan. passengers() << " cestujucich. n"; cout << "Vaha sedanu je " << sedan. get_weight() << " kg. n"; cout << "Vaha sedanu na jedno koleso je " << sedan. wheel_loading() << " kg. nn"; truck kamion; kamion. initialize(18, 12500. 0); kamion. init_truck(1, 33675. 0); cout << "Vaha kamiona je " << kamion. get_weight() << " kg. n"; cout << "Efektivita kamiona je " << 100. 0 * kamion. efficiency() << " percenta. n"; return 0; }

Výstup: Bicykel má 2 kolesa. Vaha bicykla na jedno koleso je 6. 25 kg.

Výstup: Bicykel má 2 kolesa. Vaha bicykla na jedno koleso je 6. 25 kg. Vaha bicykla je 12. 5 kg. Sedan vezie 5 cestujúcich. Váha sedanu je 3500 kg. Vaha sedanu na jedno koleso je 875 kg. Vaha kamiona je 12 500 kg. Efektivita kamiona je 72. 929 percenta.

Príklad keď sú dáta v triede vehicle deklarované ako private: #include <iostream. h> class

Príklad keď sú dáta v triede vehicle deklarované ako private: #include <iostream. h> class vehicle { private: int wheels; float weight; public: void initialize(int in_wheels, float in_weight); int get_wheels(void) {return wheels; } float get_weight(void) {return weight; } float wheel_loading(void) {return weight/wheels; } }; class car : public vehicle { int passenger_load; public: void initialize(int in_wheels, float in_weight, int people = 4); int passengers(void) {return passenger_load; } };

class truck : public vehicle { int passenger_load; float load; public: void init_truck(int how_many

class truck : public vehicle { int passenger_load; float load; public: void init_truck(int how_many = 2, float max_load = 24000. 0); float efficiency(void); int passengers(void) {return passenger_load; } }; void vehicle: : initialize(int in_wheels, float in_weight){ wheels = in_wheels; weight = in_weight; } void car: : initialize(int in_wheels, float in_weight, int people){ passenger_load = people; //wheels = in_wheels; sú nedostupné (nededia sa) //weight = in_weight; vehicle: : initialize(in_wheels, in_weight); // je nutné ich inicializovať pomocou funkcie } void truck: : init_truck(int how_many, float max_load){ passenger_load = how_many; load = max_load; }

float truck: : efficiency(void){ // return load / (load + weight); weight je nedostupné

float truck: : efficiency(void){ // return load / (load + weight); weight je nedostupné return load / (load + get_weight( )); // weight sa získa pomocou funkcie } int main(){ vehicle bicykel; bicykel. initialize(2, 12. 5); cout << "Bicykel ma " << bicykel. get_wheels() << " kolesa. n"; cout << "Vaha bicykla na jednu pneumatiku je " <<bicykel. wheel_loading() << " kg. n"; cout << "Vaha bicykla je " << bicykel. get_weight() << " kg. nn"; car sedan; sedan. initialize(4, 3500. 0, 5); cout << "Sedan vezie " << sedan. passengers() << " cestujucich. n"; cout << "Vaha sedanu je " << sedan. get_weight() << " kg. n"; cout << "Vaha sedanu na jednu pneumatiku je " << sedan. wheel_loading() << " kg. nn"; truck kamion; kamion. initialize(18, 12500. 0); kamion. init_truck(1, 33675. 0); cout << "Vaha kamiona je " << kamion. get_weight() << " kg. n"; cout << "Efektivita kamiona je " << 100. 0 * kamion. efficiency() << " percenta. n"; return 0; } Výstup je rovnaký

Príklad keď spôsob dedenia je typu private: #include <iostream. h> class vehicle { protected:

Príklad keď spôsob dedenia je typu private: #include <iostream. h> class vehicle { protected: int wheels; float weight; public: void initialize(int in_wheels, float in_weight); int get_wheels(void) {return wheels; } float get_weight(void) {return weight; } float wheel_loading(void) {return weight/wheels; } }; class car : private vehicle { int passenger_load; public: void initialize(int in_wheels, float in_weight, int people = 4); int passengers(void) {return passenger_load; } };

class truck : private vehicle { int passenger_load; float load; public: void init_truck(int how_many

class truck : private vehicle { int passenger_load; float load; public: void init_truck(int how_many = 2, float max_load = 24000. 0); float efficiency(void); int passengers(void) {return passenger_load; } }; void vehicle: : initialize(int in_wheels, float in_weight){ wheels = in_wheels; weight = in_weight; } void car: : initialize(int in_wheels, float in_weight, int people){ passenger_load = people; wheels = in_wheels; weight = in_weight; } void truck: : init_truck(int how_many, float max_load){ passenger_load = how_many; load = max_load; }

float truck: : efficiency(void){ return load / (load + weight); } int main(){ vehicle

float truck: : efficiency(void){ return load / (load + weight); } int main(){ vehicle bicykel; bicykel. initialize(2, 12. 5); cout << "Bicykel ma " << bicykel. get_wheels() << " kolesa. n"; cout << "Vaha bicykla na jednu pneumatiku je " <<bicykel. wheel_loading() << " kg. n"; cout << "Vaha bicykla je " << bicykel. get_weight() << " kg. nn"; car sedan; sedan. initialize(4, 3500. 0, 5); cout << "Sedan vezie " << sedan. passengers() << " cestujucich. n"; //cout << "Vaha sedanu je " << sedan. get_weight() << " kg. n"; //cout << "Vaha sedanu na jednu pneumatiku je " << sedan. wheel_loading() << " kg. nn"; truck kamion; // kamion. initialize(18, 12500. 0); kamion. init_truck(1, 33675. 0); // cout << "Vaha kamiona je " << kamion. get_weight() << " kg. n"; // cout << "Efektivita kamiona je " << 100. 0 * kamion. efficiency() << " percenta. n"; return 0; } // funkcie z public časti triedy vehicle sú v tejto funkcii pre objekty z odvodených tried //nedostupné

Výstup: Bicykel má 2 kolesa. Vaha bicykla na jednu pneumatiku je 6. 25 kg.

Výstup: Bicykel má 2 kolesa. Vaha bicykla na jednu pneumatiku je 6. 25 kg. Vaha bicykla je 12. 5 kg.

 Príklad 2 (viacnásobná dedičnosť) Zadanie: Implementujte dve základné triedy nákladné auto a vodič

Príklad 2 (viacnásobná dedičnosť) Zadanie: Implementujte dve základné triedy nákladné auto a vodič a z týchto tried odvodenú triedu riadené auto. Základná trieda auta nech obsahuje dáta: hmotnosť nákladu, hmotnosť vozidla, spotreba paliva a funkciu na ich inicializáciu. Ďalej, funkciu na výpočet efektívnosti vozidla. Základná trieda vodič nech obsahuje hodinovú mzdu vodiča, funkciu na jej inicializáciu a funkciu na výpočet nákladov na mzdu vodiča pripadajúcich na jednotku vzdialenosti (km, míľa). Odvodená trieda riadené auto nech obsahuje inicializačnú funkciu všetkých zdedených údajov. Všetky triedy nech obsahujú funkciu na výpočet celodenných nákladov potrebných na prevádzku. V hlavnom programe vytvorte objekt odvodenej triedy a vypíšte potrebné informácie.

#include <iostream. h> class truck { protected: float load; float weight; float consumption; public:

#include <iostream. h> class truck { protected: float load; float weight; float consumption; public: void initialize(float in_l, float in_w, float in_mpg) { load = in_l; weight = in_w; consumption = in_mpg; }; float efficiency(void) { return(load / (load + weight)); }; }; class driver { protected: float hourly_pay; public: void initialize(float pay) {hourly_pay = pay; }; float cost_per_mile(void) {return(hourly_pay / 55. 0); } ; };

class driven_truck : public truck, public driver { public: void initialize_all(float in_l, float in_w,

class driven_truck : public truck, public driver { public: void initialize_all(float in_l, float in_w, float in_mpg, float pay) { load = in_l; weight = in_w; consumption = in_mpg; hourly_pay = pay; }; float cost_per_full_day(float cost_of_gas) { return(8. 0 * hourly_pay + 8. 0 * cost_of_gas * 55. 0 / consumption); }; }; main() { driven_truck my_ford; my_ford. initialize_all(20000. 0, 12000. 0, 5. 2, 12. 50); cout << "Efektívnosť Forda je " <<my_ford. efficiency() << "n"; cout << "Náklady na vodiča na míľu sú " << my_ford. cost_per_mile() << "n"; cout << "Celkové náklady na denné prevádzkovanie Forda sú " << my_ford. cost_per_full_day(1. 129) << "n"; return 0; }

Výstup: Efektívnosť Forda je 0. 625 Náklady na vodiča na míľu sú 0. 227273

Výstup: Efektívnosť Forda je 0. 625 Náklady na vodiča na míľu sú 0. 227273 Celkové náklady na denné prevádzkovanie Forda sú 195. 530762

 Pr. Meno funkcie je vo všetkých triedach (základných a odvodených) rovnaké #include <iostream.

Pr. Meno funkcie je vo všetkých triedach (základných a odvodených) rovnaké #include <iostream. h> class truck { protected: float load; float weight; float consumption; public: void initialize(float in_l, float in_w, float in_mpg) { load = in_l; weight = in_w; consumption = in_mpg; }; float efficiency(void) { return(load / (load + weight)); }; float cost_per_full_day(float cost_of_gas){ return(8. 0 * cost_of_gas * 55. 0 / consumption); }; }; class driver { protected: float hourly_pay; public: void initialize(float pay) {hourly_pay = pay; }; float cost_per_mile(void) {return(hourly_pay / 55. 0); } ; float cost_per_full_day() {return(8. 0 * hourly_pay); }; };

class driven_truck : public truck, public driver { public: void initialize_all(float in_l, float in_w,

class driven_truck : public truck, public driver { public: void initialize_all(float in_l, float in_w, float in_mpg, float pay) { truck: : initialize(in_l, in_w, in_mpg); driver: : initialize(pay); }; float cost_per_full_day(float cost_of_gas) { return(8. 0 * hourly_pay + 8. 0 * cost_of_gas * 55. 0 / consumption); }; }; main() { driven_truck my_ford; my_ford. initialize_all(20000. 0, 12000. 0, 5. 2, 12. 50); cout << "Efektívnosť Forda je " <<my_ford. efficiency() << "n"; cout << "Náklady na vodiča na míľu sú " << my_ford. cost_per_mile() << "n"; cout << "Denné náklady na prevádzku Forda sú" << my_ford. truck: : cost_per_full_day(1. 129) << "n"; cout << "Denné náklady na vodiča sú" << my_ford. driver: : cost_per_full_day() <<"n"; cout << "Celkové náklady na denné prevádzkovanie Forda sú " << my_ford. driven_truck: : cost_per_full_day(1. 129) << "n"; return 0; }

Výstup: Efektívnosť Forda je 0. 625 Náklady na vodiča na míľu sú 0. 227273

Výstup: Efektívnosť Forda je 0. 625 Náklady na vodiča na míľu sú 0. 227273 Denné náklady na prevádzku Forda sú 95. 530769 Denné náklady na vodiča sú 100. 0 Celkové náklady na denné prevádzkovanie Forda sú 195. 530762

Pr. Odvodená trieda zdedí premennú rovnakého mena z viacej tried class truck{}; // ostáva

Pr. Odvodená trieda zdedí premennú rovnakého mena z viacej tried class truck{}; // ostáva nezmenená class driver { protected: float hourly_pay; float weight; // premenná má to isté meno ako v triede truck public: void initialize(float pay, float in_w) { hourly_pay = pay; weight = in_w; }; float cost_per_mile(void) {return(hourly_pay / 55. 0); } ; float drivers_weight(void) {return(weight); }; }; class driven_truck : public truck, public driver { public: void initialize_all(float in_l, float in_w, float in_mpg, float pay, float in_dw) { truck: : initialize(in_l, in_w, in_mpg); driver: : initialize(pay, in_dw); }; float cost_per_full_day(float cost_of_gas) { return(8. 0 * hourly_pay + 8. 0 * cost_of_gas * 55. 0 / consumption); }; float total_weight(void) {return(truck: : weight + driver: : weight); }; };

main() { driven_truck my_ford; my_ford. initialize_all(20000. 0, 12000. 0, 5. 2, 12. 50, 90.

main() { driven_truck my_ford; my_ford. initialize_all(20000. 0, 12000. 0, 5. 2, 12. 50, 90. 0); cout << "Efektívnosť Forda je " << my_ford. efficiency() << "n"; cout << "Náklady na vodiča na míľu sú " << my_ford. cost_per_mile() << "n"; cout << "Celkové náklady na denné prevádzkovanie Forda sú " << my_ford. cost_per_full_day(1. 129) << "n"; cout << "Celková hmotnosť je " << my_ford. total_weight() << "n"; return 0; } Výstup: Efektívnosť Forda je 0. 625 Náklady na vodiča na míľu sú 0. 227273 Celkové náklady na denné prevádzkovanie Forda sú 195. 530762 Celková hmotnosť je 12090

Cvičenia 1. Vysvetlite chybu class B{ public: B(int a){x = a; } private: int

Cvičenia 1. Vysvetlite chybu class B{ public: B(int a){x = a; } private: int x; }; class D : public B { public: D(){…} … };

2. Čo je výstup class B{ public: B( ){cout<< “B construktor”<<endl; } ~B( )

2. Čo je výstup class B{ public: B( ){cout<< “B construktor”<<endl; } ~B( ) {cout<< “B destruktor”<<endl; } }; class D 1: public B{ public: D 1( ): B( ) {cout<< “D 1 construktor”<<endl; } ~D 1( ){cout<< “D 1 destruktor”<<endl; } }; class D 2: public D 1{ public: D 2( ): D 1(){cout<< “D 2 construktor”<<endl; } ~D 2( ){cout<< “D 2 destruktor”<<endl; } }; void main( ){ B b; D 1 d 1; D 2 d 2; }

3. Je nutné, aby základná trieda mala konštruktor? 4. Predpokladajme, že základná trieda má

3. Je nutné, aby základná trieda mala konštruktor? 4. Predpokladajme, že základná trieda má dva konštruktory náhradný a konštruktor s argumentom. Odvodená trieda má jeden konštruktor s jedným argumentom. Musí konštruktor odvodenej triedy volať obidva konštruktory základnej triedy? 5. Musí deštruktor odvodenej triedy volať deštruktor základnej triedy ak tento existuje? 6. Rozšírte program z príkladu 1 o ďalšiu úroveň podtriedy a napíšte konštruktor, ktorý inicializuje lokálnu premennú triedy B. 7. Vytvorte dve triedy A a B s defaultovými konštruktormi, ktoré sa pri volaní ohlásia výpisom. Odvoďte novú triedu C z A a vytvorte v nej členský objekt triedy B (deklaráciou) ale nevy tvorte konštruktor triedy C. Čo sa stane po vytvorení objektu triedy C v hlavnej funkcii?