トップページ⇒tech
21コメント6KB

[C++]深い呼び出しからの復帰

■ このスレッドは過去ログ倉庫に格納されています
0001名無しさん@お腹いっぱい。NGNG
言語はC++です。
A@`B@`C@`D@`Eは関数 or メソッドです。

AがBを呼んで
BがCを呼んで
CがDを呼んで
DがEを呼んで
という状況があるとします。
ここでEからAへ一気に戻りたいんです。
returnしていくのも気に入らないので
Eで例外を投げてAで捕捉しようと思います。

この方法どう思いますか?
0002名無しさん@お腹いっぱい。NGNG
バカ
0003名無しさん@お腹へった。NGNG
設計しなおす > 1
00041NGNG
どうもです。
これsetjmp@`longjmpよりは安全だし
しっかり説明を書いておけばすっきりしてるんですが。。。
具体的な理由を説明してくれませんか?
0005>1NGNG
>returnしていくのも気に入らないので
何故そう思うのか、よく考えてみろ。
0006名無しさん@お腹いっぱい。NGNG
あなたの書くプログラムは誰も使いたくないでしょう。
0007名無しさん@お腹いっぱい。 NGNG
>あなたの書くプログラムは誰も使いたくないでしょう。
B〜Eは(同じクラスなら)privateにしてあれば、
まあ、普通と思います。
エラーで戻るなら、throwを使うのは問題ないと思います。
0008名無しさん@お腹いっぱい。NGNG
例えば
BにおけるC
CにおけるD
の呼び出し以前に
何か明示的な後片付けが必要な処理(典型的にはnew)を行っていた場合、
それらが片づけられないままになるのが問題。
自動変数として確保されたオブジェクトについては、throwによる
スタック巻き戻しの際に破棄されるけれども、破棄すべき資源が
常にこのような形で獲得されている訳ではなかろう。

これを回避するには

1.
BやCといった中間層でもtry/catchを使い、
例外を捕捉-->後片付け-->再throw
といった処理を行う

2.
BやCでは明示的な後片付けが必要となる処理を行わないようにする

といった方策が考えられるが、1は手抜きをしたいという当初の意図には
反するし、2のような方針を今後そのコードを保守する全ての人間に
確実に守らせるというのは難しいだろう。
0009名無しさん@光速NGNG
ていうかさ、例外有効なら、関数は常に、いつ下から例外が上がって
来ても問題ない作りになってなくちゃだめだよ。そもそも。本当わね(ワラ
0010名無しさん@お腹いっぱい。NGNG
要するに「コルーチン」作りたいんだよね
まず、それ以外の方法で作れないかどうか考えてみて
それ以外の方法でしか作れない場合、作っていいんじゃない?
# 質問が抽象的なのでこれぐらいのことしか答えられない

もちろん、いくつかの注意点があり(例えば>>8)
変なバグを作らないように気をつけてください
0011>1NGNG
もしかしてゲームでも書いてる?
0012名無しさん@お腹いっぱい。NGNG
しかしコルーチンを例外で実装というのも、なんか…
速度も速くないし、プログラムのミスは発生しやすいし、
returnに比べていいことないと思うけど。

Cのlongjmpの代わりにC++では例外を使うという発想は
間違ってると思う。
0013名無しさん@お腹いっぱい。NGNG
longjmp ってどういうときに使う?
ハードウエア関係の処理でしか使用経験なし。
0014名無しさん@お腹いっぱい。NGNG
エラー処理なら遠慮なくthrowしとけ。newにはauto_ptrを使っておけ。
エラーでないならやめとけ。もっと簡単な方法が必ずある。
0015名無しさん@お腹いっぱい。NGNG
残念ながら例外でコルーチンは実装出来ない
0016名無しさん@お腹いっぱい。NGNG
1に確認したいのだが、そもそも B@`C@`D@`E はプログラム
中何度も呼ばれるものなのか?
そしてまさか、
funcD(){・・・・funcE();return;};
funcC(){・・・・funcD();return;};
funcB(){・・・・funcE();return;};

なんて事になってるんじゃないだろうな?

あるいは、funcEで入力終了を検出したら、一挙に処理を捨てて
しまいたいような処理なのか?
0017名無しさん@お腹いっぱい。NGNG
newした資源うんぬんってのは普通のreturnでも同じ問題が起こる。
結局throwは大域returnだ。
0018>17NGNG
せいぜいメモリリークさせないように気をつけてくれ。
0019名無しさん@お腹いっぱい。NGNG
http://member.nifty.ne.jp/f-sasaki/CFSP.LZH

コルーチン
0020名無しさん@お腹いっぱい。NGNG
>17
「大域return」を使うメリットがひとつもない。効率もよくならないし、
コーディングも簡単にならない。どちらもよくて同等、むしろ不利な場合
の方が多い。
0021文字列の代入・長さ取得・比較・連結NGNG
#include <stdio.h>
#include <string.h>
void main()
{
char s1[80]@`s2[80];
int ln;

strcpy(s1@`"abcdef");
strcpy(s2@`"uvwxyz");
printf("s1=%s s2=%s\n"@`s1@`s2);

ln=strlen(s1);
printf("1en=%d\n"@`ln);

if(strcmp(s1@`s2) >0)
printf("左辺が大\n");
if(strcmp(s1@`s2) <0)
printf("右辺が大\n");
if(strcmp(s1@`s2) ==0)
printf("等しい\n");
if(strcmp(s1@`s2) !=0)
printf("等しくない\n");

strcat(s1@`s2);
printf("s1+s2=%s\n"@`s1);
}


■ このスレッドは過去ログ倉庫に格納されています