Odpověď na názor

Odpovídáte na názor ke článku Alokátory a operator new v C++.

  • 5. 9. 2012 14:21

    Ondřej Novák (neregistrovaný)

    [6] k tomu asi pár námitek.

    1) Vůbec to není o továrnách (což taková funkce Create mimochodem je). V C++ existuje jediná legální cesta, jak vytvořit objekt a to pomocí operátoru new. Nic jiného není možné, nebo jde o hack. I kdyby se to řešilo extra alokací a pak konstrukcí, i placement new je operator new. A samozřejmě výše uvedený systém nebrání takovou funkci napsat. Nicméně pořád je pro mě jednodušší napsat šablonu, která podědí T a DynObject a výslednou instanci (šablony) nechat zkonstruovat přes new(...).

    K tomuto bodu ještě jedna námitka. Problém šablony je ten, že předpokládáte konstrukci objektu bez parametů. Ale co když konstruktor vyžaduje nějaké parametry? Já mám dost objektů, které se nedají zkonstruovat bez parametrů. Jsou to zpravidla "satelity", pomocné objekty navázané na nějaký hlavní objekt a jeho referenci dostávají právě parametrem v konstruktoru. A zpravidla jsou ty satelity alokované nějakým speciálním alokátorem

    2) STL alokátory nelze instanciovat. Tečka. Tím jsou pro mě nepoužitelné (nemohu vytvořit instanci alokátoru, který by třeba spravoval nějaký kus paměti, kde by prováděl alokace).

    K druhé části bodu 2, opět je to totéž. Dealokaci v C++ smí provádět pouze a jenom pouze operátor delete. Pokud dealokujete zavoláním destruktoru a pak uvolnění paměti, tak potěš koště! Jak zjistíte velikost objektu? Co když má virtuální destruktor? Správnou velikost objektu poskytuje pouze operátor delete a to pouze ten přetížený ve třídě. A důvod, proč je vhodné znát velikost objektu při dealokaci jsem myslím uváděl.

    Dávat referenci dovnitř objektu je intruzivní řešení, které navíc trpí problémem rozštěpené zodpovědnosti. Jak se dostane tato reference do objektu? Kdo jí tam umístí? Alokátor nemůže, protože v době, kdy alokuje ten objekt ještě neexistuje. A konstruktor taky nemůže, protože ten zase nemusí o nějakém speciálním alokátoru vědět. Leda že by ho dostal jako parametr, ale pak jej zase uvádíme dvakrat (jednou jej voláme a pak předáváme konstruktoru, zajistěte, že vždycky půjde o tentýž objekt. Opět budete potřebovat nějakou továrnu). Tohle všechno věc šíleně zešložiťuje. A teď si k tomu přidejte takový exception handling kolem toho.

    p.s. A znova. K vytvoření objektu se používá new a k destrukci objektu se používá delete. Cokoliv jiného vede na zprasený neportabilní kód. Dodržujme prosím všechna doporučení tohoto nádherného jazyka. Nepleťte do toho chytré ukazatele, ty mají fungovat nad tímto systémem. A zase si hodně zjednoduším práci, když budu vědět, že chytrý ukazatel může objekt jednoduše dealokovat přes delete, aniž by musel nějaký alokátor znát.

    Moje PS (třída std::allocator slouží spíš k alokaci prvků ve vektoru. To je trochu jiná úloha, než alokace dynamických objektů)