C++相談室 part51
■ このスレッドは過去ログ倉庫に格納されています
0001v(^・^)v
2006/07/17(月) 04:48:17ただし質問の前にはFAQに一通り目を通してください。
IDE(VC++など)などの使い方の質問はその開発環境のスレに
お願いします。
テンプレその他 >>1-15 付近参照
前スレ
C++相談室 part50
http://pc8.2ch.net/test/read.cgi/tech/1149427282/
0153デフォルトの名無しさん
2006/07/20(木) 05:04:29いや、それだったら例外と大して差がないから、結局同じ問題に帰着する。
0154デフォルトの名無しさん
2006/07/20(木) 09:04:11・終了処理用のmethodを別途作る。こちらは必要な例外を投げる。
と作っておき、エラーハンドリングをきちんとしたい時は2でやる。
簡便にやりたい時は1で済ませる。
というのはもはや定法です。
0155デフォルトの名無しさん
2006/07/20(木) 09:06:26クライアントは、生成・削除以外の責任を持たなくて良いくらいのカプセル化の方が、気持ち良い
削除前に必ずrelease()を呼んでください…みたいのは嫌なんだよな
まぁ、今はしょうがないのでそうしてるけど、次があったらどうにかして欲しいわ
0156デフォルトの名無しさん
2006/07/20(木) 10:56:55きちんとcatchしといたほうがいいのでしょうか。
0157デフォルトの名無しさん
2006/07/20(木) 11:09:13・デストラクタは例外を投げてはいけない。デストラクタ内で例外を投げる関数を呼び出す場合、
デストラクタがプログラムを中止させるか、その例外を補足し飲み込む(処理する)ようにする。
・クラスのクライアントが例外に対処する必要があるなら、クラスに「例外を投げるかもしれない処理」
をする通常の関数(つまり、デストラクタでない関数)を付ける。
0158デフォルトの名無しさん
2006/07/20(木) 12:39:19けっして定法ではないと思う。
ネットでも仕事でもよく見かけるのはエラーチェックしない糞プログラムばっかりだ。
0159デフォルトの名無しさん
2006/07/20(木) 12:56:35えーとそれは「定法である」ということにケチを付けたいということでよろしいか?
0160デフォルトの名無しさん
2006/07/20(木) 13:41:59その例外を受けたときどうしたいのかによって、答えは違うだろう。
ソケットクローズがエラーだったとして、それを検出したらどうするのかと。
0161デフォルトの名無しさん
2006/07/20(木) 14:47:090162デフォルトの名無しさん
2006/07/20(木) 15:09:29投げたくなっても、投げてはいけません。
0163デフォルトの名無しさん
2006/07/20(木) 15:16:23ただし、一番上のやつは駄目で、二番目を参照すること。
0164デフォルトの名無しさん
2006/07/20(木) 21:43:43例えばここのFileHandleクラスはデストラクタでcloseしてエラーチェックしてないよ。
こういう場合はどうするの?
0165デフォルトの名無しさん
2006/07/20(木) 22:14:37それがおかしいだけ
お偉いさんが書くものすべて正しいと思ってるあほは氏ねば?w
0166デフォルトの名無しさん
2006/07/20(木) 22:17:33> どうするの?
どうしたいの?
0167デフォルトの名無しさん
2006/07/20(木) 23:12:450168デフォルトの名無しさん
2006/07/20(木) 23:17:32正しい例など存在しない。
0169デフォルトの名無しさん
2006/07/21(金) 02:18:07デストラクタで資源解放→close等でエラーの可能性がある→デストラクタで例外は禁止→エラーを黙殺するな
で、初心者が困っててもどうすりゃいいのか妥当なサンプルも提示出来ないってことか
154は定法とまで言ってるのにな
0170デフォルトの名無しさん
2006/07/21(金) 02:38:50More Effective C++を久しぶりに読んだが、訳がひどいねえやっぱり・・・
しかし、例え初心者でも、この本は読むべきだろう。コード片を示せとか
言ってる奴がいるが、本で数ページを割いて説明している事を小さな
コード片にまとめるのは至難の業。
0171デフォルトの名無しさん
2006/07/21(金) 03:16:23だから何度も言ってるだろう。
リソースがリークして困るならデストラクタでやるな。
0172デフォルトの名無しさん
2006/07/21(金) 03:17:31何言ってんだ?リソースの解放をデストラクタでやるのは何も問題ないだろ。
0173デフォルトの名無しさん
2006/07/21(金) 03:23:48お前こそなに言ってんだよ。
「リークして困るなら」と言ってるだろうが。
0174デフォルトの名無しさん
2006/07/21(金) 03:27:370175デフォルトの名無しさん
2006/07/21(金) 03:28:03ケースバイケースなのは分かったからサンプルを示してくれって話だろ。
0176デフォルトの名無しさん
2006/07/21(金) 03:32:280177デフォルトの名無しさん
2006/07/21(金) 03:33:070178デフォルトの名無しさん
2006/07/21(金) 03:41:22そうなると、ほかの処理ができなくなるんじゃないのか。
そんなトラップのようなデストラクタを持つクラス、使いたくないな。
自分だけで使うんなら、いいんだろうけどね
0179デフォルトの名無しさん
2006/07/21(金) 03:44:42>>161,163
0180デフォルトの名無しさん
2006/07/21(金) 03:46:25>そもそも誰もデストラクタで例外禁止なのは否定してないし、理由を聞いてるわけでもない。
0181デフォルトの名無しさん
2006/07/21(金) 03:52:32違う。
黙殺していい場合にのみ、デストラクタでリソースの解放をやってもいい、が正解。
0182デフォルトの名無しさん
2006/07/21(金) 07:29:13【 靖国神社とは … ”靖 国 機 関 説” 】
-----------------------------------------------------------------------------------
戦 前 : 官僚が天皇の名を騙り、国民を騙す戦争推進機関として設立。神を捏造。不遜、極まりない。
戦 後 : 官僚の戦争責任を、国民の戦没者追悼の念・祖先尊崇の伝統とすり替え、
数多の戦没者の中に埋没・隠蔽させる官僚のための官僚スキーム。
個人情報保護法が、国家経済破綻の責任者を隠す為の、隠蔽スキームであるのと同じ汚い手口!
-----------------------------------------------------------------------------------
影 響 : 戦後外交の足かせ。中国、朝鮮に付け入られる原因となった。尖閣しかり、竹島しかり!
今 後 : 古臭い靖国モデルは、21世紀日本にとって百害あって一利なし。破壊すべし。ってか、創価・靖国キモイ。
-----------------------------------------------------------------------------------
天皇陛下も国民とともに、官僚とその手先自民党と闘われていた事が判明!
【昭和天皇、A級戦犯合祀に反撃 …宮内庁長官メモ】(読売)
http://www.yomiuri.co.jp/national/news/20060720it06.htm 「親の心、子知らずとはこの事…」
【「増税して下さいと謝るまで削れ」、「病院・幼稚園つぶせ」首相、諮問会議で指示】
http://www.asahi.com/politics/update/0627/014.html
0183デフォルトの名無しさん
2006/07/21(金) 09:14:41代入演算子のオーバーロードを定義するとき、戻り値をクラスの参照にするべきだと
いうことをよく見るのですが、何故でしょうか?
例)
Hoge というクラスがあったとして
Hoge & Hoge::operator=(const Hoge& x)
{
//定義
}
よく見る解説では a=b=cのような処理を実行するために戻り値は参照でなければ
ならないといけないと書いてあります。
でも、以下のように値を返してもa=b=c は可能だと思えます。
Hoge Hoge::operator=(const Hoge& x)
{
//定義
}
戻り値を値にしてしまった場合、a=b=cが不可能となるようなケースってあるのでしょうか?
よろしくお願いします。
0184デフォルトの名無しさん
2006/07/21(金) 09:36:52> a=b=cが不可能となるようなケースってあるのでしょうか?
コピーコンストラクタが宣言だけされて、定義されてない時。
0185デフォルトの名無しさん
2006/07/21(金) 09:57:55Hoge a, b, c;
(a = b) = c;
のように書いた際に、一時生成されたテンポラリオブジェクトにcが代入されて
a == cとならなくなってしまうから、必ず参照を返さなければいけない
0186デフォルトの名無しさん
2006/07/21(金) 13:09:35VC6で、
cout << (int)(18.4*100000) << endl;
と書いたときに、1839999 と表示されるのだが、
何か上手い回避手段は無いものか。
0187デフォルトの名無しさん
2006/07/21(金) 13:12:400188デフォルトの名無しさん
2006/07/21(金) 13:17:05- (int)(18.4*100000)
+ round(18.4*100000)
0189デフォルトの名無しさん
2006/07/21(金) 13:26:54あーなるほど。確かに。
でも、やりたいのは端数切捨て処理だから、やるとすればこうか。
template< typename T > inline T fix( T value ) {
return ( value < 0 ) ? std::floor(value) : std::ceil(value);
}
面倒だけど、これでやってみるよ。
0190デフォルトの名無しさん
2006/07/21(金) 13:34:02あ、ceil と floor 逆だ。
0191190
2006/07/21(金) 13:38:20>>186 の提案もいいが、それだと 18.65 を端数切捨てで 18 と表示したいときに
19 と表示されてしまう。
どうしたもんだろ。
0192デフォルトの名無しさん
2006/07/21(金) 13:45:21これをそれぞれaaとccという行列にコピーしたいと思い,
for(j=0;j<=m-1;j++){
for(k=0;k<=n-1;k++)
aa[j][k] = a[j][k];
cc[j][k] = c[j][k];
}
というプログラムを書いたのですが,
aaの方はちゃんとaの行列になるんですが,
ccの方が計算されずに全ての行列の値が0のままになってしまいます.
aaとccのfor文の計算を分割すればちゃんと計算されるのですが,
なぜこの場合同時にできないのでしょうか?
どのようにすれば解決できるのでしょうか?教えてください.よろしくお願いします.
0193デフォルトの名無しさん
2006/07/21(金) 13:52:45カッコ悪い。
慣れない内はforやifの後を必ず複文化しよう。
0194デフォルトの名無しさん
2006/07/21(金) 13:55:59どこをどう丸めたいのかよく判らんが、sprintf()の"%.2f"で四捨五入して
sprintf()の"%.*s"で切り捨ててから数値化するとかw
まぁ、100倍して整数に四捨五入してから100で割って切り捨ててもいいんでね?
0195デフォルトの名無しさん
2006/07/21(金) 14:24:03若しくは有理数クラスでも使う
0196190
2006/07/21(金) 14:29:18double rhs = strtod( TextBox1.Text().c_str() );
double lhs = strtod( TextBox2.Text().c_str() );
if( ... /* 整数表示フラグ */ )
{
stringstream s;
s << static_cast<int>( rhs * lhs );
TextBox3.Text( s.str() );
}
みたいなプログラムを組んでいて、仕様では
整数表示の際は端数を切り捨てることがきまっています。
>>186 の例のように
TextBox1 に 18.4、
TextBox2 に 100000 が代入された場合、
TextBox3 には 1839999 が表示されてしまうわけです。
両辺を n倍し、nで割る方式では上記問題を防げません。
とりあえず、↓の形で妥協することにしました。
int const n = 6;
sprintf( buf1, "%.*f", n, rhs * lhs );
sprintf( buf2, "%.*s", strlen(buf1)-n+1, buf1 );
TextBox3.Text( buf2 );
0197デフォルトの名無しさん
2006/07/21(金) 14:41:12sprintf(buf, "%.0f", 18.4*100000);
or
std::cout << std::setprecision(0) << std::fixed << 18.4*100000 << std::endl;
0198デフォルトの名無しさん
2006/07/21(金) 15:16:13>>196 に
> 整数表示の際は端数を切り捨てることがきまっています。
と書いてるように、丸めてしまっては意味がありません。
0199デフォルトの名無しさん
2006/07/21(金) 15:22:23こんな間抜けな質問するだけあるな。
0200デフォルトの名無しさん
2006/07/21(金) 16:14:50sprintf()の"%.0f"なら四捨五入ですが何か。
0201デフォルトの名無しさん
2006/07/21(金) 19:02:51Packed BCDとかDecimal Arithmeticのライブラリ使いなよ。
http://www2.hursley.ibm.com/decimal/
0202デフォルトの名無しさん
2006/07/21(金) 22:51:44でなんとかなりそだとおもうんだけど・・・
テストすんのが面毒背
0204デフォルトの名無しさん
2006/07/22(土) 13:22:40あるヘッダファイル内で int hoge=3; と定義し、2つの cpp ファイル (a.cpp、b.cpp) からそのヘッダをインクルードすると、もちろんリンク時にエラーが出ます。
ところが、定義を const int hoge=3; とすると、エラーが出ませんでした。
これは、hoge と言う実体が2つ生成され、a.cpp と b.cpp の hoge はそれぞれ別のものを指していると考えてよろしいのでしょうか?
ということは、スコープをファイル内に限定する static const int hoge=3; と同じ意味になるのでしょうか?
0205デフォルトの名無しさん
2006/07/22(土) 13:54:17(変更可能な左辺値)でしょうか?
0206デフォルトの名無しさん
2006/07/22(土) 13:56:31そんなん試してみりゃすぐわかんじゃん・・・
0207デフォルトの名無しさん
2006/07/22(土) 14:05:06operator=の定義次第です。
0208デフォルトの名無しさん
2006/07/22(土) 14:18:05C++ではconst int は定数扱い。
0209デフォルトの名無しさん
2006/07/22(土) 15:39:18floatでもconstを付けると同じ現象となりますが、これはどう説明する気ですか?
0210デフォルトの名無しさん
2006/07/22(土) 15:58:13constはデフォルトで内部リンケージを持っている。
//file1.c
const int hoge = 3;
//file2.c
const int hoge = 7;
としても文法違反ではなくリンクエラーにはならない。
ということが、ビョーンのバイブルの246ページに書いてある。
0211デフォルトの名無しさん
2006/07/22(土) 15:59:29現象っていうか文法を知らないだけではないかとjvんszぃ;vbds;pzvびsz@あvp
0212デフォルトの名無しさん
2006/07/22(土) 16:03:260213デフォルトの名無しさん
2006/07/22(土) 16:08:42floatはコンパイラベンダのサービスだろw
// integral or enumertion typeのconstはinternal linkage
// 7.1.5.1.2より
0214209に捧ぐ
2006/07/22(土) 16:13:280216デフォルトの名無しさん
2006/07/22(土) 16:46:330217デフォルトの名無しさん
2006/07/22(土) 16:54:30>>210が説明してんだろぼけ
0218デフォルトの名無しさん
2006/07/22(土) 17:16:58未熟な自演はトリップの修正を忘れます。
>>209
>ということは、スコープをファイル内に限定する static const int hoge=3; と同じ意味になるのでしょうか?
>>210が説明しているとおりだが、お前にわかりやすく言えば、次の2つは同じ意味。
const int hoge=3
static const int hoge=3 (規格的に正しいかどうか走らないがVS2005ではとおる)
0219デフォルトの名無しさん
2006/07/22(土) 17:21:29×正しいかどうか走らないが
○正しいかどうかは知らないが
const をa.c b.c 間で共有する場合、これで出来てるようであるが規格上はどうなの?
// a.c
extern const float aa = 10
// b.c
extern const float aa
0220禿@ベル研究所 ◆HsptrkZmYk
2006/07/22(土) 17:24:55externを付けると外部リンケージを持つ
0221デフォルトの名無しさん
2006/07/22(土) 17:37:40うむ
だから
//file1
extern const int hoge = 7;
//file2
extern const int hoge = 8;
はリンクエラーだな
bcc32ではそうだった
ちなみに
//file1
extern const int hoge = 7;
//file2
const int hoge = 8;
も無問題だった
0222デフォルトの名無しさん
2006/07/22(土) 18:29:53これよく解らんのだが、どれが戻り値で、どれがオペレーターなの?
0223デフォルトの名無しさん
2006/07/22(土) 18:38:300224デフォルトの名無しさん
2006/07/22(土) 18:41:04C++は奇奇怪怪だなwww
この書式にすぐにくじけてしまう
0225デフォルトの名無しさん
2006/07/22(土) 18:50:37はゲームを作ることを目的とした参考書じゃなくて普通の参考書を買っ
て勉強したほうがいい?
0226デフォルトの名無しさん
2006/07/22(土) 18:51:32なんて関数があった場合に、
そのOPが定義してあると、
Class class;
C( class ); なんかで変換可能ってこと?
こういうのなんていうの?自動型変換オペレーター?
0227デフォルトの名無しさん
2006/07/22(土) 18:57:240228デフォルトの名無しさん
2006/07/22(土) 19:00:360229デフォルトの名無しさん
2006/07/22(土) 19:05:24ぃぁーC++すごいわー・・・
0230デフォルトの名無しさん
2006/07/22(土) 19:28:41アホハッケーン
0231204
2006/07/22(土) 19:29:00実体が複数作られるのは避けたいため、extern 宣言をしようと思います。
// hoge.h (インクルードガード済み)
extern const int HOGE = 3;
struct HOGESTRUCT {
int array[HOGE];
};
今、このファイルを2つの cpp からインクルードすると、HOGE に関して重複定義のリンクエラーが起きました。
// hoge.h
extern const int HOGE;
のように、ヘッダ内では宣言だけにして、
// a.cpp
const int HOGE = 3;
のように、cpp 内で、HOGE の値を定義したのですが、
hoge.h のHOGESTRUCT の宣言時に HOGE の値が未知なため、array の宣言がうまく行きません。
extern をはずしてしまうと、HOGE の実体が複数作られておいしくありません。
これを解決するには、#define マクロを用いるか、enum ハックを行う、以外に方法はありませんでしょうか?
0232デフォルトの名無しさん
2006/07/22(土) 19:37:55>実体が複数作られるのは避けたいため
なぜ?
そもそもアドレス取らない限りコンパイル時に埋め込まれる。
0233デフォルトの名無しさん
2006/07/22(土) 19:45:29常識的には>>232だが、それ以外でないとどうしてもいやだ、それをやると
明日首をつらなければならないって言うんならそんな奴には#defineがお似合いだ。
0234204,231
2006/07/22(土) 19:57:28深い意味はありませんでした。複数作られることが単に無駄な気がしただけです。
例えば、10KB くらい分の定義が 100 ファイルから読まれると、1MB も無駄に exe が大きくなるんじゃないかなーと。
気にしないことにします。ありがとうございました。
0235デフォルトの名無しさん
2006/07/22(土) 20:00:25>例えば、10KB くらい分の定義が 100 ファイルから読まれると、1MB も無駄に exe が大きくなるんじゃないかなーと。
普通その手のプログラムは実行モジュール自体が数100MBに達するだろうから無駄と言う観点では誤差。
#寧ろ他に減らすべきものがたくさんあるはずだ。
0236デフォルトの名無しさん
2006/07/22(土) 20:02:39extern const int HOGE;
struct HOGESTRUCT {
int array[HOGE];
};
は明らかにコンパイルエラーだろう。extern const int HOGE;は外部変数を
参照するための宣言であって、int array[HOGE];のHOGEの定数値が定義されてない。
// hoge.h (インクルードガード済み)
const int HOGE = 3;
struct HOGESTRUCT {
int array[HOGE];
};
ではだめなの?const int HOGE = 3;は内部リンケージを持つから、複数のcpp
ファイルからインクルードしてもリンクエラーにはならないと思うけど。
認識違いだったらすみません。
0237デフォルトの名無しさん
2006/07/22(土) 20:08:44プギャーm9(ry
0238デフォルトの名無しさん
2006/07/22(土) 20:50:58>232
>そもそもアドレス取らない限りコンパイル時に埋め込まれる。
exeが大きくなることは無いって意味だとおもうが
0239デフォルトの名無しさん
2006/07/22(土) 21:09:04は、アドレスを取らない限りは
#define HOGE 3
とほぼ同じと思って構わない。
C++ では。
0240デフォルトの名無しさん
2006/07/22(土) 21:10:07ってな感じでコマンドラインで渡したパスを開こうとしても開けない
渡しているパスがC:\Programm Files\〜なんだけれども空白が原因?
C:\test.txtは問題なかったし
0241デフォルトの名無しさん
2006/07/22(土) 21:18:39空白で問題が発生するのは考えにくいな。
perror() してみるとなにかわかるかもしれない。
0242デフォルトの名無しさん
2006/07/22(土) 21:32:42結果はNo such file or directory
もちろんパスは実際にあるものを渡してるから無いはずはない
一応短いけどソース出しときます
int main(int argc, char* argv[])
{
//引数チェック
if(argc!=2) return 0;
printf("%s\n",argv[1]);
ifstream inf(argv[1]);
perror("test");
if(!inf)
{/*・・・
0243デフォルトの名無しさん
2006/07/22(土) 21:44:11× Programm Files
○ Program Files
0244デフォルトの名無しさん
2006/07/22(土) 21:46:50引数をダブルコーテーションで囲め
0245デフォルトの名無しさん
2006/07/22(土) 21:50:25本当に>>243が原因なんじゃないだろうか
0246デフォルトの名無しさん
2006/07/22(土) 22:15:55ごめんProgrammは素で間違えた
けれど引数の方はちゃんとProgramで渡してるから問題ない
ダブルクォーテーションもつけてて下の状態でも通らない
"C:\Program Files\JaneDoeView\Logs\Logs\2ch\PC等\プログラム\1048668198.dat"
0247デフォルトの名無しさん
2006/07/22(土) 22:18:52いやその場合プログラム側でダブルクォーテーションを削除してからifstreamに渡さなければならない
0248デフォルトの名無しさん
2006/07/22(土) 22:19:14いいえ全然違います
0249デフォルトの名無しさん
2006/07/22(土) 22:22:54× C:\Program Files\JaneDoeView\Logs\Logs\2ch\PC等\プログラム\1048668198.dat
○ C:\Program Files\JaneDoeView\Logs\2ch\PC等\プログラム\1048668198.dat
0250デフォルトの名無しさん
2006/07/22(土) 22:25:52渡されたコマンドライン引数argv[1]をprintfで直接表示しても""はついてないから
それではないと思う
>>249
自分のだとlogs\logsの下にログがある
Jane入れたときに自分で設定を弄った
0251デフォルトの名無しさん
2006/07/22(土) 22:26:53とんでもない嘘つくなよw
>>250
cmd.exeにargv[1]のファイルをD&Dして実行してみろ
0252デフォルトの名無しさん
2006/07/22(土) 22:33:56C:\〜〜>"プログラム本体" "目的のdat"
やってみてもファイルオープンで躓く
fstreamに必要な設定とかあるの?
■ このスレッドは過去ログ倉庫に格納されています