[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 2chのread.cgiへ]
Update time : 05/09 11:06 / Filesize : 125 KB / Number-of Response : 558
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

ぱっと見て「ヘタだなぁ」と思うコード その5



1 名前:デフォルトの名無しさん [2006/08/12(土) 01:56:11 ]
禁止ネタ(超既出)
・長い関数
・深いネスト
・グローバル変数
・goto
・memset
・malloc - free
・局所ブロック
・サンプルコードのtypo
・記述スタイル
・関数・変数名

過去スレ
その4: pc8.2ch.net/test/read.cgi/tech/1153312202/
その3: pc8.2ch.net/test/read.cgi/tech/1149986051/
その2: pc8.2ch.net/test/read.cgi/tech/1142741989/
初代 : pc8.2ch.net/test/read.cgi/tech/1141867015/


207 名前:デフォルトの名無しさん mailto:sage [2006/08/31(木) 22:39:56 ]
>>206
おお!trycatchの適切な利用方法を説明してみてくれ。
なんかパっとしねぇの多いんだ。

208 名前:デフォルトの名無しさん mailto:sage [2006/08/31(木) 23:30:19 ]
>>202
rethrow する前にログったり BarException 固有の処理するけど
紙面の都合で省かれてるんだと思うことにしよう。

> 多胎
派生例外クラスにありとあらゆるケースの例外処理が書かれて
かえって可読性が下がる気がしなくもない。

209 名前:デフォルトの名無しさん mailto:sage [2006/09/01(金) 00:23:55 ]
当然のことだが、例外クラスはそれを使うクラスのことは知らない。
まさか、1クラスにつき1例外作るとか言うんじゃないだろうな。

210 名前:デフォルトの名無しさん mailto:sage [2006/09/01(金) 00:34:41 ]
そう。だから例外処理で多態は困難に感じる。

211 名前:デフォルトの名無しさん mailto:sage [2006/09/01(金) 00:40:22 ]
ここで「こいつ下手そう」発言君↓

212 名前:デフォルトの名無しさん mailto:sage [2006/09/01(金) 00:42:04 ]
>>211
こいつ下手そう

213 名前:デフォルトの名無しさん mailto:sage [2006/09/01(金) 00:45:06 ]
>>207
try {
resA->open(); // res: resource
resB->open();
resA->hoge();
resB->fuga();
resB->close();
resA->close();
}
catch () {
}

214 名前:デフォルトの名無しさん mailto:sage [2006/09/01(金) 00:48:58 ]
んなーこたーない

215 名前:213 mailto:sage [2006/09/01(金) 00:52:06 ]
>>214
ん、俺?
俺いつもこうやってるよ。俺下手なのか?



216 名前:デフォルトの名無しさん mailto:sage [2006/09/01(金) 00:52:40 ]
ここでもやっぱり「こいつ下手そう」発言君↓

217 名前:デフォルトの名無しさん mailto:sage [2006/09/01(金) 00:53:34 ]
どう考えても213はおかしいだろ

218 名前:デフォルトの名無しさん mailto:sage [2006/09/01(金) 00:53:42 ]
>>213
見るからに例外安全じゃないコードだな。
close前に例外飛んだらout

もしRAIIだから大丈夫だとしたら逆にcloseを明示的に書いているのがダサい。

219 名前:213 mailto:sage [2006/09/01(金) 00:54:12 ]
>>217
どこが?

220 名前:213 mailto:sage [2006/09/01(金) 00:55:14 ]
>>218
あー、俺やっぱり下手だわ。
意味さっぱりわかんね。

221 名前:デフォルトの名無しさん mailto:sage [2006/09/01(金) 00:56:35 ]
>>218
エラーコードでいちいちエラーチェックするより、例外使ったほうがいいという例じゃないの?

222 名前:デフォルトの名無しさん mailto:sage [2006/09/01(金) 01:00:20 ]
>208-210
派生例外クラスじゃなくて、handleException を多態にするという意味では?

void handleException ( Exception& e ); // 共通の処理
void handleException ( BarException& e ); // BarExceptionだけの処理

try{
 //FooException,BarException,BazExceptionが発生する可能性あり
}
catch( Exception e ){
 handleException( e );
}

