5ちゃんねる ★スマホ版★ ■掲示板に戻る■ 全部 1- 最新50  

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

例外処理

1 :デフォルトの名無しさん:2006/03/18(土) 16:37:26
語れ


372 :デフォルトの名無しさん:2006/12/01(金) 22:32:18
>>371
横レスだけど、それって(この例だと)

ファイルが無いときに困りはじめるところで例外を出せってことじゃないの?
一般的にファイルを扱うところ(言われたことをするだけ=下請け)と
各プログラムでそれを呼び出すところ(元請け)の違いではないかと

あさっての方向だったらゴメン

373 :デフォルトの名無しさん:2006/12/02(土) 00:28:04
まぁ例外とエラーは違うっつー話でFAC

374 :デフォルトの名無しさん:2006/12/02(土) 01:00:54
>>371
(一部すっとばすなどして)処理を続行可能な軽微なエラーのことだと思う。

375 :デフォルトの名無しさん:2006/12/02(土) 03:46:12
string.find()で-1が返るのもエラーと言えなくはないな

376 :デフォルトの名無しさん:2006/12/02(土) 16:44:20
匙を投げる代わりに例外を投げてるんだろ

377 :デフォルトの名無しさん:2006/12/02(土) 20:32:23
>>366
それはどこのJava/C#ですか?

378 :デフォルトの名無しさん:2006/12/02(土) 23:07:34
>377
Javaのcharも、C#(CLR)のcharもUTF-8じゃないんだが。


379 :デフォルトの名無しさん:2006/12/04(月) 14:57:59
とりあえずありえないような例外をCatchはしないようにしている
くらいかなぁ・・・
後一元管理でスタックトレースをログ保存してるくらいか・・・

380 :デフォルトの名無しさん:2006/12/05(火) 00:26:41
チェック例外と非チェック例外が共存するのってどうなんかな。
最近は専らJavaで書いてるけど、この共存状態は
便利さよりも危うさ・不明快さが勝るように感じる。
全部チェックもしくは全部非チェックじゃダメだったんだろうか。
ありえない状態はError投げれば良いし。

100歩譲ってRuntimeExceptionはThrowableから直接派生させるべきだったのでは。

381 :デフォルトの名無しさん:2006/12/05(火) 11:25:14
>>380
全部非チェックにすりゃよかったのに、って意見は多いよな。 後出しだけど。
全部チェックにすると、OutOfMemoryとか常に出る可能性があるからなんかだめぽ。

382 :デフォルトの名無しさん:2006/12/05(火) 11:33:46
OutOfMemoryErrorが追加されたんじゃなかったっけ

383 :デフォルトの名無しさん:2006/12/05(火) 23:52:57
Error は別にあるのに Exception のサブクラスで
RuntimeException を作ると言うクラス階層が
生理的に不自然に感じる。

384 :デフォルトの名無しさん:2006/12/15(金) 01:15:51
VC#のWeb参照でWSDLからクラスを自動生成すると
FAULTを思いっきりスルーしてくれるから困る。

385 :デフォルトの名無しさん:2006/12/19(火) 06:47:46
C++でアプリを正常終了する時に例外を投げるのって邪道?

386 :デフォルトの名無しさん:2006/12/19(火) 07:57:38
>>385
普通に間違い。

387 :デフォルトの名無しさん:2006/12/19(火) 11:01:33
ずっと稼動してる様なアプリだと、シグナルがきたら終わるとかよくやるけど
そこで例外投げるってのはどうかと思う。

>例外は、それを取り巻くコードの
>構造と意味を、根底から覆します。例外は、プログラムの実行時
>セマンティックを一時的に繋ぎ変え、通常実行しているコードを迂回し、
>こういう状況でなければ決して実行されないコードを動作させます。


388 :デフォルトの名無しさん:2006/12/19(火) 11:45:38
間違いってことはないが、明らかに設計が普通ではない

