W jaki sposób norma określa czas życia obiektu tymczasowego utworzonego podczas oceny wyrażenia warunku o wartości if
?Czas istnienia nienazwanego tymczasowego obiektu zbudowanego w wyrażeniu warunku
Szukałem tej informacji i znalazłem coś podobnego w przykładzie do punktu [10] w 1.9 $, strona 10. (Mam tutaj na myśli Ostateczną wersję roboczą nowej specyfikacji.) Jednak wciąż nie było to jasne (wystarczy) i ponieważ Visual C++ działał inaczej niż moje zrozumienie tego przykładu, zdecydowałem się zapytać.
Proszę podać właściwe odniesienia do specyfikacji.
Jeśli nazwa obiektu to utrzymuje się przez cały if
(tak więc zarówno true
bloku i false
bloku ale jest zniszczone przed if
końcach).
Na przykład:
if (MyClass x = f()) { /* ... */ } else { /* ... */ }
nextInstruction();
x
mogą być stosowane zarówno w if
blokach ale zostaje zniszczony przed nextInstruction
zostanie wywołany.
Ale co, jeśli tego nie nazwiesz?
if (f()) { /* ... */ } else { /* ... */ }
nextInstruction();
W moim zrozumieniu odwołania części specyfikacji wartość zwracana przez f()
zostanie zniszczony zanim wejdzie jeden z bloków (zarówno dla true
lub dla false
) wykonanie.
Jednak Visual C++ niszczy ten tymczasowy obiekt tak, jakby został nazwany. (EDIT:..! jak Tino Didriksen wskazał Visual C++ działa dobrze tu i rzeczywiście teraz potwierdzić, że również muszę się pomylić, patrząc na wstępnych wynikach testów)
ten ma znaczenie w niektórych skrajnych przypadkach (nie omawiamy tutaj, jak bardzo są prawdopodobne i czy dobrze jest napisać kod w ten sposób ...).
Na przykład pozwala mieć:
class ScopedLock {
public:
~ScopedLock() { if (isLocked()) unlock(); }
operator bool() const { return isLocked(); }
/* ... */
};
Teraz, jeśli mamy kod jak:
if (ScopedLock lock = resource.lock()) { /* ... */ }
możemy być pewni, że gdy wykonanie wchodzi blok true
posiadamy zasób i że nie będzie być odblokowane, zanim opuścimy ten blok.
Ale co, jeśli ktoś napisał tak:
if (resource.lock()) { /* ... */ }
Teraz ważne jest w tym momencie destruktora dla tymczasowego ScopedLock
zostanie wywołana. Ponieważ określa, czy ten kod jest poprawny, czy nie (w sensie wykorzystania zasobów). (Znów pomińmy dyskusję na temat tego, czy pisanie takiego kodu jest generalnie złe, nie o to pytać ...)
W pełni kompilowany przykład będzie znacznie lepszy, a następnie fragmenty kodu. Twoje pytanie jest trudne do zrozumienia ze względu na złożoność. Zajęło mi trochę czasu, aby zrozumieć, ale jest dobre :) –