[C++] Kopiowanie do obiektu static przy throw obiektu global


(Quentin) #1

Witam!

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:

void fun()

(Fiołek) #2

W C++ argumenty przekazuje się przez wartość(domyślnie), nie przez referencję/wskaźnik. Z blokami try..catch jest tak samo.


(Quentin) #3

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ę.


(Fiołek) #4

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.


(Quentin) #5

Nie rozumiesz o co mi chodzi :wink:

:arrow: http://img263.imageshack.us/img263/8927/rzutgorszy.png

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 :?:

:arrow: http://img401.imageshack.us/img401/3307/rzutlepszy.png


Mam nadzieję, że teraz wiecie o co mi chodzi...


(Fiołek) #6

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).


(Sawyer47) #7

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 :wink:)


(Quentin) #8

Aha, no to dzięki za pomoc :slight_smile:


([alex]) #9

Chyba jednak nie zrozumieliście się z fiolkiem :smiley:

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.


(Quentin) #10

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 :stuck_out_tongue: