C++相談室 part91
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
2011/09/13(火) 23:01:46.23ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレに
お願いします。
前スレ
C++相談室 part90
http://hibari.2ch.net/test/read.cgi/tech/1310885439/
このスレもよろしくね。
http://hibari.2ch.net/test/read.cgi/tech/1312621728/
ついでに壁紙にしてね。
http://www.research.att.com/~bs/Bjarne.jpg
0153デフォルトの名無しさん
2011/09/24(土) 23:45:50.29場合によりけりかなぁ
例えばprintfはエラーを返すけどその中のどこでエラーが起きたか……なんて気にしないでしょ。標準ライブラリでなくてもPOSIXやWin32でも。
どこで起きたかって情報を完全に不要にするのは難しいしそれが必要になることもあるけど、その情報が頻繁に必要になるのは関数が持つエラー通知のインターフェースの作りがよくないんだと思うよ
これはエラー処理にC++の例外を使用するかは関係ない
0154デフォルトの名無しさん
2011/09/25(日) 00:02:00.17どこで起きたかの情報を保持する例外投げればいいんじゃない?あなたはあほなの?
0155デフォルトの名無しさん
2011/09/25(日) 00:12:43.34組み込みやゲームとか処理がタイトなものならともかく、
普通使うだろ
0156デフォルトの名無しさん
2011/09/25(日) 00:25:38.820157デフォルトの名無しさん
2011/09/25(日) 00:28:49.56主張は理解できるが
GCが便利かといわれるとちょっとどうかなw
RTTIはテストやデバッグ実行時のときは便利だよね
それ以外ではコンパイラでoffにしてる
エラー発生位置もそうだけどRTTIつかいまくりの設計もどうにかしたほうがいいと思うぞ
便利なのはわかるけど普通不要だから
0158デフォルトの名無しさん
2011/09/25(日) 00:30:25.67if文の羅列とかもうやめたい
0159デフォルトの名無しさん
2011/09/25(日) 00:30:29.41サイズが増える
0160デフォルトの名無しさん
2011/09/25(日) 00:51:58.21組み込みの現場ぐらいでしか問題にならんだろ
0161デフォルトの名無しさん
2011/09/25(日) 00:55:55.89dynamic_castってRTTI使ってたっけ?
仮想関数テーブルで判定してるだけじゃない?
0162デフォルトの名無しさん
2011/09/25(日) 01:00:48.71使ってる
0163デフォルトの名無しさん
2011/09/25(日) 05:28:10.30結構複雑
0164デフォルトの名無しさん
2011/09/25(日) 08:33:42.66class IDrinkable {};
class IEquipment : public IItem {};
class Weapon : public IEquipment {};
class Armor : public IEquipment {};
class Potion : public IItem, public IDrinkable {};
std::list<shared_ptr<IItem>> items;
コンテナにつっ込まれた要素の、元の型を知りたい時に、IItem クラスは何を用意することがベストだろうか
1. 何も用意しない。dynamic_cast を使用する
2. virtual ItemType GetType() = 0
enum ItemType {
ItemType_Weapon, // Weapon クラスはこれを返す。
ItemType_Armor, // Armor クラスはこれを返す。
...
}
3. virtual Weapon * CastToWeapon() { return NULL; }
Weapon クラスはオーバーライドして、this を返す。
他の派生したクラスへキャストする関数も用意する。
4. その他
0165デフォルトの名無しさん
2011/09/25(日) 09:17:58.62そういう風に基底クラスのインタフェースを定義する。
0166デフォルトの名無しさん
2011/09/25(日) 09:46:25.09じゃないと何の為に派生してるのやら分からん
ただ、AにBの派生クラスを登録して、
Aの派生クラスからBの派生クラスを使う、
というような場合にはdynamic_castもやむを得ない場合もある
0167デフォルトの名無しさん
2011/09/25(日) 13:09:59.73メモリリーク周りのバグだけ残して、期限までに納品とかできるのにな
バックログは後々で修正してさ
0168デフォルトの名無しさん
2011/09/25(日) 15:59:41.980169デフォルトの名無しさん
2011/09/25(日) 16:08:32.660170デフォルトの名無しさん
2011/09/25(日) 18:53:08.88させる奴は殺害もの
0171デフォルトの名無しさん
2011/09/25(日) 19:02:43.66なんのために抽象化したリストに突っ込むかによるだろ。
ダウンキャスト的な動作が必要なら、少々とこばっても最初から
元の型を保持したリストを別途用意しとくほうがマシ。
そもそも抽象化したリストに投入する事は、元の型を捨てるという意味だから。
std::list<shared_ptr<Weapon>> weapons;
std::list<shared_ptr<Armor>> armors;
std::list<shared_ptr<IItem>> items;
Weapon weapon;
weapons.push_back(&weapon);
items.push_back(&weapon);
0172デフォルトの名無しさん
2011/09/25(日) 21:20:11.60無視してそのままアプリ実行したらまずいのかな
0173デフォルトの名無しさん
2011/09/25(日) 21:27:11.82flush()で失敗したら、書き出し先ドライブを変えるとかユーザーにリカバリーを選択させる。
closeで失敗したら、失敗したよってユーザーに通知することぐらいしかできないだろ。
あとは、ダンプを作成してどっかに吐き出しとくことぐらいか。
0174デフォルトの名無しさん
2011/09/25(日) 21:30:15.27そうはいってもメモリ管理はミスる時にはミスります。malloc()/free() となんらかわりません。
0175デフォルトの名無しさん
2011/09/25(日) 21:31:07.40フラッシュで失敗したばあいはいくらでも復旧可能
フラッシュで成功したばあいは直後のクローズで失敗しても特に実害は無いのでご自由に
というかんじか
フラッシュの使い道初めて知ったよとんくす
0176デフォルトの名無しさん
2011/09/25(日) 21:32:57.13そもそもコンストラクターでオブジェクトの作成なんてする必要があるか疑問だが。
配列を確保するならまだしもね。
0177デフォルトの名無しさん
2011/09/25(日) 22:00:40.25何が言いたいのかさっぱりわからない。
コンストラクタでオブジェクト作成しなかったら何するの?って感じなんだけど。
0178デフォルトの名無しさん
2011/09/25(日) 22:06:43.41基本的にはメンバー変数に実体を置くか、
外部のオブジェクトを参照するだけで十分な筈。
メモリー操作が必要となるのは、配列かAPIのリソースぐらいじゃん。
0179デフォルトの名無しさん
2011/09/25(日) 22:09:55.79新たに別のファイルを開き直して、もう一回出力とか。
0180デフォルトの名無しさん
2011/09/25(日) 23:02:56.12お前がそう思うんならそうなんだろう、お前ん中ではな(AA略
0181デフォルトの名無しさん
2011/09/25(日) 23:10:29.50もしかして誤字ではなく本気で open と言っているのか?
0182デフォルトの名無しさん
2011/09/25(日) 23:12:39.10まさか、クラスのメンバーにfstreamのポインター置いて、
クラス内で new と delete を繰り返してるとか?
それともfunctionクラスみたいに型をカプセル化する
オブジェクトを内包しててnewで生成してるとか?
前者は作りを見直すべきだし、後者は滅多に
つくるようなもんじゃないよな。
0183デフォルトの名無しさん
2011/09/25(日) 23:13:42.92誤爆か?
0184デフォルトの名無しさん
2011/09/25(日) 23:19:33.790185デフォルトの名無しさん
2011/09/25(日) 23:29:25.53「RAII の徹底が不十分な場合、コンストラクタの途中で例外が出てメモリリークする
ことがある」
ということを言いたかったんだと思うんだけど、合ってるかな?
0186デフォルトの名無しさん
2011/09/25(日) 23:37:28.34例外が発生すればメモリーリークになるわけじゃないけど、
ちゃんと例外発生時の例外処理を書いてないとメモリーリークになる。
RAIIはどうでもいいけど。いくら例外処理で対処できるとはいえ、
NULL初期化とかが必要になるコンストラクターのメモリ操作自体は減らすべき。
0187デフォルトの名無しさん
2011/09/25(日) 23:38:19.030188デフォルトの名無しさん
2011/09/25(日) 23:43:33.52class Type
{
Example *a,*b,*c;
public:
Type():a(0),b(0),c(0)
try
{
a = new Example();
b = new Example();
c = new Example();
}
catch(...)
{
delete a;
delete b;
delete c;
}
};
0189デフォルトの名無しさん
2011/09/25(日) 23:57:53.460190デフォルトの名無しさん
2011/09/25(日) 23:57:56.140191デフォルトの名無しさん
2011/09/25(日) 23:58:15.750192デフォルトの名無しさん
2011/09/26(月) 00:05:40.59なんでその文脈でRAIIを選択肢から外すんだよw
0193デフォルトの名無しさん
2011/09/26(月) 00:07:47.940194デフォルトの名無しさん
2011/09/26(月) 00:08:00.12その catch の中の a,b,c へのアクセスはすべて未定義動作。ミスとか関係ない。
0195デフォルトの名無しさん
2011/09/26(月) 00:10:11.320196デフォルトの名無しさん
2011/09/26(月) 00:13:14.36なんで未定義になるんだ?
0197デフォルトの名無しさん
2011/09/26(月) 00:13:43.22実体で割り当てたんじゃ要求を満たせないときに new するに決まってんだろ。
メンバの寿命とクラスの寿命がずれてるとか、途中で具象クラスを入れ替えるとか、
考えれば出てきそうなもんだ。
0198デフォルトの名無しさん
2011/09/26(月) 00:15:34.48え?
0199デフォルトの名無しさん
2011/09/26(月) 00:16:00.87http://blogs.wankuma.com/episteme/archive/2011/02/20/197105.aspx#197169
15.3 p10 でそう決められているから、らしい。
そんなのコンパイルエラーにしろよとは思う。
0200デフォルトの名無しさん
2011/09/26(月) 00:17:19.68メンバー割り当てるヤツがいるから書いたんだよ。
pimpとかは大事だけど、単にリソース開閉のためだけにメモリ操作するなんて無駄じゃん。
0201デフォルトの名無しさん
2011/09/26(月) 00:20:37.49そこ見ても解るけど問題起きるのは規格に準拠してないコンパイラだけでしょ。
0202デフォルトの名無しさん
2011/09/26(月) 00:21:09.41ああ >>188 よく見たら function try block になってる(?)のか。
コンストラクタ本体の中で try ... catch するぶんには問題ないよね。
0203デフォルトの名無しさん
2011/09/26(月) 00:23:20.69そこから「コンストラクタでnew」まで攻撃対象を辺に拡大するから話がおかしくなってる。
ふつうにその無駄を叩けよ。
0204デフォルトの名無しさん
2011/09/26(月) 00:27:23.900205デフォルトの名無しさん
2011/09/26(月) 00:28:21.20そうだけど、188が function try block のつもりじゃないとしたら、 throw; が抜けてる。
0206デフォルトの名無しさん
2011/09/26(月) 00:29:13.71これは : がないからfunction-try-blockじゃなくて普通にコンストラクタ内部のtryブロックだろ
{}を書き忘れただけじゃねーかな
0207デフォルトの名無しさん
2011/09/26(月) 00:29:31.45どこにそんなこと書いてあるの?
0208デフォルトの名無しさん
2011/09/26(月) 07:06:32.240209デフォルトの名無しさん
2011/09/26(月) 07:28:53.09メンバー関数が初期化された状態で、
例外処理に入るとは限らない。
的な事じゃ無いんだろうか。
0210デフォルトの名無しさん
2011/09/26(月) 12:33:45.410211デフォルトの名無しさん
2011/09/26(月) 13:24:29.55コンストラクタでfunction-try-blockを使ってるなら
function-try-block中で例外が発生した時点で構築済みの基底クラスやメンバ変数は破棄されて無効なオブジェクトになるので
その後のcatch節の中ではアクセスしてはいけない、ってこと。
ttp://codepad.org/6zad5CVy
0212デフォルトの名無しさん
2011/09/26(月) 14:12:37.120213デフォルトの名無しさん
2011/09/26(月) 15:14:06.620214デフォルトの名無しさん
2011/09/26(月) 21:18:22.73引数はどうなんの?やっぱり未定義かえ?
0215デフォルトの名無しさん
2011/09/26(月) 22:15:43.84class a{
operator a(); // これ作れちゃうんだ
};
0216デフォルトの名無しさん
2011/09/26(月) 22:30:59.94プールを渡してやったらファーストフィットやらベストフィットやらを
サクッと構築できるライブラリとかないかな。
0217デフォルトの名無しさん
2011/09/27(火) 00:07:08.50引数の寿命はfunction-try-blockのハンドラを抜けるまで延長される。だから引数にはアクセスできる。
ttp://codepad.org/0wwV4V4w
0218デフォルトの名無しさん
2011/09/27(火) 01:01:19.970219デフォルトの名無しさん
2011/09/27(火) 01:02:49.390220デフォルトの名無しさん
2011/09/27(火) 07:13:06.38規格上はやっぱりセーフなんだ。良かった。
0221デフォルトの名無しさん
2011/09/27(火) 07:36:18.86aにキャストしても呼ばれないし、
aの派生クラスbを作ってaに代入やキャストしても呼ばれないし、
operator aを直接呼ばないと呼ばれないっぽ
環境依存かもしれないけど
使い道はなさげ
0222デフォルトの名無しさん
2011/09/27(火) 08:19:27.190223デフォルトの名無しさん
2011/09/27(火) 09:24:53.290224デフォルトの名無しさん
2011/09/27(火) 09:48:59.65> 使わない方がいいという意見
どこ見たの?
0225デフォルトの名無しさん
2011/09/27(火) 11:42:28.770226デフォルトの名無しさん
2011/09/27(火) 12:17:30.45便利だし
0227デフォルトの名無しさん
2011/09/27(火) 13:01:40.640228デフォルトの名無しさん
2011/09/27(火) 13:06:09.17試しにググって見たら、「C++ 例外 使わない」 で12,400件でたぞ。意外と多い。w
おれは、半々だな、使う部分と使わない部分がある。
0229デフォルトの名無しさん
2011/09/27(火) 13:20:16.77構造としてのヒープじゃなくて領域としてのヒープか?
ファーストフィットだけならsimple segregated storageってのがあるからそれを実装したライブラリで領域を外から与えられるやつ探せばいいと思うよ
一応boostにもあるけど領域を外から与えられるかどうかはわからん
データ構造のほうならstd::make_heapで
0230デフォルトの名無しさん
2011/09/27(火) 18:50:38.32それを達成するには例外を利用する標準ライブラリを
例外の出ないタイプのものに置き換える必要があるから
正直そこまでやるのもどうかと思う
0231デフォルトの名無しさん
2011/09/27(火) 19:05:00.980232デフォルトの名無しさん
2011/09/27(火) 19:34:48.292. エラーが発生したときに落ちることを許可しない
1 && 2 であれば、例外を使用する
bool TryGetHoge(Hoge * pOutput) // Nothrow
const Hoge * GetHogeOrNull() // Nothrow
const Hoge & GetHogeOrThrow() // Hoge が取得できないばあいはスロー
const Hoge & GetHogeOrDie() // Hoge が取得できない → 死
0233デフォルトの名無しさん
2011/09/27(火) 19:42:16.44無駄にコストが掛かる、ってのはどういうこと?
C++は原則的に要求された機能を実現するのに必要なだけのコストしか掛けない。
プログラマが実際には使わない機能を含めて要求していたならその分無駄にコストが掛かるといえるけど
それは具体的な状況次第。
0234デフォルトの名無しさん
2011/09/27(火) 19:58:52.24関数の本体自体を生成してるわけじゃないんだし
0235デフォルトの名無しさん
2011/09/27(火) 20:02:51.220236デフォルトの名無しさん
2011/09/27(火) 20:05:16.85大した事ないよね
0237デフォルトの名無しさん
2011/09/27(火) 20:15:39.34例外が発生したところで、根っこでキャッチする限り落ちることはなくね?
それが良いわけでもないけどさ。
逆にエラー無視してたらまずくね?
いずれセグメントエラーでも起こして無断で死ぬでしょ。
0238デフォルトの名無しさん
2011/09/27(火) 20:17:09.460239デフォルトの名無しさん
2011/09/27(火) 20:21:25.77{
try { return Main(void); } catch(...) { Message("Fackin Error !!!"); return 1 ; }
}
0240デフォルトの名無しさん
2011/09/27(火) 21:34:14.780241デフォルトの名無しさん
2011/09/27(火) 21:40:07.15simple segregated storageかいいね。ありがとう。
0242デフォルトの名無しさん
2011/09/28(水) 19:33:43.190243デフォルトの名無しさん
2011/09/28(水) 19:36:12.710244デフォルトの名無しさん
2011/09/28(水) 19:57:25.790245デフォルトの名無しさん
2011/09/28(水) 20:08:28.29チムポも蒸れる
0246デフォルトの名無しさん
2011/09/28(水) 20:18:05.220247デフォルトの名無しさん
2011/09/28(水) 20:26:59.490248デフォルトの名無しさん
2011/09/28(水) 20:27:37.840249デフォルトの名無しさん
2011/09/28(水) 20:32:50.41初期化のコンスラクタを呼びたいだけじゃないのか?
それならるぞ。
0250デフォルトの名無しさん
2011/09/28(水) 20:42:54.84Type (*constractor)(int) = &Constractor<Type(int)>;
Type object = constractor(10);
0251デフォルトの名無しさん
2011/09/28(水) 20:45:30.980252デフォルトの名無しさん
2011/09/28(水) 20:52:11.40マルチすると一部の人はヘソを曲げて答えてくれなくなっちゃうぞ
■ このスレッドは過去ログ倉庫に格納されています