223 名前:デフォルトの名無しさん mailto:sage [2006/09/01(金) 01:07:01 ]
>>221
エラーチェックの話なら,
例外版は適切にRAIIとかfinally相当でリソースの後始末をするべき。
これだと例外を使うとリソースをリークするという話にしか見えん。

まともに例外を扱えないやつが例外を書くと危険極まりない。
下手糞の例外は下手糞のgotoよりはるかに凶悪

224 名前:デフォルトの名無しさん mailto:sage [2006/09/01(金) 01:07:31 ]
>>220-221
resA の open に成功して、resB の open に成功した場合、
resA のリソースが開放されないので例外安全にならない。
スコープ抜けたら勝手に開放される(RAII)のであれば
わざわざ close 呼んでるのが冗長。

225 名前:デフォルトの名無しさん mailto:sage [2006/09/01(金) 01:11:43 ]
>下手糞の例外は下手糞のgotoよりはるかに凶悪

まったくもってごもっとも。
つーか正直なところどんだけやってもC++の例外を使いこなす自信が持てん。



226 名前:デフォルトの名無しさん mailto:sage [2006/09/01(金) 01:11:45 ]
>>224
たぶん主張内容から推察するに
× resBのopenに成功
○ resBのopenに失敗
だな。
主張内容は完全に同意。

227 名前:デフォルトの名無しさん mailto:sage [2006/09/01(金) 01:16:58 ]
>>222
実際にやってみたか?引数のオーバロードは多態ではないから
e が BarException でも共通の処理のほうに飛ぶんだが。

228 名前:デフォルトの名無しさん mailto:sage [2006/09/01(金) 01:17:16 ]
>>222
オブジェクト自身が振る舞いを知ってる場合が多態で
入り口(呼び出し側)でオーバーロード用意して
振り分けしちゃうのは多態とは言わないと思ってました。
実際のところどうなんでしょう?

>>226
ご指摘の通り。しかも223氏が本質的な発言先にしちゃってるし。
もう俺寝た方が良さそう。

229 名前:デフォルトの名無しさん mailto:sage [2006/09/01(金) 01:23:53 ]
>>228
お休み、よい夢をー。

230 名前:213 mailto:sage [2006/09/01(金) 03:26:07 ]
あー、それは当然catch内でやる。213はtry{}の例。

231 名前:デフォルトの名無しさん mailto:sage [2006/09/01(金) 03:41:27 ]
catch内でリソースの開放処理をするのも上手くない。
その時点でcloseなどの解体処理が正常時と異常時の二箇所に分散するということが確定するから。
エラー処理を一箇所でやるための例外でその処理が分散したら本末転倒。
そんなんするならgotoでエラー処理するほうが開放処理が一箇所にまとまる分マシとさえ言える。

結局資源開放するならC++ならRAIIが定石(他言語ならfinally)

232 名前:231 mailto:sage [2006/09/01(金) 03:54:18 ]
あと、resB->open()時に発生した例外と
hoge(),huga()で発生した例外で開放するリソースが変わるからさらに面倒だな。
open時だとresAのみ、それ以外だとresA,resBを開放する必要がある。
こんなのを手動で開放処理書いてたら俺は間違いなくどこかでミスる自信がある。

233 名前:デフォルトの名無しさん mailto:sage [2006/09/01(金) 03:58:32 ]
> 間違いなくどこかでミスる自信がある
うん、間違いなくミスってるよw
resA->open()時に例外が発生する事象を見逃してる。
このケースだと資源の解放はいらない。

234 名前:231 mailto:sage [2006/09/01(金) 04:02:32 ]
うへぇ、本当だ。やっぱりミスってたかー...
うーん、こういう解体処理はRAIIに任せなきゃ駄目だなマジで

235 名前:デフォルトの名無しさん mailto:sage [2006/09/01(金) 04:03:46 ]
つまり例外は使うなってことでFA?



236 名前:デフォルトの名無しさん mailto:sage [2006/09/01(金) 04:05:09 ]
>>231
例外が有効な例を教えてくれ

237 名前:デフォルトの名無しさん mailto:sage [2006/09/01(金) 04:07:57 ]
こっちで。

例外処理
pc8.2ch.net/test/read.cgi/tech/1142667446/

238 名前:231 mailto:sage [2006/09/01(金) 04:12:41 ]
>>236 >>213のケースをRAIIで書くと有効な例になるんじゃね?
try {
    Resource resA(a->getResource());
    Resource resB(b->getResource()); 
    resA->hoge();
    resB->fuga();
}catch(){
  /* エラー処理を記述 */
}

