Izom copy-and-swap je idiom programovacího jazyka C++ , který vám umožňuje navrhovat příkazy přiřazení tolerantní k výjimkám .
Tento idiom je založen na idiomu „ Získání zdroje se inicializuje “.
Tento idiom zahrnuje implementaci následujících funkcí členů třídy:
Příklad:
class Copyable { veřejnost : Copyable & operator = ( const Copyable & _v ) { kopírovatelný tmp ( _v ); toto -> swap ( tmp ); vrátit * toto ; } void swap ( Copyable & _v ) noexcept ; };Tolerance výjimek znamená, Copyable& operator=(const Copyable &)že v příkazu přiřazení není žádný bod, kde by vyvolání výjimky způsobilo únik paměti.
Operátor přiřazení se nejprve pokusí získat zdroj „dočasné kopie přiřazovaného objektu“ ( tmp) a v případě úspěchu změní jeho obsah s obsahem aktuálního objektu ( this). Protože je metoda swapdeklarována jako nevyvolávající výjimky ( noexcept), jediným bodem, kde může dojít k výjimce, je kopírování objektu _v. Pokud se kopírování nezdaří, pak řízení nedosáhne metody swap, jinak destruktor objektu tmpuvolní prostředky, které dříve vlastnil aktuální objekt ( this) (viz idiom RAII ).
Výše uvedená implementace je odolná i vůči přiřazení objektu k sobě ( a=a), má však režii spojenou s tím, že i v tomto případě bude vytvořena dočasná kopie. Náklady můžete vyloučit dodatečnou kontrolou:
class Copyable { veřejnost : Copyable & operator = ( const Copyable & _v ) { if ( toto != & _v ) Kopírovatelné ( _v ). swap ( * toto ); vrátit * toto ; } void swap ( Copyable & _v ) noexcept ; };Mnoho kontejnerů a algoritmů C++ Standard Library a STL předpokládá operátor přiřazení odolný vůči výjimkám, ale bez použití idiomu copy-and-swap je někdy docela obtížné implementovat takový operátor přiřazení pro třídy obsahující například ukazatele na instance jiné třídy.
Máte-li členskou funkci swap, která nevyvolává výjimky, můžete použít podobnou techniku k provedení jakékoli operace s objektem se silnou zárukou bezpečnou pro výjimky .
Chcete-li to provést, nejprve vytvořte kopii existujícího objektu, proveďte na kopii potřebné úpravy a poté změňte *thisdočasný objekt.