Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Ne-defaultni konstruktori u virtualnim baznim klasama

[es] :: C/C++ programiranje :: Ne-defaultni konstruktori u virtualnim baznim klasama

[ Pregleda: 1819 | Odgovora: 15 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

peromalosutra
Ivan Rajkovic
Software engineer
Luxoft
Berlin

Član broj: 54774
Poruke: 846
*.prolocation.net.



+144 Profil

icon Ne-defaultni konstruktori u virtualnim baznim klasama25.05.2018. u 13:38 - pre 29 meseci
Prvo mali intro, radim na aplikaciji koja treba da prikazuje neku telemetriju, ali takodje i da salje komande nazad ka sistemu koji prati. E sad prikazivanje nije 1-1, bice tu i procesiranja kao sto je konverzija mjernih jedinica, kesiranje, filtriranje, bufferovanje nekih vrijednosti, itd. Takodje i interakcija sa korisnikom ce zahtjevati neke masine stanja.

E sad, posto ima gomila nepoznanica, a aplikacija se razvija paralelno sa samim sistemom koji nadzire, dosao sam na ideju da koristim arhitekuru baziranu na grafovima. Dakle imam baznu klasu Node (cvorovi grafa), te klase EventSource i DataSource koje definisu ivice grafa. Sam graf definisem u XML fajlu i python scriptom generisem C++ koji kreira cvorove i uspostavlja veze izmedju njih. Na ovaj nacin, vecinu logike guram u samu definiciju grafa (XML fajl), a ja vec mogu da implementiram gomilu nodova koje znam da ce mi trebati. Moze se cak reci da je XML fajl neka vrsta DSL-a (Domain Specific Language).

Konacno - pitanje: Node klasa je baza za EventSource i DataSource. Trebaju mi obe stvari (jedno radi pull, jedno push, ne mogu da ih objedinim). Obe klase moraju da znaju za Node (jer moraju da se identifikuju prema drugim cvorovima). Neki nodovi ce biti i EventSource i DataSource, sto dovodi do dijamanta (diamond problem). Turio sam da EventSource i DataSource virtuelno nasledjuju bazu Node i to je ok, e sad problem je sto Node klasa nema defaultni konstruktor, vec samo explicit konstruktor koji uzima parametar (nodeid). Medjutim ovo znaci da svaka klasa koja nasledjuje EventSource ili DataSource mora eksplicitno da zove Node(nodeid) konstruktor. Ovo je stvar virtuelnog nasledjivanja, gdje "most derived" klasa uvijek prvo zove virtuelne baze. Ovaj pristup mi se ne svidja jer su sve child klase "zaprljane" detaljima bazne klase - prvo moraju da i one uzimaju NodeId parametar, zatim moraju da ga proslijede Node konstruktoru. I tako za svaku child klasu. Gadno.

Alternativa je da Node klasi dam default konstruktor i dodatnu metodu setNodeId(NodeId). Ovo znaci da vise ne moram da se bakcem oko pozivanja baznog konstruktora u child klasama (poziva se implicitno). Mana je sto mi to malo smrdi, jer je uloga konstruktora da ustanovi invarijantu. Nemam problem sa tim da cu zaboraviti da setujem NodeId, jer kao sto rekoh, to ce sve da izgenerise python skripta svakako, ali opet..

Cini mi se da imam sukob izmedju rjesenja za koje mislim da je ispravno (prva opcija) i onog koje mi djeluje elegantno (druga opcija).

Pitanje je, postoji li neka treca i bolja opcija? Samo nemojte reci da je multiple inheritance zlo, zato sto u ovom slucaju bas fino odgovara problemu, kompozicija mi ne odgovara.
 
Odgovor na temu

Branimir Maksimovic
Senior Software Engineer

Član broj: 64947
Poruke: 4850
178.250.138.*



+992 Profil

icon Re: Ne-defaultni konstruktori u virtualnim baznim klasama25.05.2018. u 13:54 - pre 29 meseci
Pa cim moras da setujes nodeid, svejedno ces morati u konstruktoru mos derived klase. Ako to ne moras onda znaci da mozes da spucas defaultni konstruktor.
Meni nekako sam graf ne ide da bi trebalo da bude vezan samo za Data/EventSource, posto mozda samu strukturu mozes da upotrebis za jos nesto, al ajde.
Nego imas neki specificni razlog sto neces kompoziciju? Ona je skoro uvek bolje resenje od nasledjivanja.
press any key to continue or any other to quit....
 
Odgovor na temu

peromalosutra
Ivan Rajkovic
Software engineer
Luxoft
Berlin

Član broj: 54774
Poruke: 846
*.ip.prioritytelecom.net.



+144 Profil

icon Re: Ne-defaultni konstruktori u virtualnim baznim klasama25.05.2018. u 19:43 - pre 29 meseci
Mogu raditi dodjelu NodeId-a u konstruktoru (sto znaci da svaka klasa mora da prosledjuje taj parametar dalje Node klasi), ali kao drugo rijesenje, mogu i da imam metodu setNodeId() u Node baznoj klasi. U tom slucaju gomila klasa koje nasledjuju Node klasu ne moraju da eksplicitno pozivaju konstruktor bazne klase (kompajler sam izgenerise poziv za defaultni konstruktor).

Dakle imam trade off, gdje u drugom slucaju konstrukciju radim u dve faze (prvo pravim objekat na heapu, pa onda zovem setNodeId), ali buduci da ce kreiranje nodova raditi python skripta, ostatak koda (gomila klasa koje implementiraju cvorove grafa) je malo cistiji.

E sad, sto se kompozicije vs. nasledjivanja tice, jasno je da treba uvijek pokusati sa kompozicijom, ali u ovom slucaju mi to ne odgovara. Cvor koji implementira DataSource jeste (is-a) DataSource. Nasledjivanjem DataSource bazne klase on dobija njen interfejs i ostali cvorovi grafa mogu da komuniciraju sa njim preko tog interfejsa. Ista stvar je isa EventSource klasom. S tim sto cvor moze da bude i DataSource i EventSource u isto vrijeme.

 
Odgovor na temu

Branimir Maksimovic
Senior Software Engineer

Član broj: 64947
Poruke: 4850
178.250.138.*



+992 Profil

icon Re: Ne-defaultni konstruktori u virtualnim baznim klasama25.05.2018. u 19:57 - pre 29 meseci
Nekako ne bih izvodio Data/Event Source iz cvora, nego bih u cvoru spucao dva pointera Event/Data Source, gde bi ove bile bazne klase/interfejsi. Ref na cvor mozes da bacas u konstruktoru bez problema, pa prica stoji sa setNodeId.
To mu dodje na isto samo sa time da Data/Event sourcevi postaju cisti interfejsi umesto da se vezuju za cvor.
press any key to continue or any other to quit....
 
Odgovor na temu

djoka_l
Beograd

Član broj: 56075
Poruke: 2917

Jabber: djoka_l


+1223 Profil

icon Re: Ne-defaultni konstruktori u virtualnim baznim klasama26.05.2018. u 09:50 - pre 29 meseci
Večiti problem C++ programera - kako prilagoditi realan problem virtuelnom svetu C++ programa. A da sve to staviš u C i ne razmišljaš o virtuelnim baznim klasama i njihovim nedefaultnim konstruktorima. Ili da promeniš od početka pristup problemu.
 
Odgovor na temu

Branimir Maksimovic
Senior Software Engineer

Član broj: 64947
Poruke: 4850
178.250.138.*



+992 Profil

icon Re: Ne-defaultni konstruktori u virtualnim baznim klasama26.05.2018. u 13:52 - pre 29 meseci
Nije ovo samo specificno za C++, vec za OO programiranje. Ko da si reko batali OOP, vrati se na proceduralno ;)
Ja sam mu samo rekao kako bi ovo resio da radi recimo u Javi posto ona ne podrzava multiple inheritance... no ovo njegovo resenje je sasvim ok.
press any key to continue or any other to quit....
 
