friend vs protected/private öröklődés

 ( verkri | 2009. június 27., szombat - 23:31 )

Hello mindenki, a problémám a következő.

1, Van egy osztály, nevezzük "packer"-nek, amely egy bonyolult adatszerkezet csomagolóosztálya. Ez tökéletesen működik, külön header + impl fájlban ( packer.h, packer.cpp), szóval nem lenne jó bántani.

2, Van egy másik osztály(hierarchia) pl. "uclass", amelynek konstruktora egy "packer" objektumot kap, viszont meghív olyan globális függvényeket, amelyeknek a bonyolult adatszerkezetet kell átadni paraméterként, így érdemes lenne elérni a "packer" objektum adattagjait.

Kis szemléltető:
http://hup.pastebin.com/f2f40ef12

0.Mo: publikus getter függvény packer-be.
Problémák:
- függőségi problémák, minek akkor packer osztály, nemde?

1.Mo: Legyen uclass barátja packernek.

Problémák:
- módosítani kell packer.h -t, előfordulhat, hogy több uclass típusú osztály lesz, így állandóan módosítani kell packer.h-t. ( másrészt include-olni uclass.h-t, ide-oda függőség, ajajjaj )
- ha uclass-ból öröklődik valami, az már nem lesz barátja packer-nek, szóval ismét packer.h módosítás, blaaa

Kérdés: Lehet ezen problémákat kiküszöbölni?

2.Mo: Származzon uclass protected/private módon packer-ből.
Problémák:
- szükséges protected/private getter fgv-ek packer-ben, ezek lehetnek static-k, viszont akkor paraméterül kell kapjanak egy packer objektumot ( lásd 47.48. sorok ), amely nekem túl nyakatekertnek tűnik.
- a packer osztály protected/private függvényei, adattagjai ( amelyek nem tartoznak uclass-ra ) is láthatóak lesznek uclass-ban, és annak gyerekeinél is!!

Kérdés: Lehet ezen problémákat kiküszöbölni?

És a legutolsó kérdés:
TI hogyan oldanátok ezt meg?

Ha valami nem világos, pontosítok.

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

Szerintem sokkal megfelelobb lenne "csomagoloosztaly" helyett "burkolo osztaly" es "packer" helyett "wrapper", ha jol ertem a feladatat.

Az altalad felvazolt megoldasok kozul a 0. a legokesabb, az 1.-vel megsertened az egysegbezartsag alapelvet, a 2. meg a tipikus peldaja annak az esetnek, amelyben butasag oroklodest hasznalni (erre latom te is rajottel!).

En felulirnam Wrapper m_addr cast operatorat, benne meg visszateritenem az adattagot, igy az m_addr-t varo fuggvenyeknek kozvetlenul az osztaly peldanyat adhatnam parameterul.

----------------------
"ONE OF THESE DAYS I'M GOING TO CUT YOU INTO LITTLE PIECES!!!$E$%#$#%^*^"

A 0. szerintem a legrosszabb, mert ekkor gyakorlatilag kiadom a nagyvilágnak a "packer" azaz Wrapper osztály belső megvalósítását. ( implementáció elrejtése... ) Ez itt most fontos lenne, hogy ne így legyen, ezért is vetettem el.

Az m_addr -ra kasztoló operátor jó ötlet, majd megvizsgálom.

A protected és private öröklődés bár "öröklődés", gyakorlatilag csak implementációs technika, jelenleg én emellett állok.

"A 0. szerintem a legrosszabb, mert ekkor gyakorlatilag kiadom a nagyvilágnak a "packer" azaz Wrapper osztály belső megvalósítását. ( implementáció elrejtése... )"

Ebben a kontextusban nem ertem, miert fontos a union elrejtese, hiszen, mint mondtad, szukseges nehany globalis fuggveny meghivasanal, nem egy sajat tipus, amelyet barmikor valtoztathatsz...

"Ez itt most fontos lenne, hogy ne így legyen"

Miert?

"Az m_addr -ra kasztoló operátor jó ötlet, majd megvizsgálom."

Ez ugyanazt csinalja, mint a getter, csak szvsz kenyelmesebb...

"A protected és private öröklődés bár "öröklődés", gyakorlatilag csak implementációs technika, jelenleg én emellett állok."

Felesleges fuggosegeket vezetsz be, hiszen mindket oroklodestipussal tobbet fog tudni a szarmaztatott osztaly a wrapperrol, mint a getter eseten!

----------------------
"ONE OF THESE DAYS I'M GOING TO CUT YOU INTO LITTLE PIECES!!!$E$%#$#%^*^"

Egy egyszerű megoldás lehet a getterek helyett egy 'Unwrap' osztályt létrehozni,
ami friendje a Wrappernek, és rajta keresztül le tudsz kérdezni a bonyolult adatszerkezetekre mutató const ref-et.

class Wrapper
{
  friend class Unwrap;
public:
  ...
private:
  T m_x;
};


class Unwrap
{
  const Wrapper& m_w;
public:
  Unwrap(const Wrapper& w) : m_w(w) {}
  const T& getX() { return m_w.m_x; }
};