Mi a hiba az alábbi példákban?
a)
class A
{
...
};
class B
{
...
};
class C: public A, public B
{
...
};
B*pb= new C;
A*pa=(A*)pb;
C* pc = (C*)pv;
delete pc;
b)
class A
{
...
};
class B
{
...
};
class C: public A, public B
{
...
};
B*pb= new C;
void* pv=pb;
C* pc = (C*)pv;
delete pc;
Alkalmazottakat (Employee) tartunk nyilván egy polgármesteri hivatalnak készülő nyilvántartási rendszerünkben, amelyet a helyi kórház is használni fog. Az Alkalmazott a Személy osztályból (Person) származnak. A nyilvántartó rendszer két másik rendszerrel van kapcsolatban: az egyik az adóhivatal rendszere, a másik az egészségbiztosításé.
A Személy osztály deklarációja az alábbi:
class Person
{
protected:
string name;
int birthYear;
public:
Person(string name,
int birthYear):name(name), birthYear(birthYear){}
void print(){ cout << name << ' ' << birthYear << endl;}
void setBirthYear(int birthYear){ this->birthYear = birthYear; }
};
Az adóhivatal rendszere az alábbi osztályt adja, amibe nem nyúlhatunk bele, a forrása nincs meg, csak a .h file és a tárgykódú file valamilyen formátumban (.obj, .o, .a, .lib, .dll,.so):
class TaxSystem
{
unsigned tax;
public:
TaxSystem();
// Ezzel kell adót befizetni
void payTax(const ITaxPayer& taxPayer);
};
Ennek egy lehetséges implementációja az alábbi (a példa szerint nem áll rendelkezésre, csak binárisan, jelen példában nem akarjuk az összes operációs rendszerre lefordítva odaadni, inkább közöljük):
class TaxSystem
{
unsigned tax;
public:
TaxSystem():tax(0){};
// Ezzel kell adót befizetni
void payTax(const ITaxPayer& taxPayer)
{
// Húsz százalékot adózik
tax+=taxPayer.getIncome()*0.2-taxPayer.taxReduction();
}
};
Ennek az adófizetést végző függvénye az alábbi osztályt várja, amelyet mi is megkapunk:
class ITaxPayer
{
public:
// Az évi jövedelmet adja vissza
virtual unsigned getIncome()const=0;
// Az adókedvezményt adja vissza
virtual unsigned taxReduction()const=0;
};
Hasonlóan az egészségbiztosítás is rendelkezik egy rendszerrel, a függvények deklarációit .h állományban meg is kapjuk:
class HealthCare
{
public:
// Megnézi, van-e fedezet egy kezelésre
static bool isInsuranceForTreatment(IInsured& insured, unsigned amount);
// Levonja az kezelés költségét a biztosított egyenlegéből
static void chargeTreatment(IInsured& insured, unsigned amount);
};
Az implementáció nem áll rendelkezésre, csak binárisan, most az egyszerűség kedvéért megadjuk:
class HealthCare
{
public:
// Megnézi, van-e fedezet egy kezelésre
static bool isInsuranceForTreatment(IInsured& insured, unsigned amount)
{
if(insured.isValidInsurance() && insured.getInsuranceBalance() - amount >=0)
{
return true;
}
else
{
return false;
}
}
// Le vonja az kezelés költségét a biztosított egyenlegéből
static void chargeTreatment(IInsured& insured, unsigned amount)
{
if(isInsuranceForTreatment(insured,amount))
{
// Hibakezelés
assert(0);
}
else
{
insured.decreaseIsuranceBalance(amount);
}
}
};
Az IInsured osztály szintén rendelkezésre áll:
class IInsured
{
public:
// Az egészségbiztosítás egyenlegét adja vissz
virtual unsigned getInsuranceBalance()const=0;
// Megadja, hogy van-e az illetőnek érvényes biztosítása
virtual bool isValidInsurance()const=0;
//
virtual void decreaseIsuranceBalance(unsigned amount)=0;
};
Azt szeretnénk elérni, hogy az Employee osztály példányait egyszerűen tudjuk adóztatni, vagy ellenőrizni, van-e fedezet az ellátásra, illetve az ellátás költségét levonni a biztosításból.
Erre egy példa:
int main()
{
Employee emp ("James Bond", 1930,1952);
emp.salary=200000; // Ennyit keres havonta
emp.insuranceBalance+=700000; // Ennyi TB-t fizetnek utána, Mr. Bond gyakran kerül kórházba
// Az APEH rendszeréhez kapcsolódunk
TaxSystem ts;
// Adót fizetünk
ts.payTax(emp);
// Mr. Bond kórházba kerül egy lövöldözés után az Aranykéz utcában (Golden Hand c. epizód)
// Az OEP rendszeréhez kapcsolódik a kórház, megnézi, ki tudja-e fizetni a kezelést
if(!HealthCare::isInsuranceForTreatment(emp,500000))
{
cout << "No money for treatment" << endl;
}
// A kezelés után levonja a kezelés értékét a biztosításból
HealthCare::chargeTreatment(emp,500000);
}