Sdílet prostřednictvím


Jak: návrh pro bezpečnost výjimku (C++)

Jednou z výhod mechanismus výjimek je toto provedení, spolu s údaji o výjimce, přejde přímo z příkazu, který vyvolá výjimku prvního zachycení příkazem, který zpracovává ho.Obslužná rutina může být libovolný počet úrovní nahoru v zásobníku volání.Funkce, které se nazývají mezi příkaz try a příkaz throw, není nutné žádné informace o výjimce, která je vyvolána.Však musí být navržen tak, že můžete přejít mimo rozsah "nečekaně" na místo, kde může šířit až od pod výjimku a tak Zredukovat za částečně vytvořené objekty úniku paměti nebo datových struktur, které jsou ve státech nepoužitelná.

Základní postupy

Robustní zpracování výjimek zásad vyžaduje pečlivé myšlenky a měl by být součástí procesu návrhu.Obecně většina výjimek jsou zjištěny a v nižších vrstvách softwarový modul vyvolána výjimka, ale obvykle tyto vrstvy nemají dostatek kontextu zpracování chyb nebo vystavit zprávu koncovým uživatelům.Ve střední vrstvy můžete funkce zachytit a znovu vyvolal výjimku v případě, že mají kontrolovat objekt výjimky nebo mají další užitečné informace pro vrchní vrstvu, která nakonec zachytí výjimku.Funkce by měla zachytit a "swallow" výjimku pouze v případě, že je schopen zcela zotavit.V mnoha případech je umožnit výjimku rozšířit až na vrchol zásobníku volání správné chování ve střední vrstvy.I v nejvyšší vrstvě je vhodné nechat neošetřená výjimka ukončit program, pokud výjimka opouští program v jiném státě, ve kterém nelze zaručit jejich správnost.

Bez ohledu na to, jak funkce zpracovává výjimky, pomohou zaručit, že se jedná o "bezpečné výjimka," musí být navrženy podle následujících základních pravidel.

Hh279653.collapse_all(cs-cz,VS.110).gifZachovat jednoduchý zdroj tříd

Při zapouzdřit Správa ruční prostředků ve třídách, použijte třídu, která nemá žádnou jinou spravovat jednotlivé zdroje; v ostatních případech dojít ke vzniku netěsnosti.

Hh279653.collapse_all(cs-cz,VS.110).gifSpráva prostředků pomocí stylu RAII

Za bezpečné pro výjimku musí zajistit objekty, aby byla přidělena pomocí funkce malloc nebo new jsou zničeny, a všechny prostředky, jako jsou popisovače souborů jsou uzavřeny nebo uvolněny ani v případě, že je vyvolána výjimka.Inicializace je pořízení prostředku (RAII) stylu spojuje řízení těchto zdrojů na životnost automatické proměnné.Když funkci dostane mimo rozsah platnosti, vrácením běžným způsobem nebo z důvodu výjimky, jsou vyvolány destruktory pro všechny plně konstruovány automatické proměnné.Objekt obálky RAII například inteligentní ukazatel volání, vhodné odstranit nebo zavřete funkce v jeho destruktor.Výjimka safe code je životně důležité pro předání vlastnictví jednotlivých zdrojů určitý druh objektu RAII.Všimněte si, že vector, string, make_shared, fstream, a podobné třídy zpracovat pořízení prostředku pro vás. Nicméně unique_ptr a tradiční shared_ptr staveb nejsou zvláštní, protože pořízení prostředků provádí uživatel namísto objektu; proto považovány za Zničení je uvolnění prostředků , ale sporný jako RAII.

Tři výjimky záruky

Obvykle je popsána výjimka bezpečnosti z hlediska záruky tři výjimky, které mohou poskytovat funkce: Ne selhání záruční, silné záručnía základní záruka.

Hh279653.collapse_all(cs-cz,VS.110).gifZáruka ne proti selhání