どこにも開放処理はいらないし俺がミスる心配もない

239 名前:デフォルトの名無しさん mailto:sage [2006/09/01(金) 06:58:19 ]
ミスる心配が無いって気分いいよな

240 名前:デフォルトの名無しさん mailto:sage [2006/09/01(金) 07:11:51 ]
>>238
それだと、resA, resBに特化したエラー処理が書けないよ

241 名前:デフォルトの名無しさん mailto:sage [2006/09/01(金) 07:57:56 ]
COMでIDispatchとか使わされる状態だと例外ないとやってらんね

242 名前:デフォルトの名無しさん mailto:sage [2006/09/01(金) 08:53:43 ]
エラー処理は ResA.hoge()、ResB.hoge() の返り値を
switch-case なり if なりで判定して行う。
エラー処理と例外処理は別のものだよ。

243 名前:デフォルトの名無しさん mailto:sage [2006/09/01(金) 10:41:22 ]
>227
まぁ、>222のとおりだとそうなるけど。

catch(BarException e) を同様に作ってやればいいだけの話。

try{
 //throws FooException,BarException,BazException
}
catch( BarException be ){
 handleException( be );
}
catch( Exception e ){
 handleException( e );
}


244 名前:デフォルトの名無しさん mailto:sage [2006/09/01(金) 11:37:27 ]
以降、例外関連はこっちで。

例外処理
pc8.2ch.net/test/read.cgi/tech/1142667446/

245 名前:デフォルトの名無しさん mailto:sage [2006/09/01(金) 13:07:27 ]
これJavaの話?



246 名前:デフォルトの名無しさん mailto:sage [2006/09/01(金) 22:39:05 ]
>>240
try {
  Resource resA(a->getResource());
  Resource resB(b->getResource());
  try {
    resA->hoge();
  } catch(){
    // resA に特化したエラー処理
    // 処理を途中で止めるなら throw
  }
  try {
    resB->fuga();
  } catch(){
    // resB に特化したエラー処理
  }
}catch(){
/* エラー処理を記述 */
}

>>242
> エラー処理と例外処理は別のものだよ。

はぁ?

247 名前:デフォルトの名無しさん mailto:sage [2006/09/01(金) 23:11:38 ]
はぁ?

248 名前:デフォルトの名無しさん mailto:sage [2006/09/02(土) 01:35:16 ]
エラー処理と例外処理は別のものだろ。
それは間違いない。例外=エラーじゃない。
ファイルストリームの中でバッファ溢れを検知して例外投げて
捕まえた奴がフラッシュしてバッファ空にして処理続行、
別に変わった使い方じゃないし、どこにもエラーは無い。

249 名前:デフォルトの名無しさん mailto:sage [2006/09/02(土) 05:35:40 ]
はじめてtry-cacheがあって本当に良かったと思ったのはつい最近。
javascriptでregexpを評価する時に
食わせる正規表現が不完全な時に出るエラーメッセージをcacheして潰した時。

つーのも、無計画に追加していった自分用リンク集がいい加減肥大化して
目的のもの見つけるのが面倒くさくなってきたんで
regexpインクリメンタルサーチを搭載してみたんだけど
入力途中の、正しい正規表現かどうかかわからん文字列を
本当に正規表現として正しいのかどうか調べてから食わせるより
とりあえず食わせてみた後にエラー潰したほうが遥かに楽だったという話

