トップページ⇒tech
111コメント43KB

え、マジ?すげえ!

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさんNGNG
すっごい技術の話をしようぜ。
プログラム関連の話歓迎。
0002デフォルトの名無しさんNGNG
プログラム関連以外もOK?
0003デフォルトの名無しさんNGNG
                                     ▄▄▄██████▄
     ███▀     █████████      ▄▄▄▄█████▀▀  ████▀▀
    ███▀ ██  ███▀ ▄███▀        ▀▀▀▀      ███▀
   ██▀ ▄███▀███▄▄▄███                ▄▄▄█▀
 ▄███▄▄██▀ █▀  ▀████                  ▀██▄
 ▀▀▀▀███▄      ▄██▀█▄▄                 ███
    ██▀ ███   ██▀  ▀███▄▄              ███
  ▄████▀▀██ ▄█▀▄▄   ▀█████▄▄           ███
  ▀█▀▀  █▄▄█▀   ████▄  ▀███▀▀▀         ███
▄   ███ ▀███      ▀▀▀                  ███
███  ███  ▀▀                           ███
 ███  ▀        ▀████▄             ▄▄▄▄████
  ▀              ▀████             ▀█████
                                     ▀██▀


0004デフォルトの名無しさんNGNG
ズサー
0005デフォルトの名無しさんNGNG
すげぇ速攻終わってるよ
0006デフォルトの名無しさんNGNG
どのスレに書けばいいのかわからなかったので、この駄スレを使って、
C++でのイディオム実装の方法を考えさせてください。

いま俺が興味があるのは、More Effective C++ や Exceptional C++ に
書いてある「リソースの獲得は初期化」ってイディオムです。

CFile file;// not MFC 自作クラスのCFileです
if(file.Load("test.txt") == false) return ERROR;
string str = file.ReadOneLine();// 一行読み込み

みんなこんな感じのコードを書いてると思うんですけど。
「リソースの獲得は初期化」を実装すると、こうなるんじゃないかと。

if(CFile::IsExist("test.txt")) return ERROR;
CFile file("test.txt");
string str = file.ReadOneLine();// 一行読み込み

CFileはファイルを処理するクラスなんですから、CFileのインスタンスが
存在するときには、いつでもそのインスタンスでひとつのファイルを
処理できなくちゃいけないんじゃないかと。逆に言えば、いつでも処理できる
という状態を基準にして、インスタンスを生成しなければならないん
じゃないかと。そのためには、いつもコンストラクタでリソースを確保して、
デストラクタでリソースを解放して。Load,Read,Open,Closeなんて関数は
いっさい作らない(Reloadはアリだと思うけど)。
というのが、「リソースの獲得は初期化」ってイディオムを実装したスタイル
なんじゃないかと思うんですけど、どうでしょう?

「リソースの獲得は初期化」でグーグっても一件しか出てこないのは
どういうわけなんでしょ。みんなこんなことは考えてないんですか。
このイディオムを守ると、リソースリークが激減しそうな予感がするのは
俺だけなんですか。

なんか、何を聞きたいのかさっぱりわからない文章になってますけど、
とりあえずこのイディオムの実装の仕方とかを考えてる人と話したいんです…。
0007デフォルトの名無しさんNGNG
駄スレ駄スレ駄スレ駄スレ駄スレ駄スレ駄スレ駄スレ駄スレ
0008デフォルトの名無しさんNGNG
>>6
駄スレにレスるのもなんだが、オレなら例外にするかな。
try {
CFile file("foo.txt");
// 処理……
}
catch (FileNotFoundException& e) {
}
catch (FileIOException& e) {
}
File not found を例外と考えるかどうかは意見の分かれるところだが。
0009デフォルトの名無しさんNGNG
今からこのスレは、
「駄スレを速攻で終了させる方法を話し合うスレ part 1」
となりました。
0010 NGNG
駄スレ職人の俺から言わせてもらえば、
駄スレには上等な駄スレと駄目な駄スレがある。
このスレは駄目な駄スレだ。
0011デフォルトの名無しさんNGNG
>>10
漏れにも優良駄スレを作るコツを教えてくれ!
漏れ的に考えると
優良駄スレ=厨房隔離スレ
だろうか。
0012デフォルトの名無しさんNGNG
>>8
>駄スレにレスるのもなんだが
あー、やっぱC++相談室あたりのちゃんとしたスレで聞いた方が
良かったんですかね…。マルチポストって言われないように、
何を聞きたいのかをちゃんとまとめ直して投稿します。