Záruka ne proti selhání (nebo "Ne throw") je nejsilnější zaručeno, že mohou poskytovat funkce.To znamená, že funkce vyvolat výjimku, nebo se povolit jeden k šíření.Však nelze poskytnout spolehlivě taková záruka nevíte (a) jsou všechny funkce, které volá tuto funkci také ne proti selhání, nebo (b) víte, že jsou zachyceny všechny výjimky, které jsou vyvolány, dříve, než dosáhnou-li tuto funkci, nebo (c) víte, jak zachytit a správně zpracovává všechny výjimky, které mohou dosáhnout této funkce.

Silné záruky a základní záruka spolehnout za předpokladu, že jsou destruktory č proti selhání.Všechny nádoby a typy v knihovně Standard zaručit jejich destruktory nelze vyvolat.Je také vyžadováno konverzace: standardní knihovny vyžaduje, že uživatelem definované typy, které byly sděleny – například jako argumenty šablony – musí mít bez vyvolání destruktory.

Hh279653.collapse_all(cs-cz,VS.110).gifSilné záruky

Silné záruky uvádí, že je-li funkce nedostane mimo rozsah platnosti z důvodu výjimky, znatelné netěsnosti stavu paměti a program nebude změněn.Funkce, která poskytuje silné záruka je v podstatě transakce, která má sémantiku potvrzení nebo vrácení: zcela úspěšná nebo nemá žádný vliv.

Hh279653.collapse_all(cs-cz,VS.110).gifZákladní záruka

Základní záruka je nejnižší prioritu tři.Při silné záruky je příliš nákladné, spotřeba paměti nebo výkonu však může být nejlepším řešením.Základní zaručit státy, že pokud dojde k výjimce, byly prozrazeny žádné paměti a objekt je stále v použitelném stavu, přestože data mohl být změněn.

Výjimka bezpečné třídy

Třídu lze zajistit bezpečnost svou vlastní výjimku, i v případě, že je spotřebované nebezpečné funkce tím, že sám částečně vyrobeno nebo zčásti zničeno.Je-li konstruktor třídy ukončí před dokončením, nikdy vytvoření objektu a jeho destruktor se nikdy volána.Přestože automatické proměnné, které jsou inicializovány před výjimka bude mít jejich destruktory vyvolán dynamicky přidělená paměť nebo prostředky, které nejsou spravovány inteligentní ukazatel nebo podobné automatické proměnné bude prozrazena.

Předdefinované typy jsou všechny ne selhání a typy standardní knihovny podporují základní záruka minimálně.Postupujte podle těchto pokynů pro typ definovaný uživatelem, který musí být bezpečné výjimek:

  • Umožňuje spravovat všechny prostředky chytré ukazatele nebo jiných obalů RAII typu.Funkce správy zdrojů ve vašem destruktoru třídy vyhnout, protože destruktor nesmí vyvolat, je-li konstruktor vyvolá výjimku.Pokud je třída správce vyhrazený prostředek, který řídí pouze jeden zdroj, pak je však přijatelné použít ke správě prostředků destruktor.

  • Pochopit, že výjimka vyvolána v konstruktoru základní třídy nemůže požití v konstruktoru odvozené třídy.Pokud chcete přeložit a znovu vyvolal výjimku základní třídy v konstruktoru odvozené, pomocí bloku try funkce.Další informace naleznete v tématu Jak: zpracování výjimek v základní třídě konstruktory (C++).

  • Zvažte, zda pro uložení stavu všech třídy v datovém členu, který je obalen elementy inteligentní ukazatele, zejména v případě, že třída má pojem "inicializace, který je povolen selhání." Přestože C++ umožňuje členům neinicializovaná data, nepodporuje instance inicializována nebo částečně inicializované třídy.Konstruktor musí buď úspěšné nebo selže; je-li konstruktor se nespustí po dokončení není vytvořen žádný objekt.

  • Nepovolit výjimky k návratu z destruktoru.Základní teorii C++ je, že destruktory by nikdy povolit výjimku rozšířit až na vrchol zásobníku volání.Pokud destruktoru musí provádět operace potenciálně vyvolání výjimky, musí to v bloku try catch blokem a swallow výjimku.Standardní knihovna obsahuje všechny destruktory, který definuje tuto jistotu.

Viz také

Koncepty

Chyby a zpracování výjimek (moderní Příručka programování C++)

Jak: rozhraní mezi výjimečné a jiných výjimečných kód