Dziedziczenie wielobazowe (wielodziedziczenie)

0x08 graphic

class Punkt

{

int x,y;

public:

Punkt(...) {...}

~Punkt(...) {...}

drukuj() {...}

};

class Kolor

{

short kolor;

public:

Kolor(...) {...}

~Kolor(...) {...}

drukuj() {...}

};

0x08 graphic

0x08 graphic
0x08 graphic
0x08 graphic

class Punktkol : public Punkt, public Kolor

{

public:

Punktkol(...) {...}

~Punktkol(...) {...}

drukuj() {...}

};

#include <iostream>

class Punkt

{

int x, y ;

public :

Punkt (int xx, int yy)

{ x=xx ; y=yy ; }

~Punkt () { }

void drukuj ()

{ cout << "Wspolrzedne: " << x << " " << y << endl ; }

};

class Kolor

{

short Kolor ;

public :

Kolor (int kk)

{ Kolor = kk ;}

~Kolor () { }

void drukuj ()

{ cout << "Kolor : " << Kolor << "\n" ; }

} ;

class PunktKolor : public Punkt, public Kolor

{

public :

PunktKolor (int, int, int) ;

~PunktKolor () { }

// w obydwu klasach bazowych zmienne są prywatne,

// dostęp do nich zapewniają funkcje

void drukuj ()

{ Punkt::drukuj () ; Kolor::drukuj () ; }

} ;

PunktKolor::PunktKolor(int xx, int yy, int kk) : Punkt (xx, yy),Kolor (kk)

{ }

main()

{

PunktKolor p(2,4,0) ;

cout << "------------\n" ;

p.drukuj () ; // funkcja drukuj() z Punktkol

cout << "------------\n" ;

p.Punkt::drukuj () ; // funkcja drukuj() z Punkt

cout << "------------\n" ;

p.Kolor::drukuj () ; // funkcja drukuj() z Kolor

cout << "------------\n" ;

}

0x08 graphic

// klasa Lista: obsługuje listę,

// obiekty listy są wskazywane

struct element {

element *nastepny;

// void * - lista może obsługiwać

// zbiór obiektów różnego typu

void *zawartosc;

};

class Lista {

element * glowa;

public:

Lista();

~Lista();

// zwróć adres kolejnego obiektu

void* kolejny();

// dodaj kolejny obiekt

void dodaj(void *);

...

};

// klasa Punkt jest przykładem

// klasy obiektów przechowywanych

// za pomocą listy

class Punkt

{

int x,y;

public:

Punkt();

void drukuj();

};

void Punkt drukuj ()

{ cout << x << " " << y << endl;

}

0x08 graphic
class Lista_punktow: public Lista, public Punkt {

public:

Lista_punktow() {}

void drukuj();

};

void Lista_punktow::drukuj ()

{ ...

while ( ! koniec() ) {

Punkt * wsk = (Punkt *) kolejny() ;

wsk->drukuj () ;

}

}

Typ void

void* wsk; wskaźnik void* można bowiem jawnie przekształcić do innego typu.

#include <iostream>

// klasa Lista

struct element // element listy

{ element * nastepny ; // wskaźnik na następny element listy

0x08 graphic
void * zawartosc ; // wskaźnik na przechowywany obiekt

} ;

class Lista

{ element * glowa ; // wskaźnik na pierwszy element listy

element * biezacy ; // wskaźnik na bieżący element listy

public :

Lista ()

{ glowa = NULL ; biezacy = glowa ; }

~Lista () ;

0x08 graphic
void dodaj (void *) ; // dodaj element na początek listy

void pierwszy () // ustaw się na pierwszym elemencie listy

{ biezacy = glowa ;

0x08 graphic
}

void * kolejny () // zwróć adres bieżącego obiektu,

// ustaw się na kolejnym elemencie listy

{ void * wsk_el = NULL ;

if (biezacy != NULL){ wsk_el = biezacy -> zawartosc ;

biezacy = biezacy -> nastepny ;

}

return wsk_el ;

}

int koniec () { return (biezacy == NULL) ; }

} ;

Lista::~Lista ()

{ element * nast ;

biezacy = glowa ;

while (biezacy != NULL )

{ nast = biezacy->nastepny ; delete biezacy ; biezacy = nast ; }

}

0x08 graphic

void Lista::dodaj (void * nowy)

{ element * wsk_el = new element ;

wsk_el->nastepny = glowa ; wsk_el->zawartosc = nowy ;

glowa = wsk_el ;

}

// klasa Punkt

class Punkt

{

int x, y ;

public :

Punkt (int xx=0, int yy=0) { x=xx ; y=yy ; }

void drukuj () { cout << "Wspolrzedne : " << x << " " << y << endl ; }

} ;

// klasa Lista_punktow

class Lista_punktow : public Lista, public Punkt