>オレなら例外にするかな。
そうですね。CFileのコンストラクタは、どっちみち例外を
投げるしかないですから。関数の呼び出しの浅い部分では
IsExistでチェックしておいて、深い部分では例外に任せるのが
いいかもしれません。
0013デフォルトの名無しさんNGNG
>>12
確かに、C++相談室の方が良いと思われ。

>>11
長年の経験によると、優良駄スレは
・1に長文が書かれている。・その内容が、ツッコミ所満載。
・1が厨房。・1が常駐。・1が無知。・1が知ったかぶる。
・2ゲットされている。・ネタに付き合ってくれる住人が4人以上居る。
うえの条件を6つ以上満たしているのが、優良駄スレだと思われる。
0014デフォルトの名無しさんNGNG
優良駄スレ == ネタスレ?
0015デフォルトの名無しさんNGNG
駄スレにレスるのもなんだが
ここでレスするときは、ちゃんと最初に上記のフレーズを書き込むこと。
00161NGNG
ひどいありさまだな。
0017デフォルトの名無しさんNGNG
>1
ズゲエ ズゲエヨ オマエ
0018デフォルトの名無しさんNGNG
「プログラミング教えて」系スレでも 1 が真面目に勉強する気を見せている
場合優良スレになることがある。
そして俺も読んでこっそり勉強してたりする。いや、立てたことはないけどね。
0019デフォルトの名無しさんNGNG
アルカ?
0020デフォルトの名無しさんNGNG
>>19
ある。でも最近は無い。
0021デフォルトの名無しさんNGNG
>>20
どれよ?
0022デフォルトの名無しさんNGNG
>>12
コンストラクタの例外投げって、ありか?
おれとしては、あってはならないもののような気がする・・・
0023デフォルトの名無しさんNGNG
>>22
ぉぃぉぃ
0024デフォルトの名無しさんNGNG
>>22
ありです
0025デフォルトの名無しさんNGNG
>>22
デストラクタの勘違い?
0026 NGNG
何としても抱いてみたいと真剣にお考えの女優、アナウンサーを
5名以上7名人お聞かせください。(18歳以下タレント、東京以
外のタレント、アナは除く)
その中でご相談可能な名前があった場合のみお返事いたします。
場所は本州の県庁所在地から選んでください。
秘密を守るため即決で受け付けますので、問い合わせ後12時間
後以降18時間以内に返信チェック願います。
メールは下記アドレスあて女優名(5名以上)、希望都市、年令
をお送りください。返信ボタンは使わないでください。
記載、人数が欠けていた場合返信できない場合があります。
[email protected]
0027.NGNG
ahokusa
0028デフォルトの名無しさんNGNG
>>25
コンストラクタでもデストラクタでも例外投げって、別にかまわんでしょ?
0029デフォルトの名無しさんNGNG
デストラクタが例外投げたら死ぬときがある。
003030げっと-NGNG
                                     ▄▄▄██████▄
     ███▀     █████████      ▄▄▄▄█████▀▀  ████▀▀
    ███▀ ██  ███▀ ▄███▀        ▀▀▀▀      ███▀
   ██▀ ▄███▀███▄▄▄███                ▄▄▄█▀
 ▄███▄▄██▀ █▀  ▀████                  ▀██▄
 ▀▀▀▀███▄      ▄██▀█▄▄                 ███
    ██▀ ███   ██▀  ▀███▄▄              ███
  ▄████▀▀██ ▄█▀▄▄   ▀█████▄▄           ███
  ▀█▀▀  █▄▄█▀   ████▄  ▀███▀▀▀         ███
▄   ███ ▀███      ▀▀▀                  ███
███  ███  ▀▀                           ███
 ███  ▀        ▀████▄             ▄▄▄▄████
  ▀              ▀████             ▀█████
                                     ▀██▀