250 名前:デフォルトの名無しさん mailto:sage [2006/09/02(土) 06:39:17 ]
>>249敢えて何も言うまい(´・ω・`)

251 名前:デフォルトの名無しさん mailto:sage [2006/09/02(土) 10:38:15 ]
>>249
2回間違えるあたり単なるスペルミスではなさそうだな。

252 名前:デフォルトの名無しさん mailto:sage [2006/09/02(土) 12:53:01 ]
キャッシュ?

253 名前:デフォルトの名無しさん [2006/09/02(土) 13:26:45 ]
「おまえらのコードは俺が理解できないから汚い。俺のコードは俺が理解しやすいから美しい。」
もう結論出てますよ。いつまで無意味な論争やっているんですか?

254 名前:デフォルトの名無しさん mailto:sage [2006/09/02(土) 14:18:02 ]
>ぱっと見て「ヘタだなぁ」と思うコード
>>248

255 名前:デフォルトの名無しさん mailto:sage [2006/09/02(土) 14:50:25 ]
>>249
正しい正規表現かどうか調べるのと
正規表現をビルドしてみるのとコスト変わらないのかな

文字列が正しい正規表現かどうか調べるメソッドが存在する処理系ってある?




256 名前:デフォルトの名無しさん mailto:sage [2006/09/02(土) 17:16:03 ]
正規表現オブジェクト内部で
処理する前に正しいかどうか調べてんじゃない?
バッファオーバーフローとかしたら致命的だし
ホットなループ内でエラーチェックするのはコストが高すぎる

257 名前:デフォルトの名無しさん mailto:sage [2006/09/02(土) 20:33:26 ]
ふつーの正規表現ライブラリなら構文食わせた段階でコンパイルされる。

まあたとえば空文字列にマッチしてしまうような正規表現はエラーではないが、
そういう用途には向いていないので実際のデータを食わせる前に判定した方がいいけどな

258 名前:デフォルトの名無しさん mailto:sage [2006/09/02(土) 20:46:47 ]
> 文字列が正しい正規表現かどうか調べるメソッドが存在する処理系ってある?

文字列が正規表現として正しいかを判定する正規表現を書けばいいんじゃないか?

259 名前:デフォルトの名無しさん mailto:sage [2006/09/02(土) 21:40:27 ]
正規表現ライブラリ内でパターンをコンパイルする時に
構文解析やってるはずなのに
その結果を返すメソッドが用意されてないからって
わざわざ自作するのは人間のコストが高すぎる。
とりあえずコンパイルして例外キャッチしてで十分に思う。
使用できる表現を限定する必要があるなら
頑張って自作するっきゃないだろうけど。

260 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 01:23:00 ]
>>249が「例外があって良かった」の例になっていない件について

は、もう突っ込み入ってるのか

261 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 01:34:44 ]
例外が便利なのは
・複雑なエラー状態を統一的に扱える
・複雑な呼び出し構造や一時変数の破棄をを自動的に処理できる
の2点なんだけど、
後者はデストラクタがきっちり定義された型の変数だけでコードを書いてないとあまり意味がない。
前者は誰がどう見ても便利。固定した構文があるだけでもぜんぜん違う。


まあ今時の言語なら実行時エラーを捕獲する機構は必須だわな。
プログラムが自分や他のモジュールについてのメタ情報を扱うのが最近の流行だ。

262 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 02:41:23 ]
javascript のクロスブラウザ対応コードとかだと
最初にバージョン等で依存するメソッドなりプロパティなり参照させて
そいつをcatchして「これはECMA1.1だ。あっちはJScriptだな」
とかやっててため息が出る。
コード書いた奴のせいではないけど。

263 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 03:30:47 ]
それは確かに
(スクリプトホストの実装が)ヘタだなぁ

264 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 08:59:17 ]
>>261
> 例外が便利なのは

・正常系の処理が素直に書ける

ことに尽きると思う。

例外がないと、エラーチェックだらけで処理が追いにくい。

>>262
ため息をつくほどのことか? >>261 が言うように処理系がメタ情報を
提供するのが最近の流行だろうけど、ちょっと古い実装系だと提供す
る関数自体が未実装だったりするので過渡期のテクとしてはやむをえ
ないと思うよ。

265 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 09:08:29 ]
>>264
それってメリットかなぁ・・・
俺はエラーの分岐もプログラムのうちだと思うけど。
そもそも正常系とわける意味がわからない。
エラー処理だって仕様の一部だよ。
あるべき場所になくて実は例外で飛んでるってのはかなり追いにくい。



266 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 10:11:14 ]
>>265
それじゃ、試しにログ出力関数を作ってみてくれ。
仕様としては、指定された名前のファイルがあれば追記でなければ新規作成。
行の内容はタイムスタンプと指定された文字列。文字列中の非可読文字は適切に処理するってことで。
それを例外を使わずに書いたものと使って書いたものを用意すれば、
どっちが読みやすい(「追いやすい」か)とか議論もできるだろう。

267 名前:デフォルトの名無しさん [2006/09/03(日) 10:40:55 ]
>>266
>仕様としては、指定された名前のファイルがあれば追記でなければ新規作成。
>行の内容はタイムスタンプと指定された文字列。文字列中の非可読文字は適切に処理するってことで。
っていう関数(例えばwriteLog関数)を作って

re = hoge.init();
if(re != S_OK){
  writeLog("初期化失敗");
  return; //処理によってreturnするもよし、続行するもよし
}

re = hogest.init();
if(re != S_OK){
  writeLog("オプション無し");
}

って話じゃないの?
別に関数の中で色々とやることにメリットを感じないんだけど?
だってエラーがでた箇所みつけにくいじゃん。

ところで
>指定された名前のファイルがあれば追記でなければ新規作成
これってfopenを'a'で開くだけじゃんw

お前が何をいわんとするのかさっぱりわからない。

268 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 10:41:28 ]
俺もため息が出るよ。
醜くてもやむをえずそれを書いた人の心中察するあまり…

269 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 10:48:59 ]
で、>>267

try{

  hoge.init();
  hogest.init();
  ・
  ・
  ・
}

って書くと

catch()
catch()
catch()




って書かなきゃいけないじゃん。
俺、これをやるぐらいなら>>267のほうが100倍ぐらいいいと思うんだけど。
エラーが起きたらエラーが起きたその箇所にその内容が書いてあるほうがいいと思うんだけどなぁ。

270 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 11:21:30 ]
>>267
>これってfopenを'a'で開くだけじゃんw
あ、いけね、「新規作成して1行ファイル内容を出力」の肝腎な後半を忘れてた。

で、漏れはそのwriteLog()相当の中身の話をしたかったんだがなぁ。
それはさておき、>269のcatch()の連続は何?

271 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 11:24:21 ]
C++でinitというメンバ関数名を見るたびに嫌気が差す。
コンストラクタでええやん。

コンストラクタがあるのに何がかなしゅうて一々ケッタイな初期化せにゃあかんねん。

>>270
たぶん、例外要因全部別々にcatchしてる例外初心者でしょ。
俺ならstd::exception.whatで終わらせるけど。

272 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 11:35:26 ]
>>270
>あ、いけね、「新規作成して1行ファイル内容を出力」の肝腎な後半を忘れてた。
日本語でおk

>で、漏れはそのwriteLog()相当の中身の話をしたかったんだがなぁ。
こんなのtrycatchに関係あるの?わからない。

>>271
>C++でinitというメンバ関数名を見るたびに嫌気が差す。
だってMFCからいってコンストラクタじゃウィンドウできてねーし。
継承して作ったら何もしようが無い。

>std::exception.what
なにそれ?資料少なすぎてマイナーなんじゃね?
なんかよくなるの?
基本的に処理とエラー内容はできるだけ離したくないんだけど?
俺のニーズにはあってるのかな?

273 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 11:39:47 ]
>>272
標準ライブラリをマイナーと言われても困る。
>>270
俺は例外信者だけどこれ位の規模だと例外非使用でも大差ないと思う。
マルチバイト文字とかその辺まで凝るとまた話が違うかも知れんけど。
void writeLog(const char*filename,const char*logmsg){
    char buf[64],c;
    FILE*fp = fopen(filename,"a");
    if(fp){
        time_t tm = time(NULL);
        strftime(buf,64,"%H:%M:%S | ",localtime(&tm));
        fputs(buf,fp);
        while((c=*logmsg++)!='\0')
            fputc(isprint(c)?c:'.',fp);
        fputc('\n',fp);
        fclose(fp);
    }
}

274 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 11:41:23 ]
>>273
だって全然検索ヒットしないよ。
入れてみたものの誰も使ってないんじゃない?
C言語のunionみたいさ。

275 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 11:43:14 ]
>>271
コンストラクタでエラーが起きたときに
それを通知するには例外を使うのが普通だろうけど
そのリソースに代替物があって、初期化の失敗が
致命的なエラーにならないときには
例外ではなく戻り値で通知して欲しい、とか

まあ、オブジェクトが正常かどうかを
問い合わせる関数を追加すればいいのだろうけど。



276 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 11:46:23 ]
www.google.co.jp/search?q=std+exception+what
std exception what の検索結果 約 4,800,000 件中 1 - 10 件目 (0.15 秒)

277 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 11:53:22 ]
>>274
Cでunion使わないってありえねー。
C++だと継承でほぼ代用できるから利用価値が低下するけど。
>>275
その場合なら自分も例外処理にするよりも普通は成否を返すでしょうね。
C++のiostreamもそのパターンの場合は例外を投げないですしね。
例外を使う場合はむしろメモリ不足とかの代替とか無理な状況に使うほうが多いですし。

278 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 11:53:56 ]
>>276
おお、検索の仕方が悪かっただけか。すまん。
でも、やっぱり、

catch()
catch()
catch()

って書くみたいなんだけど?

279 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 11:58:19 ]
>>273
fputs(), fputc(), fclose()のエラー処理も入れてくれ。

>>272
「新規作成して1行目にファイル内容の概略を出力」でいい?
要は、ファイル名がerror.logなら"; error.log"と書いておくとかそんな感じで。
#この件は説明不足が続いて失礼。

>>276
それは余りに無意味な検索の仕方だ。3つの単語を別々に検索してしまうジャマイカ。

280 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 12:04:37 ]
>>278
int main()
{
    try
    {
        // ...
    }
    catch(const std::exception& e)
    {
        std::cerr << e.what() << std::endl;
        return 1;
    }
}
そしてこのほかには殆ど完全にと言ってよいほどtry/catchが出てこないプログラム。

281 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 12:11:00 ]
というか例外って使いこなせば使いこなすほど
try catchをほとんど書かなくなるんだよな(C++では)

282 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 12:14:00 ]
処理を中断してログ吐いて終了するくらいしか手がないときにしか
例外って使わないしねぇ…

283 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 12:39:58 ]
非チェック例外以外にチェック例外も用意したJavaですら
最近は「例外は基本的に実行時例外だけにしとけ。
どうにもならんような状態を知らせるか、
プログラミングミスを検出する目的で使え。」な流れだよね。

284 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 12:45:01 ]
>>277
> Cでunion使わないってありえねー。
> C++だと継承でほぼ代用できるから利用価値が低下するけど。

kwsk

285 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 13:30:24 ]
プログラムにバグがあるときでも何とかごまかすために使ってる>>例外



286 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 15:03:27 ]
継承で利用価値が低下するってのは、俺にもよくわからんな。
struct RGBA
{
union
{
struct
{
unsigned char r, g, b, a;
};
unsigned char rgba[4];
};

みたいなのを、
class RGBA
{
unsigned int rgba;
public:
void set(unsigned char r, unsigned char g, unsigned char b, unsigned char a);
void set(unsigned int rgba);

}

みたいに書くからって話かな?

287 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 15:13:10 ]
union と継承の関係もよくわからんが、
>>296 のプログラムと継承の関係はもっとよくわからん。

288 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 15:23:20 ]
>>287
・>286のclass RGBAはunionを使っていない。
・struct RGBAを含む構造体は内包で実現することになるが、
class RGBAを含む構造体は継承で実現できる。
#が、意味は微妙。

289 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 15:42:01 ]
277がC++だと継承で代用できるといったのはこういう例だと思う。
struct Hoge
{
    enum type_t {Foo, Bar, Piyo} type;
    union
    {
        struct foo_t {/* ... */} foo;
        struct bar_t {/* ... */} bar;
        struct piyo_t {/* ... */} piyo;
    };
};
typeによってunionのどのメンバにアクセスできるかが決まるというもの。

290 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 19:02:36 ]
そんなもんCでもできるし、継承関係ないけど…。

ひょっとして釣り?

291 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 19:24:48 ]
いや、289のようにCでは共用体でやっていたのを、C++では継承で代用…ってことなんではないかと。
自分の勘違いだったら申し訳ないが、自分は290の読解力こそ疑うが…。

292 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 19:29:06 ]
>>290
ここまで説明せにゃならんのか。
void HogeHoge(Hoge* hoge)
{
    switch (hoge->type)
    {
    case Foo: /* fooの処理 */ break;
    case Bar: /* barの処理 */ break;
    case Piyo: /* piyoの処理 */ break;
    }
}
これをOOP風にすると、継承を使いunionを使わないようにすることができる。
class Hoge
{
    virtual void HogeHoge() = 0;
};

class Foo : public Hoge
{
    virtual void HogeHoge() {/* fooの処理 */}
};
//Bar, Piyoも同じ

293 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 19:50:11 ]
union ってあるビットの塊をいろんなものに解釈するためにあると思うんだが。

Foo, Bar, Piyo が union だった場合、それぞれを Foo は Bar にも Piyo にも見えるけど、
Foo, Bar, Piyo が Hoge の派生だった時に、 Foo を Bar に見ることって無理っぽいんですが。

294 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 19:51:11 ]
やっぱりUnionと関係ない気がするな。

295 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 19:57:45 ]
共用体だからって、別のものに解釈させて使わなきゃならないってことはないんで、
292の例は別解釈をさせずに、統一的に扱うために使ってるんではないかと。
WinAPIのSendInputで使うINPUT構造体なんかも292の例と同じ使い方だね。



296 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 19:57:59 ]
>>293
289/292では、typeに指示された型以外で共用体のメンバにアクセスしてはいけないという仕様。
FooをBarとして見るなどといったことはできない。

Cでは、こういうunionの使い方をされることも全くないわけではない。

297 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 20:20:49 ]
あるunionの使い方についてはC++の継承で表現できる、なら納得。

298 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 21:32:28 ]
>>292
なんかすげーヘタな設計を見た気がする...。

> virtual void HogeHoge() {/* fooの処理 */}

とか書いてごまかしてるけど、

union {
 char a;
 int b;
 float c;
} x;

に相当するもの書いてみ。自分がどんな変な設計してるかわかるから。

>>293
ビットレベルの別解釈と、メモリの節約 (=同一の領域をいろんな意味で使う) だろ。

>>295
それは、単にタグをつけてるだけの話。

継承とはまったく関係がない。

299 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 21:45:52 ]
たとえば、Cでパーサを書くときって、Tokenをunionで実装したりしない?
union Token {
int keyword;
char *identifier;
int intValue;
double doubleValue;
};
これを、C++で書いたら、Tokenクラスを継承して、KeywordTokenとか、NumberTokenとかを
作成するような実装もありうると思うけど。


300 名前:デフォルトの名無しさん mailto:sage [2006/09/03(日) 22:16:19 ]
>>299
なるほど、すまんちょっと勘違いしてた >>292

class Base {};

class Char: Base { char a; };
class Int: Base { int b; };
class Float: Base { float c; }

みたいなイメージやね。

まあ、>>297 が正しいと思う。

301 名前:デフォルトの名無しさん mailto:sage [2006/09/04(月) 08:31:25 ]
unionでセットしたメンバ変数以外のメンバ変数として解釈するのはANSI-C的にはNG
複数のビット表現として解釈する使い方が〜とかほざくやつは完全に標準違反。

302 名前:デフォルトの名無しさん mailto:sage [2006/09/04(月) 14:56:30 ]
だが、それを承知した上で使えば中々便利。

303 名前:デフォルトの名無しさん [2006/09/05(火) 02:16:44 ]
ついに1000体突破かよ
アイロボットみたいだな
株ロボもいつか夢を見るようになるのかなぁ

304 名前:デフォルトの名無しさん mailto:sage [2006/09/05(火) 03:33:50 ]
>ANSI-C的にはNG
実装依存じゃなかったか?

305 名前:デフォルトの名無しさん mailto:sage [2006/09/05(火) 03:56:05 ]
故にNGなんだろなー。
あまりにも典型的すぎるんで、使ってるから下手だとか言う気には到底なれんが。



306 名前:デフォルトの名無しさん mailto:sage [2006/09/23(土) 20:57:55 ]
なあおまえら聞いてください。

 #define MINUS_1  -1

これは明らかにうんこたれだ。
んがしかし

 #define MINUS_1  FunnyVariant(L"-1", FV_LONG)

これはおkだよな?

(つД`) つーかもう俺泣きてぇ。
この FunnyVariant をはじめ、DB操作もお金の計算も日付計算も専用のライブラリが用意されてて
↑あんな感じで FunnyVariant クラスに *文字列を* 入れて、数値を生成しなきゃならん。
こうやって、東日本全体を覆うアレのシステムは構築されてんだぜ。。。

307 名前:デフォルトの名無しさん mailto:sage [2006/09/23(土) 21:09:20 ]
>>306
>この FunnyVariant をはじめ、DB操作もお金の計算も日付計算も専用のライブラリが用意されてて
超巨大プロジェクトは、そうするのが普通。






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<125KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef