2010-10-28 11 views
5

rozważmy Mam następującą funkcję:affectations i wyjątki

SomeType createSomeType(); 

które mogą throw zależności od pewnych powodów.

Następnie:

SomeType val = SomeType(); // initial value 

try 
{ 
    val = createSomeType(); // here 
} 
catch (std::exception&) 
{ 
} 

Jeśli createSomeType() rzuty, zawsze mogę założyć, że val wartość niezmienione?

Odpowiedz

7

Tak, jeśli createSomeType() zgłasza wyjątek, zadanie nie zostanie wykonane. Przepływ kontroli przejdzie od instrukcji throw, poprzez destruktory dowolnego obiektu createSomeType() na stosie i na końcu do instrukcji catch.

1

Jeśli operator przypisania dla SomeType jest bezpieczny dla wyjątków, można mieć pewność, że albo val zostanie przypisana stała nowa wartość, albo jej początkowa wartość pozostanie niezmieniona.

Jednak wyjątek może zostać zgłoszony przez createSomeType() lub przez zadanie po pomyślnym uruchomieniu createSomeType(). Jeśli operator przypisania dla SomeType jest przeciążony i może zgłaszać wyjątki, może się zdarzyć, że val kończy się w "niesparowanym stanie" w połowie przypisanym. Ta ostatnia jest wynikiem nieprzyjmowania wyjątkowego bezpieczeństwa w projekcie, który jest zły, ale nadal może się zdarzyć.

+4

Jeśli 'createSomeType' rzutów, będzie ciało operatora przypisania kiedykolwiek być wprowadzone? Jak mogła zmienić wartość w takim przypadku? –

+0

@ Space_C0wb0y: Może się zdarzyć, że ciało nie wyrzuci, ale przeładowane zadanie rzuca. – sharptooth

+1

OP wyraźnie pyta o przypadek, w którym "createSomeType" rzuca, więc operator przypisania nie odgrywa roli (w tym konkretnym scenariuszu). –

0

od standardowych docs 15.2.1,

miarę upływu sterowanie z rzutów ekspresji do obsługi, destruktory są wywoływane dla wszystkich automatycznych obiektów zbudowanych ponieważ blok try został wprowadzony. Obiekty automatyczne są niszczone w odwrotnej kolejności niż ich budowa .

Stąd wartość val nie zmieni ...