次は300だね?
003130げっと-NGNG
やべ、クッキー消えちゃった
0032デフォルトの名無しさんNGNG
え、最近の C++ ってコンストラクタで例外投げてもメモリリークになんないの?
↓こういうコードでコンストラクタが例外投げた場合の話よ?

Hoge *hoge = new Hoge();
0033デフォルトの名無しさんNGNG
俺は基本的に>>6のスタンスはありだと思う。
メンバ変数という概念がなくて、インスタンスは全てシングルトンで
必要になったその時に作る、必要なくなったら破棄、
こういう言語があったらどうだろう?難しいかな?
でも、どうもCFile::IsExistの存在に違和感を感じるかな。
そこまでやるなら、使用したい時に CFile file("test.txt") と
インスタンスを作る方がスマートのような気がする。
まあコンストラクタん中にIsExistを埋め込めばより良いだろうけど。
003433NGNG
意味不明だね、すまそ
0035 NGNG
>>32
ならない。
0036デフォルトの名無しさんNGNG
>>35
試したら本当だった。何時から仕様になったんだ?
0037デフォルトの名無しさんNGNG
昔からじゃないの?
0038デフォルトの名無しさんNGNG
>36
あ、本当だったってのはメモリリークを起こさなかったってことね。
下記コードで実行中のメモリ使用量変わらず (throw を抜くとすごい
勢いでメモリを消費する)。
_______________________________________________
// Cobalt Linux, gcc-c++-2.95.3-1c1r4, glibc-2.1.3-23
class A{
  char buffer[1024 * 1024];
public:
  A(){
    throw 100;
  }
};

int main(void){
  while(1){
    try{
      A *a = new A();
    } catch(int x){/* */}
  }
  return 0;
}

ちなみにメモリリークすると覚えたのは数年前の Turbo C++ 4 だったか
Visual C++ 4.0。
0039デフォルトの名無しさんNGNG
>>38
それは例外 以前の問題でしょ。
0040デフォルトの名無しさんNGNG
>38
deleteしてないから当然?
0041デフォルトの名無しさんNGNG
>>39-40
コンストラクタ内で例外を起こすと
インスタンスは生成されないのか?って実験だから
いいと思うけど。
004238NGNG
>>41
そういうこと。throw を抜いてメモリリークすることを確認したかったから
あえて delete は抜いたんだが、そこまで汲み取れなかったか。
0043デフォルトの名無しさんNGNG
>>38
throwする前にbufferにアクセスした場合どうなるの?

memset(buffer,sizeof(buffer));
throw 100;

とか。
一度スタックに取られる?
004443NGNG
>一度スタックに取られる?
んなわけないか・・
0045デフォルトの名無しさんNGNG
newは内部で以下のように動作している。
コンストラクタの時点でメモリは確保されているが、
例外を送出すると自動で解放されるようになっている。

operator new(size_t s)
{
 void* p = NULL;
 try {
  p = malloc(size);
  if (p == NULL)
   throw std::bad_alloc();
  ctor(p);
 }
 catch (...) {
  free(p);
  throw;
 }
}

004643NGNG
>>45
ああ、そういうわけですか。
判りやすい説明どうもです。
0047 NGNG
>>45
コンストラクタで例外出さないってのは常識だと思ってたんだがな。
今はそうなってるんだ。俺の覚えている範囲では、C++ がまだ ANSI
ドラフトだった頃の実装は軒並みリークしてたな。
0048デフォルトの名無しさんNGNG
バカばっかり・・・
> コンストラクタで例外出さないってのは常識だと思ってたんだがな。
意味を理解しないで憶えてるから、「思ってたんだがな。」なんて
情けないことを言う羽目になる。
0049デフォルトの名無しさんNGNG
JMP $-2
0050デフォルトの名無しさんNGNG
>>48
ハハハ、まるでnewの実装まで知らなければ
例外を使ってはいけないような口ぶりですな。
それは違うのでは?
0051デフォルトの名無しさんNGNG
>>50
それリダイレクト先間違ってる。
>>48じゃなく>>47がふさわしい。
0052デフォルトの名無しさんNGNG
>>50
newの実装を知らなければ、コンストラクタから安心して例外を出せないと思うが。
リークしないのは仕様だし、リークする処理系はバグ持ちと言うことなんだから。
勝手な思いこみでリークするとか言ってるんか、使っちゃだめだろ。
0053デフォルトの名無しさんNGNG
ぐぐるでヒットしたやつ適当に。
http://www.microsoft.com/japan/developer/library/vccore/_core_exceptions.3a_.exceptions_in_constructors.htm
http://www.cmagazine.jp/src/kinjite/cpp/exception.html
リークするしないは処理系によると思うので
どちらも正しいと言えるのでは?
0054デフォルトの名無しさんNGNG
> 意味を理解しないで憶えてるから、「思ってたんだがな。」なんて
しったか莫迦 ハケーン!
おまえ ANSI の仕様と処理系の仕様を理解しないで覚えてるだろ。
ANSI のどこにそんな「仕様」があるんだ?
0055デフォルトの名無しさんNGNG
>>53
そこで言うリークは、クラス内でnewしたオブジェクトの話であって、また別の次元の話。

newされたオブジェクトがコンストラクタ内で例外を送出したときは、
そのオブジェクトに割り当てられたメモリは解放されます。
0056デフォルトの名無しさんNGNG
Visual C++ 6.0 (MSDN) - new 演算子
> 余分な引数を付けずに operator new を使用し、/GX、/EHs、または /EHa オプションで
> コンパイルすると、コンストラクタが例外をスローしたときに operator delete を呼び
> 出すコードが生成されます。

なので VC で delete が呼び出されるかどうかはコンパイルオプションに依存。
つまりコンストラクタの例外でメモリ開放を期待する設計は処理系/環境依存の
プログラムになる。
ちなみにこんな記述もある。

> 仮引数付きの new 演算子、つまり割り当てサイズ以外の引数を伴う形式の
> new 演算子を使用すると、コンストラクタが例外をスローしたときに、
> 仮引数付きの delete 演算子が呼び出されません。
005753NGNG
>>55
つーかそれMFC例外のページですた。すまそ。
0058デフォルトの名無しさんNGNG
>>55
上 URL の第二パラグラフをよく読め。オブジェクト自身に割り当てられたメモリの話だ。
0059デフォルトの名無しさんNGNG
コンストラクタ例外のメモリリークに関して二つの話が交錯しています。

コンストラクタ内で例外が発生した場合:
 1. そのオブジェクト自身の領域が解放されるのは (言語仕様 | 処理系依存)
 2. (その未完成オブジェクトに対して) デストラクタが呼び出されるのは (言語使用 | 処理系依存)

※2 はコンストラクタ内で別オブジェクトを作成してメンバに格納し、デストラクタで
  開放するクラスを想定している。デストラクタが呼び出されないと例外発生前に確保
  したオブジェクトが開放されないという意味。

>>53, >>56 を見る限りどちらも処理系依存っぽい。
0060デフォルトの名無しさんNGNG
15.2 except.ctor
>If the object or array was allocated in a newexpression and the newexpression does not contain a newplacement, the deallocation function (3.7.3.2, 12.5) is called to free the storage occupied by the object;
placement-newで確保されてないオブジェクトは自動で解放されるとある。
>>56は環境依存じゃなくてVC依存の問題。
0061デフォルトの名無しさんNGNG
1 言語仕様
2 仕様違反

class A{
 string s;
 char* p;
public:
 A() {
  p = new char[256];
  s = "string";
  throw;
 }
 ~A()
 {
  delete[]p;
 }
};
A* pa = new A();


すべての処理は正しく終了する物とする。
この場合、A::sはオブジェクトの作成に成功しているので、
・コンストラクタで例外が呼ばれてもA::sのデストラクタは呼ばれる。
・例外が送出されているので、paは解放される。
・デストラクタが呼び出されていないので、A::pはリークする。
0062デフォルトの名無しさんNGNG
15.2 except.ctor
> オブジェクトか配列がnewexpressionの中で割り付けられ、newexpressionが
> newplacementを含んでいない場合、deallocation関数(3.7.3.2、12.5)は
> オブジェクトによって占められた記憶装置を解放するために呼ばれます;

