Pokud umožňujete kopírovat sdílením, tedy že máte konstruktor který přijímá const referenci a provede sdílení, pak vám const nepomůže, protože ho tímto způsobem obejdete
Pseudo příklad
const Value cv = {10,20,30}
Value v (cv);
v.push_back(40); // < změní se i cv!!;
Musel byste se vzdát jiných věcí. Tak například kopírování sdílením... tedy vytvářet plnohodnotné kopie. Kopírovací konstruktor by při přijmu const hodnoty prostě nemohl sdílet, musel by kopírovat. Přitom pokud kopírujete do objektu o kterém víte, že taky bude pouze const, pak je vytváření hluboké kopie zbytečné. Kopírovací konstruktor však tuhle informaci nemá
Value x(y); // potřebuju kopii
const Value x(y); // mohu sdílet.
Já to ze začátku řešil tak, že jsem měl dvě třídy. Value a ConstValue. Objekty Value by obsahovaly měnitelné kontejnery, objekty ConstValue by se měnit nedaly. No jenže co když chcete mít měnitelný kontejner konstantních kontejneru? Kterou třídu na to použijete? Já zavedl třetí....
No výsledek nebyl vůbec přehledný. Navíc jsem časem zjistil, že používám v zásadě jen ConstValue a objekty, kterým jsem říkal buildery, tedy něco, co mi pomáhá vytvořit kontejner (objekt , pole) než z něho udělám ConstValue. A tak jsem to celé přepsal do současné podoby.
Ptal jsem se proto, ze sam jsem nad podobnou otazku hloubal a klonil se spise k opacnemu zaveru, zajimal mne Vas nahled.
Mozna se tedy zeptam jinak - k cemu je kopirovani sdilenim dobre? Proc proste nepouzit const referenci?
Proc to neresit stylem:
Value x(y); // potřebuju kopii
const Value& x = y; // mohu sdílet. (... lifetime y bych nyni neresil)
Jde Vam o moznost jak se priblizit pouziti STL kontejneru const objektu nebo neco jineho?
Celé je to o tom vyhnout se dělání hlubokých kopií. JSON dokument může být velký, může být sestaven z mnoha částí.
Value result = {result1, result2, result3,...,resultN}
pokud result1 až resultN jsou všechno nějaké JSON kontejnery, pak stojíte před otázkou: Výše uvedený příklad
a) udělá kopie výsledků?
b) bude je sdílet?
asi a) je správnější, jenže... pokud každý ten result má několik megabajtů nebo strukturu do 10. úrovně pak přistupujete ke kroku b). Jenže tohle nemůžete udělat, pokud existuje někdo, kdo může obsah result1 až resultN změnit, třeba tak, jak měníte obsah proměnné typu vektor, a protože jsou ty kontejnery sdílené, změna se uplatní všude, kde je se to sdílí. On to bude měnit ve své instanci, která není označená const, přestože vy třeba držíte const verzi. Naprosto stejně funguje JavaScript, jen si to zkuste. Udělám kopii kontejneru, dojde ke sdílení
aa = [10,20,30];
bb = aa;
aa.push(40);
console.log(bb);
>[10, 20, 30, 40]
Takže výsledkem je, že nemohu použít ani a) a ani b)
Ještě je tu c) - totiž, že ze všeho udělám konstanty. Konstanty mohu sdílet, protože se nemění.
Jak si jednotlivé varianty vypadají při změnách?
a) mohu měnit co chci, mám kopii (tu musím udělat vždy)
b) mohu měnit jen to co není sdílené, nebo přijmout fakt, že se ta změna projeví jinde
c) pokud chci měnit, musím si udělat kopii toho co měním (mělká kopie)
ImtJSON je právě implementace DOMu variantou c).
Tím jsem odpověděl na otázku "k cemu je kopirovani sdilenim dobre?"
"Proc proste nepouzit const referenci?".Když sdílím, const reference nefungují. Mohu si udělat kopii sdílením. Aby const reference fungovaly, musím se vrátit k a).
PS: K variantě a), představte si, že sestavujete JSON dokument odspoda nahoru. Na každé úrovni kopírujete vše ze spodní úrovně tak, jak vkládáte prvky do kontejnerů... já vím, že jde použít std::move a přesouvat místo kopírování... dokud vám někdo ty výsledky neposkytnul jako const referenci.... pak kopírovat musíte
Intenzivně se zabývám programováním zejména v jazyce C++. Vyvíjím vlastní knihovny, vzory, techniky, používám šablony, to vše proto, aby se mi usnadnil život při návrhu aplikací. Pracoval jsem jako programátor ve společnosti Seznam.cz. Nyní jsem se usadil v jednom startupu, kde vyvíjím serverové komponenty a informační systémy v C++
Přečteno 51 063×
Přečteno 23 939×
Přečteno 22 871×
Přečteno 20 952×
Přečteno 17 760×