{ public :

Lista_punktow () {}

void drukuj () ;

} ;

0x08 graphic
void Lista_punktow::drukuj ()

{ pierwszy() ;

while ( ! koniec() )

0x08 graphic
{

Punkt * wsk = (Punkt *) kolejny() ;

wsk->drukuj () ;

}

}

int main()

{

Lista_punktow l ;

Punkt a(1,2), b(4,5), c(6,0) ;

l.dodaj (&a) ; l.drukuj () ; cout << "---------\n" ;

l.dodaj (&b) ; l.drukuj () ; cout << "---------\n" ;

l.dodaj (&c) ; l.drukuj () ; cout << "---------\n" ;

}

0x08 graphic

0x08 graphic
struct element

{ element * nastepny ;

void * zawartosc ;

} ;

class Lista

{ element * glowa ;

public :

Lista ();

~Lista () ;

void * kolejny ();

void dodaj (void *) ;

void drukuj_Lista () ;

} ;

void Lista::drukuj_Lista ()

{

Bazowa * wsk ;

pierwszy() ;

while ( ! koniec() )

{

wsk = (Bazowa *) kolejny() ;

wsk->drukuj () ;

}

}

class Bazowa

{ public :

virtual void drukuj () = 0 ;

} ;

class Punkt : public Bazowa

{ int x, y ;

public :

Punkt ();

void drukuj ()

{ cout << x << " " << y << endl; }

...

};

class Zespolone : public Bazowa

{ double rzeczywista, urojona ;

public :

Zespolone ();

void drukuj()

{ cout << rzeczywista << " + "

<< urojona << "i\n" ;

}

...

} ;

#include <iostream>

class Bazowa

{

0x08 graphic
public :

virtual void drukuj () = 0 ;

} ;

struct element

{ element * nastepny ;

void * zawartosc ;

} ;

class Lista

{ element * glowa ;

element * biezacy ;

public :

Lista () { glowa = NULL ; biezacy = glowa ; }

~Lista () ;

void dodaj (void *) ;

void pierwszy () { biezacy = glowa ; }

void * kolejny ()

{ void * wsk_nast = NULL ;

if (biezacy != NULL){ wsk_nast = biezacy -> zawartosc ;

biezacy = biezacy -> nastepny ;

}

return wsk_nast ;

}

void drukuj_Lista () ;

int koniec () { return (biezacy == NULL) ; }

} ;

Lista::~Lista ()

{ element * nast ;

biezacy = glowa ;

while (biezacy != NULL )

{ nast = biezacy->nastepny ; delete biezacy ; biezacy = nast ; }

}

void Lista::dodaj (void * nowy)

{ element * wsk = new element ;

wsk->nastepny = glowa ;

wsk->zawartosc = nowy ;

glowa = wsk ;

}

void Lista::drukuj_Lista ()

0x08 graphic
{ Bazowa * wsk ;

pierwszy() ;

while ( ! koniec() )

0x08 graphic
{ wsk = (Bazowa *) kolejny() ;

wsk->drukuj () ;

}

}

class Punkt : public Bazowa

{ int x, y ;

public :

Punkt (int xx=0, int yy=0) { x=xx ; y=yy ; }

void drukuj ()

{ cout << "Wspolrzedne punktu : " << x << " " << y << endl ; }

} ;

class Zespolone : public Bazowa

{ double rzeczywista, urojona ;

public :

Zespolone (double r=0, double i=0) { rzeczywista=r ; urojona=i ; }

void drukuj ()

{ cout << "Zespolone : " << rzeczywista << " + " << urojona << "i\n" ; }

} ;

main()

{ Lista l ;

Punkt a(1,2), b(4,5) ;

Zespolone x(3.4,5.1), y(1.8,3.5) ;

l.dodaj (&a) ; l.drukuj_Lista () ;

cout << "---------\n" ;

l.dodaj (&x) ; l.drukuj_Lista () ;

cout << "---------\n" ;

l.dodaj (&y) ; l.drukuj_Lista () ;

cout << "---------\n" ;

l.dodaj (&b) ; l.drukuj_Lista () ;

cout << "---------\n" ;

}

1

8

Punkt

Kolor

Punkt kolorowy

Tutaj jawnie jest dokonana konwersja wskaźnika void* do wskaźnika Punkt *

klasa Punkt

klasa Lista

głowa

punkt 2

punkt 1

punkt 3

głowa

obiekt 1

obiekt 2

obiekt 3

Lista klas bazowych

Funkcja drukuj() klasy Punkt

Konwersja wskaźnika void * do wskaźnika Punkt *

Klasa Bazowa „zastępuje” klasy poszczególnych obiektów

Funkcja drukuj() jest wirtualna,

zostanie tutaj wywołana funkcja drukuj() właściwego obiektu