389 :デフォルトの名無しさん:2006/12/19(火) 13:05:36
例外って飛んできたらexitするしかないような処理でしょ。

390 :デフォルトの名無しさん:2006/12/19(火) 15:42:32
暗号化したコードを復元するためのシグナルに、例外を使ったことがある。
反省はしない。

391 :デフォルトの名無しさん:2006/12/19(火) 18:07:19
どこから飛んできたのか探すのが大変だから、正常系の処理に例外は使うなってこった。遅いし。
明らかに復帰不可能な例外なら投げてもいいけど。

392 :デフォルトの名無しさん:2006/12/20(水) 01:05:59
>>389
それが決まってるなら exit() すればいいわけで、例外投げる意味が無い。

393 :デフォルトの名無しさん:2006/12/20(水) 01:50:27
>>392
exit()するとオブジェクトの始末がされないのでは?

394 :デフォルトの名無しさん:2006/12/20(水) 10:54:02
exitするしかないような事態で、正常に後始末できるの?

395 :デフォルトの名無しさん:2006/12/20(水) 11:05:25
>>392
ローカルオブジェクトのデストラクタは呼び出されないね。
意味が無いわけじゃないな。

だからといって例外の使い道がそんな場合に限定されるわけじゃないよ。
catch した人が処理を選択できるのが例外の重要な意義なんだから。

>>394
なんでできないと思うの?

396 :デフォルトの名無しさん:2006/12/20(水) 11:22:56
exitするしかないような事態って、ディスクとかネットワークトラブルとか思い浮かべてたんだけど
そんな状態で正常に後始末できるのかなと

397 :デフォルトの名無しさん:2006/12/20(水) 13:44:53
コード上のリソース(ヒープとかファイルハンドルとか)の後始末じゃね?
C++ だと例外安全かどうか気をつかうことになりそうだけどサ

398 :デフォルトの名無しさん:2006/12/20(水) 21:20:00
C++に正解などない。
書きたいように書けばいいじゃないか。

399 :デフォルトの名無しさん:2006/12/20(水) 21:24:31
しかし定石はあると言えないか?

400 :デフォルトの名無しさん:2006/12/21(木) 20:21:33
Hoge::Hoge():pint( new int ){};
これは間違いだと言いたい。

401 :デフォルトの名無しさん:2006/12/21(木) 21:30:16
>>400
何を根拠にそんなことが言える?

402 :デフォルトの名無しさん:2006/12/22(金) 15:05:04
Hoge::Hoge():pint( new int ){};
には別に悪いことはないんじゃない。

ただ、コンストラクタ/デストラクタで例外出すのはやめて欲しいがな

403 :デフォルトの名無しさん:2006/12/22(金) 15:09:36
>>402
コンストラクタは別にいいだろ。他にどうやって失敗を通知するんだ?

404 :デフォルトの名無しさん:2006/12/22(金) 15:39:18
コンストラト処理中に例外発生した半端なオブジェクトに対して デストラクタは呼ばれない
該当半端オブジェクトの、例外発生前までのうまくいっている部位の後始末をどうするかが面倒

ってことで、問題を簡単化するのに >>402 な希望だと思う

405 :デフォルトの名無しさん:2006/12/22(金) 15:57:05
それぞれのメンバが適切に RAII のルールを守っていれば話はもっと単純にできる。
それをせずに「コンストラクタから例外禁止」なんて新しいルールを作るのは良くない。

406 :デフォルトの名無しさん:2006/12/22(金) 15:58:24
>例外発生前までのうまくいっている部位の後始末をどうするかが面倒

後始末が必要なものはクラスで包めばいいじゃん。

407 :デフォルトの名無しさん:2006/12/22(金) 16:08:59
結局RAIIに徹しろっていう普通の関数の例外安全性の議論と大差ないよね>コンストラクタ
RAIIが面倒な場合は初期化子リストにtry-catch仕掛けることもできるし

一般にコンストラクタは強い例外安全性を達成するべきという主張なら十分納得できるんだけれど

