Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: asdf0 12. 10. 2014, 09:46:32
-
Dobry den,
ako riesite ukladanie data (typ) specifikovane uzivatelom? Uvedomujem si, ze je to celkom divne/blbo znejuca otazka, tak uvediem priklad:
struct Foo
{
...
int n;
User_data data;
};
...
std::vector<Foo> vec;
Cize mam nejaku strukturu Foo v ktorej chcem zahrnut lubovolny typ a rad by som to spravil bezbolestne. Napadaju ma 3 riesenia (z toho su 2 skoro rovnake :D):
- pomocou sablon - co by malo velku vyhodu ze poznam presny typ, ale kod, ktory tuto strukturu pouziva je dost velky a musel by byt zamoreny dalsim sablonovym kodom len kvoli tomu aby som mohol niekde na tu strukturu Foo<> odkazovat (projekt na ktorom pracujem je kniznica takze si nemozem spravit typedef/alias na presnu instanciu Foo<> sablony)
- pomocou void* - nemusel by som mat giganticke hlavickove subory ako pri sablonach ale pridem o typ a musim pouzit reinterpret_cast<> vo vsetkych funkciach v ktorych s touto strukturou pracujem (funkcie ktore tuto strukturu pouzivaju volaju callback-y taktiez specifikovane uzivatelom - do ich argumentov by som teoreticky mohol dat void* a nechal by som uzivatela nech si to sam pretypuje ale tiez mi to nepride ako to prave orechove...)
- skoro take iste ako 2. moznost: spravil by som si takuto nejaku triedu:
class User_data_base
{
public:
virtual ~User_data_base() = 0;
};
z ktorej by uzivatel dedil - aspon minimalna typova kontrola narozdiel od pouzivania holeho void* ale pouzivanie RTTI a dynamic_cast<>...meh...
Uchovavanie iteratoru/index ktory by odkazoval do nejakeho kontajneru/pola (cim by sa User_data uplne oddelilo od Foo) by vsetko znacne skomplikovalo pretoze struktura Foo je modifikovana z viacerych threadov.
Vase nazory? Mozno ine riesenia?
-
Nepokoušíš se v User_data o implementaci boost::any?
Jestli všechen kód používající Foo nemáš pod svou kontrolou, přetypovávání void* bych se snažil vyhnout.
-
Tak uz vim, proc sem pred lety prestal na root.cz psat :-D Neco uspesne odeslat je casove narocnejsi, nez napsat odpoved, sbohem jeste jednou.
- Zadané jméno nejde použít, protože obsahuje rezervované jméno
- Jméno které jste chtěl použít bylo moc dlouhé.
- Jaké zvíře se nachází ve slovním spojení „zrnko zelí“?:
- Doplňte název velkého lidového povstání (r.vol..e)...:
----
Ahoj, chapu dobre, ze se snazis dosahnout volani typovanych operaci nad promenymi s datovym typem, ktery je znamy jenom v runtimu? Zkus se podivat na Dispatch nebo Double Dispatch pattern. Zakladnim principem u Dispatch patternu je prevratit mysleni a prohodit operandy. Napr. misto storage.store(abstractSomething) volat abstractSomething.store(storage) a presmerovat volani zpatky, ale uz s konkretnim datovym typem.
void ConcreteSomething::store(Storage& storage) {
storage.store(this); // This has ConcreteSomething type
}
void Storage::store(const ConcreteSomething& something) {
// Type is known here
}
http://en.wikipedia.org/wiki/Double_dispatch
http://en.wikipedia.org/wiki/Visitor_pattern
Double Dispatch je pouzity napr. tady:
http://graphal.sourceforge.net/
http://sourceforge.net/p/graphal/code/ci/master/tree/libgraphal/ - tridy Value*