Czytam aktualnie o sytuacjach wyjątkowych i mam pytanie odnośnie kopiowania obiektów przy throw do obiektu statycznego.
Rozumiem tą rzecz kiedy chodzi o kopiowanie obiektu lokalnego, bo w końcu po odwikłaniu stosu - opuszczeniu bloku try - przestaje on istnieć. Nie było by możliwe skopiowanie go do argumentu w catch’u lub bezpośrednio pracowanie na nim, jeżeli typ argumentu w catch’u byłby referencją.
Ale czemu np. przy rzucaniu obiektu wyjątku, który jest obiektem globalnym też zachodzi to kopiowanie do obiektu globalnego (sprawdziłem to za pomocą konstr. kop.) :?: Niepotrzebne tracenie czasu… Tak samo jak np. przy kopiowaniu obiektu automatycznego, który jest jakby w tym samym zakresie ważności co blok try. Chodzi mi coś takiego:
Eee, no a jaki to ma związek z moim pytaniem bo nie rozumiem…
Czy to przez wartość czy przez ref/wsk to i tak każdy obiekt wyjątku przy throw musi zostać skopiowany pierwsze do obiektu static, który na stosie nie jest. Dzieje się tak nawet z globalnymi, chociaż im odwikłanie stosu nic nie zrobi. I tego nie kapuję.
Wyobraź sobie, że catch tworzy osobną funkcję która za argument przyjmuje jakiś typ wyjątku. Gdy rzucasz wyjątek throw “wywołuje” tą metodę catch i przekazuje jej rzucany obiekt. Jeśli obiekt jest referencją to szuka “funkcji catch” przyjmującej jako pierwszy argument referencję, jeśli obiekt jest wskaźnikiem to szuka funkcji przyjmującej wskaźnik a jeśli nie jest referencją ani wskaźnikiem to przekazuje go do “funkcji catch” przyjmującej argument przez wartość, czyli obiekt zostaje skopiowany i w “funckji catch” działamy na lokalnym obiekcie. Taki to ma związek.
Tak jest naprawdę. A przecież ten obiekt static, wg “Pasji C++” został założony po to, żeby kopiować do niego obiekty, które zaraz zginą na stosie w try.
Wiadomo, że obiekt globalny nie potrzebuje takiego kopiowania - bo po opuszczeniu try’u nie zginie :!:
Więc nie lepiej, żeby było coś takiego w przypadku obiektów globalnych :?:
Ah, o to Ci chodzi. W sumie nie zagłębiałem się nigdy w działanie wyjątków od strony technicznej. No bo i po co. Wyjątków nie używa się dużo razy, więc nie powinno się tego odczuć(a tym bardziej nie ma potrzeby się zastanawiać dlaczego tak, a nie inaczej).
Wiem, że to nie “rozwiązanie” problemu zadanego w temacie, a jedynie jego “obejście”, ale podchodząc praktycznie do zagadnienia: zasadniczo nie rzuca się obiektami globalnymi (oraz w C++ wyjątków nie używa się tak często jak w Javie, co dodatkowo pomniejsza skalę problemu ;))
Tak jak dałeś na rysunku rzutlepszy.png będzie w przypadku catch(int &ob) i tylko w takim przypadku może tak być.
Funkcji jak mniemam już rozumiesz bardzo dobrze więc potraktuj (w wyobraźni) tego catch’a jako funkcje z określonym typem argumentu zaś throw jako wywołanie tej funkcji … od razu zrozumiesz czemu musi to być skopiowane.
Jak typ nie będzie wskaźnikiem/referencją - oczywiście nastąpi kopiowanie ze schowka (zmiennej static). Nie wiem czemu, też autor powtarza to w książce, przecież to jest oczywiste jak 2+2 = 4. Jeżeli będzie ref/wsk, to ze schowka się nic nie będzie kopiowało, ale do funkcji prześle się adres schowka, i będzie pracowało się na oryginalnym schowku.
No właśnie o to mi chodziło. Myślałem, że globalne obiekty mogą ominąć kopiowania do schowka , ale to już nieważne