Názor ke článku JSON pro C++11 s immutabilním DOMem. od Ondřej Novák - Celé je to o tom vyhnout se dělání...

  • 14. 1. 2017 23:20

    Ondřej Novák

    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,...,re­sultN}

    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