Odgovor na temu

djoka_l
Beograd

Član broj: 56075
Poruke: 2917

Jabber: djoka_l


+1223 Profil

icon Re: Ne-defaultni konstruktori u virtualnim baznim klasama26.05.2018. u 15:36 - pre 29 meseci
Jasno je meni to, ali mi se čini da prrogrameri koji su počeli odmah sa OOP imaju naopako "zašrafljenu" glavu. Umesto da razmišljaju o rešenju problema, misle da će im egzotične konstrukcije jezika to rešiti.
Hoće da mu Node bude virtuelna klasa, pa onda smisli da Node može da ide samo izlaz ili samo ulaz. Zašto virtuelna? Meni je odmah znak da nešto nije u redu kada se ubaci virtuelna klasa. Šta node radi? Ovako kako je postavio - ništa. Često OOP-ovci zaborave osnovnu stvar u vezi klase - KLASA MORA NEŠTO DA RADI. Ovde je koristi samo kao poštapalicu. Zašto ne interfejs? Zašto node ne može da ima listu ulaznih tačaka i listu izlaznih tačaka. Umesto toga, on pravi neke klase koje samo mogu da prime poruku ili samo da pošalju.
Čak i sam opis, Node je čvor grafa, a ove druge dve su ivice. Kako to da je ivica grafa nešto što se izvodi iz čvora grafa?

