Sunteți pe pagina 1din 17

MOTENIRE MULTIPL. FUNCII PUR VIRTUALE.

RTTI

CURS 8 - PROGRAMARE II

CUPRINS
Motenire Funcii pur virtuale

Clase abstracte
Motenire multipl Clase de baz virtuale RTTI

MOTENIRE (INHERITANCE)
Definiie Motenirea este un mecanism care permite unei clase A s moteneasc atribute i metode ale unei clase B. n acest caz obiectele clasei A au acces la membrii clasei B fr a fi nevoie s le redefinim

Terminologie
Clas de baz
Clasa care este motenit

Clas derivat
O clas specializat a clasei de baz

Relaia kind-of nivel de clas


Triunghiul este un tip (kind-of) Poligon

Relaia is-a nivel de obiect


Obiectul triungiRosu este un (is-a) Poligon

MOTENIRE
Sintax
class NumeleClaseiDerivate : modificatorDeAccess NumeleClaseiDeBaz

unde
modificatorDeAcces specific tipul derivrii private (valoare implicit) protected public

Plimorfism Funcii virtuale

FUNCII PUR VIRTUALE


Definiie Sunt funcii care sunt declarate virtuale, dar nu sunt implementate n clasa de baz Trebuie s fie suprascrise n toate clasele derivate, altfel rmn pur virtuale Sintax

virtual tipDeReturn numeFunctie (listaDeParametri) = 0;

CLASE ABSTRACTE
Definiie Dac o clas conine o funcie pur virtual ea se numete abstract

class A { public: virtual void x() = 0; virtual void y() = 0; }; class B : public A { public: virtual void x(); }; class C : public B { public: virtual void y(); }; int main () { A * ap = new C; ap->x (); ap->y (); delete ap; return 0; };

Clasele abstracte nu pot fi instaniate


Clasele A i B sunt abstracte dar C poate fi instaniat Se pot utiliza pointeri la clasele virtuale Utile n cazul polimorfismului

TIPURI DE MOTENIRE N C++


Simpl

Multipl

MOTENIRE MULTIPL
Definiie Motenirea este multipl dac o clas are dou sau mai multe clase de baz Sintax class ClasaDerivat : [modificatorDeAcces] ClasaDeBaza1, [modificatorDeAcces] ClasaDeBaza2, [modificatorDeAcces] ClasaDeBazaN { }; Crete flexibilitatea ierarhilor de clase ierarhii n form de graf

MOTENIRE MULTIPL. EXEMPLU


class Mamifer { };

class AnimalInaripat { };
class Liliac: public Mamifer, protected AnimalInaripat { Liliac():AnimalInaripat(), Mamifer() { } };

MOTENIRE MULTIPL. EXEMPLU


class Animal { int varsta; };
class Mamifer: public Animal { }; class AnimalInaripat: public Animal { }; class Liliac: public Mamifer, protected AnimalInaripat { };

Liliac l; l.varsta; //eroare accesare ambigu l.Manifer::varsta=7; l.AnimalInaripat=10;

10

Problema: o instan a clasei de baz Animal este inclus de dou ori clasa derivat Liliac (una de la clasa Mamifer i una de la clasa Animalnaripat), ceea ce duce la: Pierderi la alocarea spaiului de memorie (toate atributele sunt duplicate) Ambiguiti: probleme de accesare a membrilor clasei Animal

CLASE DE BAZ VIRTUALE


Definiie: Dac o clas ca i clas de baz virtual, atunci ntr-o ierarhie de tip diamant clasa de baz este instaniat o singur dat Sintax Class clasaDerivat : [modificatorDeAcces] virtual clasaDerivata { }

11

EXEMPLU
class Animal { };
class Mamifer: public Animal { }; class AnimalInaripat: public Animal { };

Constructorul clasei de baz trebuie apelat explicit


Pai pentru iniializarea unui obiect: Apeleaz constructorul clasei de baz virtuale Apeleaz constructorii claselor de baz n ordinea declarri lor Iniializarea membrilor clasei derivate Iniializarea obiectului derivat

class Liliac: public virtual Mamifer, protected virtual AnimalInaripat { Liliac():Animal(), Manifer(), AnimalInaripat() { . } };

12

Liliac l; l.varsta;

RUNTIME TYPE INFORMATION - RTTI


E o facilitate a limbajului care permite identificarea tipului variabilelor la execuie Pentru a funciona clasele trebuie s fie polimorfice, s conin cel puin o funcie virtual Include dynamic_cast<> typeid Incluse in biblioteca typeinfo #include <typeinfo>

13

RTTI - TYPEID
Operatorul typeid este utilizat pentru a determina clasa obiectului n momentul execuiei Dac obiectul este NULL se arunc o excepie de tip std::bad_typeid Utilizare Const std::type_info & info = typeid(object)

14

RTTI - TYPEID
class Animal {

virtual ~Animal();
};

class Mamifer : public Animal { virtual ~Mamifer(); };

int main() { Animal a; Mamifer m; Animal *pa =&m; cout << typeid(a).name() <<endl; //Animal (determinat static la compilare)

cout<<typeid(m) .name() <<endl; //Mamifer (determinat static la compilare)

cout<<typeid(pa) .name() <<endl; //Animal * (determinat static la compilare)

cout<<typeid(*pa) .name() <<endl; //Mamifer (determinat dinamic la execuie deoarece este un pointer la o clas polimorfic) }

15

RTTI DYNAMIC CAST


class Animal {

virtual ~Animal();
};

class Mamifer : public Animal { virtual ~Mamifer(); };

int main() { Animal a; Mamifer m; Animal *pa =&m;

if (dynamic_cast<Mamifer*> (pa) != 0) { Mamifer *pm = (dynamic_cast<Mamifer*> (pa) ; } }

16

CURS VIITOR
abloane

17