408 :デフォルトの名無しさん:2006/12/22(金) 19:01:16
class A {
Hoge *hoge; //どっちともコンストラクタで例外を出す可能性があるクラス
Hage *hage;

A()
 try:hoge( new Hoge ), hage( new Hage ) { }
 catch( ... )
{
初期化子にtry-catch掛けられるったって、こういう状況は非常に面倒くさい。
new Hageで例外でたらどーすんだ?
}


409 :デフォルトの名無しさん:2006/12/22(金) 19:23:23
> 後始末が必要なものはクラスで包めばいいじゃん。

410 :デフォルトの名無しさん:2006/12/22(金) 19:30:10
> 後始末が必要なものはクラスで包めばいいじゃん。
初期化子を使わずにコントロールしろということなのかな?

>>408 の例だと
A()
{
 try { hoge = new Hoge; } catch(...) { throw ; }
 try { hage = new Hage; } catch(...) { delete hoge; throw ; }
};

411 :デフォルトの名無しさん:2006/12/22(金) 19:31:25
スマートポインタ使えばいいのに

412 :デフォルトの名無しさん:2006/12/22(金) 19:36:13
class A
{
std::auto_ptr<Hoge> hoge;
std::auto_ptr<Hage> hage;
A() : hoge(new Hoge), hage(new Hage) {}
};

これでどちらで例外が投げられても大丈夫。

413 :デフォルトの名無しさん:2006/12/22(金) 19:39:46
>>412
AのA のデストラクタが呼ばれないのは分かるけど、A::hoge と A::hage のデストラクタは呼ばれるの?
スマートポインタって自身のデストラクタ呼ばれないと機能しないような気がするのだが

414 :デフォルトの名無しさん:2006/12/22(金) 19:49:51
>>413
コンストラクタが完了したものはデストラクタが呼ばれる。
new Hageで例外が出ても、hogeは構築済みだからデストラクタが呼ばれる。

415 :413:2006/12/22(金) 19:57:38
>>414
てんきゅう。 自分もコード動かして確認した…
例外周りのメンバの取り扱いはややこしいねぇ

実際投げてる例外はおいといてくれw
class Hoge {
public:
 Hoge() { std::cout << "Construct Hoge" << std::endl; }
 ~Hoge() { std::cout << "Destruct Hoge" << std::endl; }
};

class Hage {
public:
 Hage() { int e=1; throw e; }
};

class A {
 std::auto_ptr<Hoge> hoge;
 std::auto_ptr<Hage> hage;
public:
 A() : hoge(new Hoge), hage(new Hage) {}
};

int main() { try { A a; } catch (...) { } return 0; }

416 :デフォルトの名無しさん:2006/12/23(土) 04:53:54
構築に成功したオブジェクトは必ず解体に成功する
構築に失敗したオブジェクトは解体する必要がない
何か気をつける余地が0になるのがRAIIのありがたいところ

417 :デフォルトの名無しさん:2006/12/23(土) 12:37:30
new Hageで確保されたメモリは開放されんの?>auto_ptr

418 :デフォルトの名無しさん:2006/12/23(土) 13:45:43
>>417
それはnew演算子の仕事だよ

419 :デフォルトの名無しさん:2006/12/23(土) 14:45:27
>>418
んーごめん。まったくわからん(´д`;

420 :デフォルトの名無しさん:2006/12/23(土) 14:59:49
>>419
new Hage の動作を分解すると、

void* storage = operator new (sizeof(Hage));
try { new (storage) Hage; }
catch (...) { operator delete (storage); throw; }

こんな感じになってるわけよ。

421 :デフォルトの名無しさん:2006/12/23(土) 16:33:22
ぉぉ。そうなんですか。
あざーす

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

★スマホ版★ 掲示板に戻る 全部 前100 次100 最新50

read.cgi ver 05.04.02 2018/11/22 Walang Kapalit ★
FOX ★ DSO(Dynamic Shared Object)