Documente Academic
Documente Profesional
Documente Cultură
RAPORT
Lucrarea de laborator nr.5
Tema: Mostenirea multipla
Varianta 10
A efectuat:
st. gr. SI-141
E. Cucu
A verificat:
Lector universitar
M. Balan
Chiinu 2015
Scopul lucrrii:
Indicatii teoretice:
Motenirea multipl, reprezint prin sine motenirea de la dou sau mai multe clase.
Pentru a nelege pentru ce ne trebuie motenirea multipl trebuie s ne amintim, c
motenirea simpl nu rezolv toate problemele, aa cum cteodat ne oblig s alegem dintre
dou clase de baz potrivite.
Este interesant prerea lui Buch referitor la acest mecanism: Motenirea multipl
este ca o paraut: de regul, nu ne trebuie, dar, cnd ntmpltor o s ne trebuiasc, o s ne
par ru dac nu o s fie la ndemn .
n aa fel, acest mecanism este foarte necesar. Dar, el nu se folosete n toate limbajele,
dar este realizat n C++. Ca de exemplu: trebuie de descris clasa Fereastra cu buton i
denumire, ns clasele Fereastra, Fereastra cu buton, Fereastra cu denumire, sunt deja create
i reprezint prin sine urmtoarea ierarhie.
Window
Button
Window
Titled
Window
Button
Titled
Window
Figura 1 Motenirea de la dou clase rude.
Ambele clase pot fi utilizate ca clas de baz, pentru noua, nc ne creat. n lipsa
motenirii multiple ar fi fost necesar de ales i de completat funcionalitile care nu ajung.
Nu numai c utilizatorul este pus n faa unei alegeri, completarea codului, prin sine
contrazice principiului de minimizare a codului i utilizarea lui repetat.
Motenirea multipl are loc i n via:
- Practicantul este student i colaborator vremelnic. El primete not pentru lucrul
su, ca student, i n acelai moment, execut funciile de colaborator, i posibil
primete i salariu.
Definirea
Motenirea multipl se declar n felul urmtor:
class Student{
public:
int mark;
...
};
class Worker{
public:
int salary;
};
class Practicant: public Student, public Worker{
};
void PutMark(Student& s, int mark){
s.mark = mark;
}
void PutSalary(Worker& w, int salary){
w. salary = salary;
}
void main(){
Practicant p;
PutMark(p,5);
PutSalary(p,200);
}
Din exemplu se vede, c clasa derivat import comportamentul ambelor clase de baz,
aa cum, , cu parametrii ambelor funcii globale, adic principiul de
rmne in vigoare! Desigur c, rmne n vigoare i posibilitatea de utilizare a formelor de
motenire, se poate de motenit deschis de la una i nchis de la alta.
Problemele
Ca i orice alt instrument puternic i frumos, motenirea multipl are neajunsurile sale,
care au devenit motivul de eliminare a motenirii multiple din multe limbaje moderne.
Problemele apar din motivul apariiei . Presupunem, c n ambele clase
de baz exist cmpuri cu unul i acelai nume.
class A{
public:
int x;
};
class B{
public:
int x;
};
n aa fel clasa C conine dou variabile cu unul i acelai nume, aa cum se motenesc
ambele, deoarece pentru fiecare clasa de baz variabila poate s aib un sens propriu.
Compilatorul nu poate decide, crei din variabilele motenite sa-i atribuie valoarea nou.
Aceiai situaie are loc i cu funciile.
Rezolvarea acestei neechivalene const n utilizarea precizrii numelui variabilei.
Numele variabilelor pot coincide, dar numele claselor nu coincid. Aa c, pentru indicarea
variabilei care este utilizat trebuie de indicat clasa, de la care este motenit variabila:
c.A::x = 10;
c.B::x = 5;
Mai dificil este cnd clasele A i B sunt nrudite, adic provin de la aceleai clase, aa
cum este prezentat n figura 1, cu toate c poate exista un caz mai dificil. n aceast
configurare exist dou variabile identice, cu unul i acelai sens. Se pot deosebi, aa cum
este prezentat mai sus. Dar problema const n aceia, c ele i dup sens sunt identice, iar
funciile definite n nivelul doi al ierarhiei, vor lucra n propriile copiii ale variabilelor, care
des duc la greeli semantice greu de gsit. Mai mult ca att, n acest caz, constructorul clasei
de baz este chemat de dou ori. Pentru rezolvarea acestei probleme se utilizeaz ultima
form de motenire: virtual.
class A{
public:
int x;
A(int x){this->x=x;}
};
class B: virtual public A{
public:
B(int x):A(x){}
};
class C: virtual public A{
public:
C(int x):A(x){}
};
class D: public B, public C{
public:
D(int x):A(x),B(x),C(x){}
}
Sarcina lucrarii:
a) S se creeze, o ierarhie de motenire: vehicul, camion maina de teren.
b) S se creeze, o ierarhie de motenire: automobil - vehicul, camion main de teren.
Listingul programului:
a)ierarhia vehicul,camion-masina de teren
Headeruri-le Vehicle,Truck,Terrain_car.h
//
// Created by JACK on 11/6/2015.
//
#ifndef CEF05A_VEHICLE_H
#define CEF05A_VEHICLE_H
#include <iostream>
using namespace std;
class Vehicle {
protected:
string name;
int price;
public:
Vehicle();
Vehicle(string,int);
Vehicle(const Vehicle&);
Vehicle& operator =(const Vehicle&);
friend istream& operator >>(istream&, Vehicle&);
friend ostream& operator <<(ostream&,const Vehicle&);
virtual ~Vehicle();
};
#endif //CEF05A_VEHICLE_H
//
// Created by JACK on 11/6/2015.
//
#ifndef CEF05A_TRUCK_H
#define CEF05A_TRUCK_H
#include <iostream>
using namespace std;
class Truck {
protected:
int power;
int weight;
public:
Truck();
Truck(int,int);
Truck(const Truck&);
return in;
}
ostream& operator<<(ostream& out, const Vehicle& obj) {
out << "Name : " << obj.name;
out << "\nPrice : " << obj.price;
return out;
}
Vehicle::~Vehicle() {
name = "";
price = 0;
}
//
// Created by JACK on 11/6/2015.
//
#include "Truck.h"
Truck::Truck():power(0),weight(0) { }
Truck::Truck(int power, int weight):power(power),weight(weight) { }
Truck::Truck(const Truck& obj):power(obj.power),weight(obj.weight) { }
Truck& Truck::operator=(const Truck& obj) {
if (this == &obj) {
return *this;
}
power = obj.power;
weight = obj.weight;
return *this;
}
istream& operator>>(istream& in, Truck& obj) {
cout << "Input power : ";
in >> obj.power;
cout << "Input weight : ";
in >> obj.weight;
return in;
}
ostream& operator<<(ostream& out, const Truck& obj) {
out << "\nPower : " << obj.power;
out << "\nWeight : " << obj.weight;
return out;
}
Truck::~Truck() {
power = 0;
weight = 0;
}
//
// Created by JACK on 11/6/2015.
//
#include "Terrain_car.h"
Terrain_car::Terrain_car(): Vehicle(),Truck(),type("") { }
Fisierul main.cpp
#include <iostream>
#include <stdlib.h>
#include "Terrain_car.h"
using namespace std;
int main() {
Terrain_car mycar;
cin >> mycar;
system("cls");
cout << mycar;
cout << endl;
system("pause");
return 0;
}
#ifndef CEF05A_TRANSPORT_H
#define CEF05A_TRANSPORT_H
#include <iostream>
using namespace std;
class Transport {
protected:
string trans;
public:
Transport();
Transport(string);
Transport(const Transport&);
Transport& operator =(const Transport&);
friend istream& operator >>(istream&, Transport&);
friend ostream& operator <<(ostream&,const Transport&);
virtual ~Transport();
};
#endif //CEF05A_TRANSPORT_H
//
// Created by JACK on 11/6/2015.
//
#ifndef CEF05A_VEHICLE_H
#define CEF05A_VEHICLE_H
#include "Transport.h"
class Vehicle : virtual public Transport {
protected:
string name;
int price;
public:
Vehicle();
Vehicle(string,string,int);
Vehicle(const Vehicle&);
Vehicle& operator =(const Vehicle&);
friend istream& operator >>(istream&, Vehicle&);
friend ostream& operator <<(ostream&,const Vehicle&);
virtual ~Vehicle();
};
#endif //CEF05A_VEHICLE_H
//
// Created by JACK on 11/6/2015.
//
#ifndef CEF05A_TRUCK_H
#define CEF05A_TRUCK_H
#include "Transport.h"
class Truck : virtual public Transport {
protected:
int power;
int weight;
public:
Truck();
Truck(string,int,int);
Truck(const Truck&);
return out;
}
Transport::~Transport() {
trans = "";
}
//
// Created by JACK on 11/6/2015.
//
#include "Vehicle.h"
Vehicle::Vehicle(): Transport(),name(""),price(0) { }
Vehicle::Vehicle(string trans,string name,int price):
Transport(trans),name(name),price(price) { }
Vehicle::Vehicle(const Vehicle& vehicle1):
Transport(vehicle1),name(vehicle1.name),price(vehicle1.price) { }
Vehicle& Vehicle::operator=(const Vehicle& obj) {
if(this == &obj) {
return *this;
}
Transport::operator=(dynamic_cast<const Transport&>(obj));
name = obj.name;
price = obj.price;
return *this;
}
istream& operator>>(istream& in, Vehicle& obj) {
in >> dynamic_cast<Transport&>(obj);
cout << "Input name : ";
in >> obj.name;
cout << "Input price : ";
in >> obj.price;
return in;
}
ostream&
out <<
out <<
out <<
return
}
Vehicle::~Vehicle() {
name = "";
price = 0;
}
//
// Created by JACK on 11/6/2015.
//
#include "Truck.h"
Truck::Truck(): Transport(),power(0),weight(0) { }
Truck::Truck(string trans,int power,int weight):
Transport(trans),power(power),weight(weight) { }
Truck::~Truck() {
power = 0;
weight = 0;
}
//
// Created by JACK on 11/6/2015.
//
#include "Terrain_Car.h"
Terrain_Car::Terrain_Car(): Vehicle(),Truck(),type("") { }
Terrain_Car::Terrain_Car(string trans,string name,int price,int power,int
weight,string type):
Transport(trans),Vehicle(trans,name,price),Truck(trans,power,weight),type("") {
}
Terrain_Car::Terrain_Car(const Terrain_Car& car):
Transport(car),Vehicle(car),Truck(car),type(car.type) { }
Terrain_Car& Terrain_Car::operator=(const Terrain_Car& car) {
if (this == &car) {
return *this;
}
Vehicle::operator=(dynamic_cast<const Vehicle&>(car));
Truck::operator=(dynamic_cast<const Truck&>(car));
type = car.type;
return *this;
}
istream& operator>>(istream& in, Terrain_Car& car) {
in >> dynamic_cast<Vehicle&>(car);
cout << "Input power : ";
in >> car.power;
cout << "Input weight : ";
in >> car.weight;
cout << "Input type : ";
in >> car.type;
return in;
}
ostream&
out <<
out <<
out <<
out <<
return
}
Terrain_Car::~Terrain_Car() {
type = "";
}
Fisierul main.cpp
#include <iostream>
#include <stdlib.h>
#include "Terrain_Car.h"
using namespace std;
int main() {
Terrain_Car mycar;
cin >> mycar;
system("cls");
cout << mycar;
cout << endl;
system("pause");
return 0;
}
Concluzie:
In urma efectuarii acestei lucrari de laborator capatat cunostinte despre
modul de lucru cu mecanismul multiplu in C++,este un mecanism foarte util
din considerentul ca clasele scrise precedent pot fi utilizate intr-o clasa care
v-a folosi functionalul lor,in plus cu ceva nou.
In mecanismul de mostenire multiplu in cazul in care avem mostenirea
ROMB poate aparea probleme atunci cind o clasa mosteneste de la doua
clase care la rindul lor mostenesc de la clasa mama deexemplu acelasi
cind,pentru prevederea asemenea cazuri este necesar de declarant clasele
care mostenesc de la clasa mama virtuale.