Csak hogy a legnyilvanvalobbat emlitsem a problemak kozul:
- nem feltetlenul rossz, ha egy osztaly default constructible, ezt igy alapbol bukod
- vannak olyan konstruktorok (illetve tagabb ertelemben muveletek), amiknek nem fogsz tudni hibakodot atadni, a teljesseg igenye nelkul: copy constructor, move constructor, assignment operator, operatorok. Letilthatod a masolast es a move-olast, de ezzel kapasbol az osztalyod hasznalhatosagat korlatozod igen durvan. Pedig egy copy construktor is dobhat. Es igen tudni kell azt is kezelni. Attol meg hogy nem birsz atmasolni egy szazmegas buffer-t (bar ez nagyon hulye pelda).
- mivel privat a destruktorod, ezert a make_shared<> szoba sem johet az objektumra mutato shared_ptr letrehozasara. Ez rogton azt jelenti, hogy ketszer kell memoriat foglalni az objektumodhoz. Holott, ha engeded, hogy legyen egy kivetel dobasra kepes publikus konstruktorod, akkor meg akar stack-en is lakhatna, joforman zero overhead-del. Bar itt meg probalkozhatsz az objektumot szarmaztatni az std::enable_shared_from_this osztalybol, az egyik dinamikus memoriafoglalas megmarad es az nem tul olcso. Tovabba shared_ptr referencia szamlalasa szalbiztos, szoval a lock-olas vagy atomi muvelet koltsege is ott van.
- Megis melyik univerzumban szamit nullptr visszaadasa "egyertelmu hibajelzesnek"?
- Tegyuk fel, hogy van 10 overload-od a konstruktorra (lasd pl. std::vector<>) azert eleg meredek lenne 10 factory method-ot is csinalni hozzajuk. A template konstruktorok is adnanak okot nemi fejvakarasra. Es ha azt mondod, hogy probalsz ultra-okos lenni, akkor csinalsz egy variadic template factory method-ot, ami lefedi az osszes konstruktort, akkor is felulhetsz a szoporollerre, mert ez azokat a konstruktorokat is publikussa teszi, amiket egyen okokbol nem akartal publikussa tenni.
- Es osszessegeben megiscsak ugyanakkora mennyisegu munkarol beszelunk. A hibakezelest rohadt nehez jol csinalni, ezen nem a sufnimegoldasok fognak atlenditeni. Le kell ulni, meg kell csinalni a hazit.
- Tovabba a +1-es implementacios problema: ha az altalad javasolt modon jarunk el, akkor van az objektumodnak egy olyan allapota amikor a konstruktor mar bekrepalt, de az objektum a memoriaban van. Tehat potencialisan hasznalhatja valaki. Egy felkesz objektumot. Ebbol azert lehet baj, bar ha kovetkezetes vagy a shared_ptr-el, akkor ez feltehetoen nem issue.
- Es +2: Ha az osztalyod ososztalya vagy valamelyik adattag inicializaloja dob, akkor *nincs* ra mod, hogy megakadalyozd a kivetel tovabbadasat felfele. Egy function try-catch-el elkaphatod, de automatikusan ujradobodik a catch blokk vegen (ezt irja elo a szabvany es jo okkal!!!). Tehat a hivo scope vegehez fogunk erni rogton, az adott objektumot fel sem kell szabaditani, mivel "sohasem jott letre", destruktor sem hivodik meg, a nagytakaritast a function catch-ben kell elvegezni.
A kulcskulonbseg annyi, hogy a kivetelek lehetove teszik hogy a hiba keletkezese es a hiba kezelese kicsit tavolabb legyen es hogy kozben az eroforrasok ne vesszenek el. Es ez jo. Nem kell mindig hasznalni, de szerintem van sok eset, foleg ha library-t irsz, amikor a kivetelek a jo megoldasik a hibak jelzesere.