Kopiera och byta

Kopiera och byt idiom  är ett C++ programmeringsspråk idiom som låter dig designa undantag - toleranta tilldelningssatser.

Formspråket är baserat på formspråket " Att få en resurs initialiseras ".

Idiomet involverar implementeringen av följande klassmedlemsfunktioner:

Exempel:

klass kopierbar { offentliga : Copyable & operator = ( const Copyable & _v ) { kopierbar tmp ( _v ); detta -> swap ( tmp ); returnera * detta ; } void swap ( kopierbart & _v ) noexcept ; };

Undantagstolerans innebär att Copyable& operator=(const Copyable &)det inte finns någon mening med en tilldelningssats där att kasta ett undantag skulle orsaka en minnesläcka.

Tilldelningsoperatören försöker först skaffa den "tillfälliga kopian av objektet som tilldelas"-resursen ( tmp) och, om den lyckas, ändrar dess innehåll med innehållet i det aktuella objektet ( this). Eftersom metoden swapdeklareras som att den inte ger undantag ( noexcept), är den enda punkten där ett undantag kan inträffa när objektet kopieras _v. Om kopian misslyckas, når inte kontrollen metoden swap, annars släpper objektets destruktör tmpde resurser som tidigare ägdes av det aktuella objektet ( this) (se RAII-formspråket ).

Ovanstående implementering är också motståndskraftig mot tilldelningar av objektet till sig själv ( a=a), men den har overhead förknippad med det faktum att en tillfällig kopia också kommer att skapas i detta fall. Du kan exkludera kostnader genom ytterligare kontroll:

klass kopierbar { offentliga : Copyable & operator = ( const Copyable & _v ) { om ( detta != & _v ) Kopierbar ( _v ). byta ( * detta ); returnera * detta ; } void swap ( kopierbart & _v ) noexcept ; };

Många C++ Standard Library och STL -behållare och algoritmer förutsätter en undantagsresistent tilldelningsoperator, men utan att använda kopiera-och-byta idiomet är det ibland ganska svårt att implementera en sådan tilldelningsoperator för klasser som innehåller till exempel pekare till instanser av andra klasser.

Andra operationer

Om du har en medlemsfunktion swapsom inte skapar undantag, kan du använda en liknande teknik för att göra vilken operation som helst på ett objekt starkt undantagssäker .

För att göra detta, gör först en kopia av det befintliga objektet, utför de nödvändiga ändringarna på kopian och ändra sedan *thisdet tillfälliga objektet.

  • om ett undantag kastas av kopieringskonstruktören, ändras inte originalobjektet och den starka säkerhetsgarantin för undantag uppfylls;
  • om ett undantag görs när ett tillfälligt objekt ändras, kommer förstöraren att anropas på det tillfälliga objektet och garantin kommer också att uppfyllas eftersom det ursprungliga objektet inte har ändrats;
  • om ändringen av det temporära objektet lyckades, utlöses bytet och destruktören av det tillfälliga objektet, vilket inte skapar undantag.

Se även

  • Idiom kan inte kopieras