I oupšte, ceo taj koncept, neko će da napravi XML, Python će da ga procesira i pretvori ga u C++, pa će neko da kompajlira taj C++. Srećno mu bilo sa debagovanjem!
 
Odgovor na temu

dejanet
Beograd

Član broj: 19240
Poruke: 1043
*.dynamic.sbb.rs.



+759 Profil

icon Re: Ne-defaultni konstruktori u virtualnim baznim klasama26.05.2018. u 16:38 - pre 29 meseci
Pa da, zasto ne list<EventSource > i list<DataSource> kao properties u Node klasi, plus getter i setters, plus odgovarajuci metodi u nastavku ?
 
Odgovor na temu

Branimir Maksimovic
Senior Software Engineer

Član broj: 64947
Poruke: 4850
178.250.138.*



+992 Profil

icon Re: Ne-defaultni konstruktori u virtualnim baznim klasama26.05.2018. u 17:45 - pre 29 meseci
samo list<Node> mislim. a sam node uz to ima i Event/Data Source pointere. Tako bih ja. Cisto da ne bi morao da se radi downcast.
press any key to continue or any other to quit....
 
Odgovor na temu

peromalosutra
Ivan Rajkovic
Software engineer
Luxoft
Berlin

Član broj: 54774
Poruke: 846
*.ip.prioritytelecom.net.



+144 Profil

icon Re: Ne-defaultni konstruktori u virtualnim baznim klasama27.05.2018. u 08:35 - pre 29 meseci
Citat:
djoka_l: A da sve to staviš u C i ne razmišljaš o virtuelnim baznim klasama i njihovim nedefaultnim konstruktorima.


Hoćeš da kazes da C kod nema arhitekturu, već samo kreneš da krkaš linije koda i nadaš se da će to da skalira? Arhitektura aplikacije često ne zavisi od samog jezika, OOP možeš da pišeš i u C-u, sa sve virtuelnim metodama. Treba samo malo više boilerplate koda koji ti C++ napravi za tebe.

E sad, zašto miješati grafove u sve ovo? Pa zato što je to jedan od pristupa da napraviš fleksibilnu arhitekturu. Zamisli da imaš gomilu implementiranih čvorova, npr. jedan čvor uzima vrijednost i prosleđuje ju dalje samo ako dođe do promjene, drugi čvor uzima neku vrijednost i renderuje ju kao GUI komponentu, itd. Svaki čvor je jedna lego kockica sa dobro definisanim interfejsom (Data/Event Source ulaz i Data/Event Source izlaz). I to mogu da programiram već danas. Onda kako dobijam detaljnije zahtjeve šta aplikacija treba tačno da radi, samo uklapam kockice (koristeći XML fajl). Ako mi zafali kockica, napravim novu, ali to ne utiče na ostatak aplikacije.

Prednosti ovakvog pristupa su skalabilnost, lakše pisanje unit testova (možeš svaki čvor pojedinačno da pokriješ), garantovano je da promjene unutar čvora neće da procure dalje, itd. All the good stuff.

Citat:
djoka_l:Jasno je meni to, ali mi se čini da prrogrameri koji su počeli odmah sa OOP imaju naopako "zašrafljenu" glavu. Umesto da razmišljaju o rešenju problema, misle da će im egzotične konstrukcije jezika to rešiti.


Ne znam da li se ovo odnosi na mene, ali pisao sam ja i proceduralni kod, a radio i u (embedded) C-u i web-u i asembleru na kraju krajeva. I, opet ponavljam, OOP nije vezan za jezik, OOP je pristup dizajniranju i možeš ga pisati i u asembleru ako želiš, samo ima više kucanja i sve moraš pješke. :)

Citat:
djoka_l:I oupšte, ceo taj koncept, neko će da napravi XML, Python će da ga procesira i pretvori ga u C++, pa će neko da kompajlira taj C++. Srećno mu bilo sa debagovanjem!


Ne znam čemu taj nedobudni ton, ali ajde. Nije prvi put da radim nešto na ovaj princip. Prednost code gen faze je što XML fajl definiše samu aplikativnu logiku. Na osnovu ovog fajla možeš čak izgenerisati sliku samog grafa (trivijalno sa GraphWiz), što pomaže kod dokumentacije. Svaki pojedinačni čvor testiraš kao da je black box. Inače, XML fajl je 1-1 preslikavanje u odnosu na C++, može se taj C++ napisati i ručno, ali budući da imam novi sloj indirekcije, mogu čak i promjeniti arhitekturu aplikacije u pozadini, a da ne diram samu logiku, samo paralelno updejtujem python parser da prati C++.

E sad da se vratimo na temu, zezancija zbog koje imam diamond "problem" (pod navodnicima jer zapravo i nije problem, rješenje postoji, ovdje pričamo o elegenciji i diskutujemo da li sam možda potpuno promašio i zaista ima puno bolji i jednostavniji pristup) je sledeća:

EventSource prilikom broadcasta event-a treba da se identifikuje. On to radi tako što pošalje NodeId parametar, koji ima zato što nasleđuje Node klasu. Tako primalac eventa zna ko je podigao event. Isto tako, povlačenje podataka (konzumer DataSource interfejsa) zahtjeva da se čvor od kojeg vučemo podatke identifikuje preko njegovog NodeId-a, jer jedan čvor može da vuče podatke od više drugih čvorova.

Zbog toga mi i EventSource i DataSource nasleđuju Event.

Citat:
dejanet: Pa da, zasto ne list<EventSource > i list<DataSource> kao properties u Node klasi, plus getter i setters, plus odgovarajuci metodi u nastavku ?


Citat:
Branimir Maksimovic: samo list<Node> mislim. a sam node uz to ima i Event/Data Source pointere. Tako bih ja. Cisto da ne bi morao da se radi downcast.


Ovdje se vraćamo na kompoziciju, a nisam siguran da je to dobar pristup (ili možda ne razumijem dobro šta predlažete).

Na primjer, ako imam čvor sa dva pointera (Event i Data source objekti), ja svejedno moram tom čvoru da dam i interfejs da bi drugi čvorovi mogli da komuniciraju sa njim. Taj interfejs upravo i obezbjeđuju Event i Data source objekti, pa ako naslijedim Event i Data source, ja taj interfejs dobijam besplatno. Sasvim moguće da nešto propuštam u ovoj priči.
 
Odgovor na temu

Branimir Maksimovic
Senior Software Engineer

Član broj: 64947
Poruke: 4850
178.250.138.*



+992 Profil

icon Re: Ne-defaultni konstruktori u virtualnim baznim klasama27.05.2018. u 10:42 - pre 29 meseci
"Na primjer, ako imam čvor sa dva pointera (Event i Data source objekti), ja svejedno moram tom čvoru da dam i interfejs da bi drugi čvorovi mogli da komuniciraju sa njim. Taj interfejs upravo i obezbjeđuju Event i Data source objekti, pa ako naslijedim Event i Data source, ja taj interfejs dobijam besplatno. Sasvim moguće da nešto propuštam u ovoj priči."

Graf ce svakako imati interfejs, samo je pitanje da li ces do Data/Event Source interfejsa dolaziti tako sto ces castovati nod ili jednostavno if(EventSource* es=node->eventSource()), svakako da mozes u ovoj f-ji castovati unutra ili jednostavno vratiti pointer.
Nekako je cistiji dizajn ako Event/DataSource ne nasledis iz Node, to je sve.
press any key to continue or any other to quit....
 
Odgovor na temu

peromalosutra
Ivan Rajkovic
Software engineer
Luxoft
Berlin

Član broj: 54774
Poruke: 846
*.ip.prioritytelecom.net.



+144 Profil

icon Re: Ne-defaultni konstruktori u virtualnim baznim klasama28.05.2018. u 21:54 - pre 29 meseci
Na kraju ste me inspirisali da ipak izmjenim pristup i mislim da sam došao do boljeg rješenja. Izbacio sam Node kao baznu klasu. Takođe sam se otarasio i NodeId koncepta, mislim da je to bila greška u samom startu. Pojedinačni čvor ne treba da zna za druge čvorove (npr. ne treba da ga interesuje NodeId onog ko šalje događaj). Umjesto toga radim sledeće:

Ukoliko čvor želi da emituje događaje, samo naslijedi EventSource klasu koja mu daje "subscribe" metodu. Ovu metodu mogu da koriste drugi čvorovi da registruju svoje event handlere. Event handler može biti bilo koji functor (uglavnom će to biti metoda neke druge čvor klase). Na ovaj način, individualni čvor ni ne zanima ko je emitovao događaj, već samo koji "slot" (event handler) je okinuo.

Što se DataSource interfejsa tiče, svaki čvor definiše scoped enumeraciju koja nabraja različite tipove ulaza u taj čvor. Na ovaj način kod unutar čvora opet ne mora da zna ništa o ostatku grafa, već samo vuče podatke, a enumeracija služi kao identifikator. Tek kod koji uvezuje čvorove (a koji se automatski generiše) radi mapiranje između enumeracija za pojedine čvorove i konkretnih node objekata.

Ovaj dizajn mi djeluje puno čistiji, nema više virtuelnog nasleđivanja, obrisao sam nešto nepotrebnog koda (explicitno pozivanje konstruktora), a mislim da sam još i povećao enkapsulaciju (čvor nema pojma o ostatku grafa, zna samo odakle da vuče podatke i može da mu bude dostavljen događaj). Možda ću još vratiti Node klasu nazad, ali ovaj put samo kao dummy zajedničku bazu kako bih mogao sve čvorove da držim u jednoj listi (mada, to možda neće biti ni potrebno).

E sad, finalno, zašto i ovdje koristim nasleđivanje, a ne kompoziciju: Pa DataSource interfejs je zapravo template (DataSource<T>), gdje T označava konkretan tip podataka koji DataSource obezbjeđuje. Ovaj interfejs sadrži apstraktnu metodu "T get()" koja vraća konkretne podatke. "T" može biti bilo šta, od struktura (koje se dosta koriste kao nosioci podataka u ostatku već razvijenih interfejsa sa kojima aplikacija treba da priča), pa do integralnih tipova.

PS: Hvala svima na hintovima, natjerali su me na razmišljanje.

C++ FTW :)

 
Odgovor na temu

djoka_l
Beograd

Član broj: 56075
Poruke: 2917

Jabber: djoka_l


+1223 Profil

icon Re: Ne-defaultni konstruktori u virtualnim baznim klasama28.05.2018. u 22:11 - pre 29 meseci
Nema na čemu
Nisam hteo da namećem rešenje, ali ono što je meni prvo palo na pamet je neki message queue, i neki "worker" elementi (consumer, producer). Svi slušaju MQ, svaki uzima poruku koja mu je interesantna, pa onda nešto radi sa tom porukom, pa je ili vraća obrađenu u MQ ili je negde upisuje. Možda veza između nodova ima topologiju grafa, ali uopšte nije potrebno da se i programu nameće grafoliko rešenje.
 
Odgovor na temu

Branimir Maksimovic
Senior Software Engineer

Član broj: 64947
Poruke: 4850
178.250.138.*



+992 Profil

icon Re: Ne-defaultni konstruktori u virtualnim baznim klasama29.05.2018. u 02:20 - pre 29 meseci
Citat:
peromalosutra:
Na kraju ste me inspirisali da ipak izmjenim pristup i mislim da sam došao do boljeg rješenja. Izbacio sam Node kao baznu klasu. Takođe sam se otarasio i NodeId koncepta, mislim da je to bila greška u samom startu. Pojedinačni čvor ne treba da zna za druge čvorove (npr. ne treba da ga interesuje NodeId onog ko šalje događaj). Umjesto toga radim sledeće:

Ukoliko čvor želi da emituje događaje, samo naslijedi EventSource klasu koja mu daje "subscribe" metodu. Ovu metodu mogu da koriste drugi čvorovi da registruju svoje event handlere. Event handler može biti bilo koji functor (uglavnom će to biti metoda neke druge čvor klase). Na ovaj način, individualni čvor ni ne zanima ko je emitovao događaj, već samo koji "slot" (event handler) je okinuo.

Što se DataSource interfejsa tiče, svaki čvor definiše scoped enumeraciju koja nabraja različite tipove ulaza u taj čvor. Na ovaj način kod unutar čvora opet ne mora da zna ništa o ostatku grafa, već samo vuče podatke, a enumeracija služi kao identifikator. Tek kod koji uvezuje čvorove (a koji se automatski generiše) radi mapiranje između enumeracija za pojedine čvorove i konkretnih node objekata.

