91
Vývoj / Re:Upcasting potomka na abstrakciu
« kdy: 17. 12. 2020, 23:28:13 »Samotné auto (u upcasted2-4) nemůže být reference. Musíš použít auto&.
Ďakujem vyskúšam.
Já bych zkusil normální IClipboardReader reader = slot; Ale nenapsal jste ani co je to za jazyk. Vypadá to sice jako C++, ale co když je to něco jiného…
Dobrý deň, toto som skúšal ako prvé, vo vyšších jazykoch to takto pekne jednoducho funguje. Ale v C++ neni vyšší jazyk a všetko mu treba pekne po lopate vysvetliť. Čo je na druhej strane aj výhoda lebo aspoň programátor pochopí ako to funguje.
Já bych zkusil normální IClipboardReader reader = slot; Ale nenapsal jste ani co je to za jazyk. Vypadá to sice jako C++, ale co když je to něco jiného…
Je to C++, takže IClipboardReader reader = slot; nebude fungovat.
IClipboardReader je abstraktní třída (interface). Nedají se od ní vytvářet instance. Jdou jenom pointery a reference. A samotná instance musí být něco odvozeného.
Fungovat bude třeba :Kód: [Vybrat]IClipboardReader &reader = slot;
IClipboardReader *reader = &slot;Kód: [Vybrat]dělá slicing. Zkopíruje bázovou třídu do nové instance. A protože je abstraktní, tak to nejde. To je ta hláška "cannot instantiate abstract class"
IClipboardReader reader = slot;
Pro Fortrana :Kód: [Vybrat]dělá taky slicing. Auto dělá z referencí hodnoty, pokud se mu neřekne jinak. Dokonce bych řekl, že je to rozumné defaultní chování. C++ není Java. Chování podobné intům je žádoucí.auto upcasted2 = (IClipboardReader&)slot; // Error: 'IClipboardReader': cannot instantiate abstract class
auto upcasted3 = std::forward<const IClipboardReader&>(slot); // Error: 'IClipboardReader': cannot instantiate abstract class
auto upcasted4 = static_cast<const IClipboardReader&>(slot); // Error: 'IClipboardReader': cannot instantiate abstract class
Druhá věc je, proč ten cast vůbec chcete ručně dělat. Volat metody předka jde i na potomkovi. A pokud budete volat nějakou funkci co bere referenci na předka, tak ten cast udělá překladač sám. Za sebe si nepamatuju, kdy jsem potřeboval ručně castit na předka. Je to fakt vzácné.
Jinak std::forward slouží k forwardování obecných parametrů a k ničemu jinému. Uvnitř je to sice cast, ale nepoužívejte to tak. Pokud nepíšete nějakou optimalizovanou ale zároveň generickou šablonu, tak forward nechcete používat. V běžném kódu se vyskytuje minimálně.
Ďakujem Vám za podrobné vysvetlenie.
Prečo to chcem pretypovať? Občas chcem pred programátorom zobraziť len metódy predka. Aby som ho nerozptyloval metódami potomka. Dajme tomu že si urobíte Modul File a v ňom funkciu File::GetStat ktorá vám vracia kompletný objekt FileStat obsahujúci info o súbore (časy modifikácie, IdSkupiny, IdJednotky, Velkosť súboru). Ale kôli užívateľskej prívetivosti si možno chcete urobiť aj wrapper File::GetTimes, od ktorého, ale programátor očakáva že bude obsahovať len časy ale už nie IdSkupiny IdJednotky a podobne. Viem že čistejší sposob by bolo ručné namapovanie objektu FileStat na FileTimes lenže takto je to jednoduchšie a hlavne omnoho rýchlejšie.