newplacement って何のことだろう? これはどこからの引用?
0063デフォルトの名無しさんNGNG
newplacementは
placement-newと呼ばれている物。
たとえば、
char buf[sizeof(Obj)];
new(buf) Obj();
こんな感じで好きなようにオブジェクトの生成位置をコントロールできる物。

引用源はISOの規格書
0064デフォルトの名無しさんNGNG
>>63
うはっ、しばらく触らんうちに C++ が進化しとる (;´Д`)

今まで出た話としては:

・言語規格としてオブジェクト自身の領域は解放されなければいけないが、
  (数年前クラスの) 古いコンパイラの幾つかは未対応のものもある。
・コンストラクタ内で例外が発生した場合、デストラクタが呼び出されるか
  (呼び出されるようにコンパイルできるか) は処理系依存。

ってことですか。
0065デフォルトの名無しさんNGNG
ツーか、良スレに進化したので age とく
0066デフォルトの名無しさんNGNG
駄スレ駄スレ駄スレ〜、駄スレ〜を〜立て〜ると〜
お馬鹿お馬鹿お馬鹿〜、お馬鹿〜に〜なる〜のさ〜
0067デフォルトの名無しさんNGNG
>・コンストラクタ内で例外が発生した場合、デストラクタが呼び出されるか
>  (呼び出されるようにコンパイルできるか) は処理系依存。

だから、デストラクタが呼び出されるのは仕様違反だって言ってるんだよ。
デストラクタが呼び出される要件はただ一つ。
オブジェクトが正しく生成されていると言うことだけ。
コンストラクタが例外を出したらオブジェクトは無かったことになるので
呼び出されるはずがない。

placement-newでメモリが解放されないのは、
newがメモリを確保するのではなくすでにメモリの存在している領域にオブジェクトを作るから。

オーバーロードで定義された引数付きnew
ex. void* operator new(size_t s, int)
で割り当てられたオブジェクト例外を出した場合は、対応する引数付きdelete
ex. void operator delete(void* p, int)
が呼び出される。
また、この引数付きoperator deleteは能動的に呼び出すことは出来ない。
0068デフォルトの名無しさんNGNG
>>67
わりい。処理系依存ってのはコンパイラがオプションによって
スイッチする機能を持ってるかどうかという意味。
0069デフォルトの名無しさんNGNG
だから下の項目は↓の方が正しいな。

・コンストラクタ内で例外が発生した場合、未完全なオブジェクトに対して
  デストラクタを呼び出すようなコンパイルオプションを持ったコンパイラ
  もある。
0070デフォルトの名無しさんNGNG
>>68
そんなことを言い出したら、すべてが実装依存って事になるぞ。
0071デフォルトの名無しさんNGNG
いままでの流れをみると、コンストラクタから外へ例外を投げてもC++の仕様ではOKで
そのオブジェクトが未完成のまま放置されたりはせず、必ず解放されると
受け取れるんだけど、この部分で処理系での違いはないと認識して良いの?
0072デフォルトの名無しさんNGNG
それに加えて、たまに規格違反の腐った処理系がある罠。ってとこかも。
0073デフォルトの名無しさんNGNG
物凄く気になることがあるんですが、
newした親objectの中でさらにnewした子objectがあったら、
コンストラクタ内で子をnewで生成した後に親objectで例外送出したら、
子objectは開放されないということですか?
007448NGNG
そろそろ解ってきたようなので、結論を書いてやる。
コンストラクタで例外を送出すれば、デストラクタは呼ばれず、メモリリークの元になる。
コンパイラのオプションだ何だと、まだバカが居るが、こんなの常識だよ。
0075デフォルトの名無しさんNGNG
>>73
そのとおり
しかし、例外が子オブジェクトのコンストラクタから送出されたのなら、リークは起こらない。
また、このためのstd::auto_ptrだったり、他のスマートポインタだったりが用意されている(言い過ぎかも
007648NGNG
>>75
子オブジェクトのデストラクタは呼ばれないぞ。
007748NGNG
ついで教えてやるが、コンパイルオプションの話は、newに対するdeleteの話だ。
デストラクタの話と混同するな。
0078デフォルトの名無しさんNGNG
>>76
は?関係ないじゃん。

class A{
public A() { throw; }
};

class B
{
 A* a;
public
 B() : a(new A) { }
}

B* b = new B();

この場合は、B::AもB自身もリークしないと言うだけ。
007948NGNG
>>78
つき合うのに疲れた。
Aについて、自分でよく考えろ。
0080デフォルトの名無しさんNGNG
>>79
偉そうな割に頭悪いな。

#include <iostream>

class A
{
public:
 A() { throw 0; }
 void* operator new(size_t s)
 {
  std::cout << "A::new" << std::endl;
  return ::operator new(s);
 }
 void operator delete(void* p)
 {
  std::cout << "A::delete" << std::endl;
  ::operator delete(p);
 }
};

class B
{
 A* a;
public:
 B() : a(new A()) { }
 void* operator new(size_t s)
 {
  std::cout << "B::new" << std::endl;
  return ::operator new(s);
 }
 void operator delete(void* p)
 {
  std::cout << "B::delete" << std::endl;
  ::operator delete(p);
 }
};

main()
{
 try {
  B* b = new B();
 }
 catch (...) {
 }
}


実行結果
B::new
A::new
A::delete
B::delete

0081デフォルトの名無しさんNGNG
頭悪そうだから、解説してやるが

>例外が子オブジェクトのコンストラクタから送出されたのなら、リークは起こらない。
子オブジェクトの生成に失敗したのだから、
自動でメモリは回収されてデストラクタ云々は全く無関係の話。
子オブジェクトからの例外を適切に処理出来なかったんだから、
親オブジェクトも生成失敗となり、こちらも回収されて一件落着。
0082デフォルトの名無しさんNGNG
48 って頭悪そう。
008348NGNG
>>81-82
自作自演やめれ。ほとんどの人間は、もう理解できた。
>>73 の質問を、自分で考えろ。
お前の教育係じゃないんだから、理解させてやる義理はない。
0084デフォルトの名無しさんNGNG
そう言われると、何かあるんじゃないかと思って
>>73をまた読み直してしまう罠。
>>48、あんた質問を読み違えて勘違いしてるんじゃない?
0085デフォルトの名無しさんNGNG
それについての答えは>>75ですでに出ている。
0086デフォルトの名無しさんNGNG
アフォばっか!キャハ☆
008748NGNG
>>84
自分で考えろと言っただろ。
説明はこれで最後だぞ、二度とないからな。
これだけ説明してわからんバカに、これ以上つき合ってられん。

親はダメで、子は大丈夫なんて、ナンセンスだろ。
オブジェクトは、親用とか子用ってのがあるのか?
子のコンストラクタでnew使ってたら、子のデストラクタが必要だろ。
008848NGNG
自分がバカと理解してないバカはやっかいだ・・・
もう2度と、お前の相手はしないからな。
0089デフォルトの名無しさんNGNG
48は逃亡しますた。
0090デフォルトの名無しさんNGNG
>>87
子のデストラクタが必要だとしても、子のコンストラクタ内でnewに
失敗したら呼び出されないのでは・・・・・・
0091デフォルトの名無しさんNGNG
>>88
>自作自演やめれ。ほとんどの人間は、もう理解できた。
>自分がバカと理解してないバカはやっかいだ・・・

0092デフォルトの名無しさんNGNG
>>90
48は80のソースの読み方を知らないか、
実行結果が理解できないのです。
0093デフォルトの名無しさんNGNG
以前ならこの手の話も、すんなり理解されたんですが。シミジミ ガメコレ言
語の悪影響でしょうかねぇ。
0094デフォルトの名無しさんNGNG
まだ初心者で、昨日このスレ見て、僕も疑問なんで、見に来ました。
理解できました!!!
>>90 でも、1つ目newが成功して、2つ目のnewが失敗しての場合、必要だと思います。
ていうか、常にデストラクタは必要だと思います!!
0095デフォルトの名無しさんNGNG
>>94
そりゃそうだ罠。
0096デフォルトの名無しさんNGNG
>>93
ガメコレってあんた・・・・ワラタよ
0097デフォルトの名無しさんNGNG
>>94
別にデストラクタでなくてもいい。
確保した領域を確実に開放出来る機構を設ければいいだけ。
コンストラクタの中で確保したのならば、
コンストラクタの中のcatch{}の中で解放してやればいい。
0098デフォルトの名無しさんNGNG
>>94
一つ目のnewが成功して、二つ目のnewが失敗した時に例外が
投げられたら、デストラクタは呼び出されません。よって
>>97さんのような機構は不可欠。
0099デフォルトの名無しさんNGNG
1人だけ理解できない可哀想な人が、未だに自作自演を繰り返していますね。書き
込んだ時刻や文体から、バレバレですが。初心者の方が誤解されると困るので、中
身のないプライドは捨てて、少し勉強をやり直すことをお勧めします。それでも理
解できないのなら、可哀想ですがプログラマになるのはあきらめた方が、貴方のた
めにもよろしいと思います。

>>97
コンストラクタでcatchするのは、誰も問題にしてませんよ。何度も貴方が書いて
きたソースのように、コンストラクタから外へthrowするのが問題なのです。
0100デフォルトの名無しさんNGNG
>>99
俺も試してみたがやはりリークは起こらないが。
いったい何が駄目なん?

#include <crtdbg.h>
class a
{
int b[0xffff];
public :
a(){throw 0;};
};

int main(int argc, char* argv[])
{
try{
a* pa = new a;
delete pa;
}
catch(...){
}
_CrtDumpMemoryLeaks();
return 0;
}
0101デフォルトの名無しさんNGNG
良スレage
0102デフォルトの名無しさんNGNG
これだとさすがにリークしない?

#include <iostream>
using namespace std;

class Test {
int *i;
void except_func() throw(int) { throw 0; }
public:
Test() throw(int) { i = new int; except_func(); }
~Test() { delete i; }
};

int main()
{
try {
Test t;
}
catch (int) {
cout << "exception thrown." << endl;
}
}
0103デフォルトの名無しさんNGNG

    低 学 歴 が 混 ざ っ て い る よ う で す
0104デフォルトの名無しさんNGNG
もう少し、優しく教えてあげれば?初心者の頃は、みんなこういう話でなやんだでしょう?
コンストラクタで、10個の異なるオブジェクトを、順番にnewでつくる場合の、エラー処理を記述してみればわかりやすいと思う。
0105デフォルトの名無しさんNGNG
コンストラクタ内で例外を起こすと、デストラクタが呼び出されません。
つまり、コンストラクタ内で、例外を起こす前に確保したオブジェクトは、
解放する手段がないために、メモリリークを起こします。
(コンストラクタ内で例外をcatchしてオブジェクトを解放してやれば済むけど)

これで分からない初心者はコンストラクタで例外を起こさなければよし!
0106デフォルトの名無しさんNGNG
>>105
ホッ、よかった。合ってたみたい。サンクス。
0107デフォルトの名無しさんNGNG
>>105
何当たり前な事言ってるの?
生成に「成功」したオブジェクトがリークするというのは>>75の時点でガイシュツでしょ
子オブジェクトも生成に失敗した場合は、リークが起こらないって話じゃなかったの?

で、成功したオブジェクトがある場合、リークして困るなら
生ポインタじゃなくてauto_ptrにすれば成功した分も自動で解放される、と。
0108デフォルトの名無しさんNGNG
>>107
そう、それでいいよ。
で、君は何が不満なの?
その解で満場一致じゃん。
0109デフォルトの名無しさんNGNG
48だけが理解できてないってことでOK?
0110デフォルトの名無しさんNGNG
105=108?
48だと思ってたんだが、冷静に見ると口調が丁寧だ。
スマソ
0111デフォルトの名無しさんNGNG
>>48 は真性
■ このスレッドは過去ログ倉庫に格納されています