Ovaj dizajn mi djeluje puno čistiji, nema više virtuelnog nasleđivanja, obrisao sam nešto nepotrebnog koda (explicitno pozivanje konstruktora), a mislim da sam još i povećao enkapsulaciju (čvor nema pojma o ostatku grafa, zna samo odakle da vuče podatke i može da mu bude dostavljen događaj). Možda ću još vratiti Node klasu nazad, ali ovaj put samo kao dummy zajedničku bazu kako bih mogao sve čvorove da držim u jednoj listi (mada, to možda neće biti ni potrebno).

E sad, finalno, zašto i ovdje koristim nasleđivanje, a ne kompoziciju: Pa DataSource interfejs je zapravo template (DataSource<T>), gdje T označava konkretan tip podataka koji DataSource obezbjeđuje. Ovaj interfejs sadrži apstraktnu metodu "T get()" koja vraća konkretne podatke. "T" može biti bilo šta, od struktura (koje se dosta koriste kao nosioci podataka u ostatku već razvijenih interfejsa sa kojima aplikacija treba da priča), pa do integralnih tipova.

PS: Hvala svima na hintovima, natjerali su me na razmišljanje.

C++ FTW :)


Tvoje probleme sa nasledjivanjem resava klasa std::any od C++17, ali ako nemas takav kompajler onda mozda postoji mogucnost da to implementiras i sa nizim, mada, sada meni bas nije jasno kako bih to implementirao ;)

press any key to continue or any other to quit....
 
Odgovor na temu

Branimir Maksimovic
Senior Software Engineer

Član broj: 64947
Poruke: 4850
178.250.138.*



+992 Profil

icon Re: Ne-defaultni konstruktori u virtualnim baznim klasama29.05.2018. u 04:26 - pre 29 meseci
Na brzinu skleptah Any klasu pa mozda da neku ideju:

Code:

#include <typeinfo>
#include <iostream>

class Any{
public:
    template <class T>
    Any(const T& t){
        ti_ = &typeid(t);
        any_ = new T(t);
        d = &Any::deleter<T>;
    }
    ~Any(){
        (this->*d)();
    }
    template <class T> T* get(){
        if (typeid(T) == *ti_) {
            return (T*)any_;
        } else {
            return 0;
        }
    }
private:
    Any& operator=(const Any&);
    const std::type_info* ti_;
    void *any_;
    void (Any::*d)();
    template <class T> void deleter(){
        delete (T*)any_;
    }
};
struct A{
    int i;
};
int main(){
  Any ii(5);
  A a { 10 };
  Any aa = a;
  std::cout <<*ii.get<int>()<<'\n'<<aa.get<A>()->i<<'\n';
}



edit:
fali copy constructor al ako ti ovo zatreba nije problem da implementiram ;p


[Ovu poruku je menjao Branimir Maksimovic dana 29.05.2018. u 15:06 GMT+1]
press any key to continue or any other to quit....
 
Odgovor na temu

glorius
Damir Nikolic
C++ developer
SR

Član broj: 4366
Poruke: 428
80.240.144.*

ICQ: 208550327


+14 Profil

icon Re: Ne-defaultni konstruktori u virtualnim baznim klasama01.06.2018. u 15:35 - pre 29 meseci
Malo vuce ka offtopic-u ali ce mozda biti interesantno sto se tice generalnog dizajna i izbegavanja ovoga:

Citat:
Alternativa je da Node klasi dam default konstruktor i dodatnu metodu setNodeId(NodeId). Ovo znaci da vise ne moram da se bakcem oko pozivanja baznog konstruktora u child klasama (poziva se implicitno). Mana je sto mi to malo smrdi, jer je uloga konstruktora da ustanovi invarijantu. Nemam problem sa tim da cu zaboraviti da setujem NodeId, jer kao sto rekoh, to ce sve da izgenerise python skripta svakako, ali opet..


Ovakve probleme sam skoro uvek resavao tako sto koristim neki Creational pattern Factory/Builder... Ta klasa moze biti friend Node-u i nasledjenim klasama tako da mnoge osetljive metode mogu biti dostupne toj nekoj Factory klasi, i u isto vreme nedostupne spoljasnjem svetu i da svu funkcionalnost kreacije stavis u tu Factory klasicu. Tako mozes izbeci konstantno zvanje baznog konstruktora vec iz factory klase pozoves setNode()...
EOF
 
Odgovor na temu

[es] :: C/C++ programiranje :: Ne-defaultni konstruktori u virtualnim baznim klasama

[ Pregleda: 1819 | Odgovora: 15 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.