C++相談室 part52
- 251 名前:デフォルトの名無しさん :2006/09/03(日) 22:59:33
- xの使い方によっては最適化で痕跡もなくなる可能性が高いが。
- 252 名前:デフォルトの名無しさん :2006/09/03(日) 23:10:22
- >>226
thisの値自体は決定してるぞ。
ポインタをデリファレンスするのは>>228の問題があるだけで。
- 253 名前:デフォルトの名無しさん :2006/09/03(日) 23:11:03
- >>252
渡した先でいくらでもデリファレンスされる可能性がある。
- 254 名前:デフォルトの名無しさん :2006/09/03(日) 23:15:20
- でも
const_cast<int&>(HOGE_SIZE) = 30;
とできるわけだが、こういうコードがあった場合は、最適化しないというようなことを
コンパイラはやっているわけ?
- 255 名前:デフォルトの名無しさん :2006/09/03(日) 23:26:35
- >>254
そのコードは鼻から悪魔が出るんじゃないのか?
- 256 名前:デフォルトの名無しさん :2006/09/03(日) 23:26:44
- >>254
それ未定義動作だからコンパイラは面倒見なくていい。
- 257 名前:デフォルトの名無しさん :2006/09/03(日) 23:28:52
- >>255 どういう意味だ?
>>256 そうなんかい。しらなんだ。
- 258 名前:デフォルトの名無しさん :2006/09/04(月) 00:20:54
- bool b[100];
memset(b, 0xFF, sizeof(b));
int x = b[0];
このとき x は未定義でしょうか?
- 259 名前:デフォルトの名無しさん :2006/09/04(月) 00:32:18
- >>258
大抵の実装で 1 が期待できるけど、保証はないだろうねぇ。
- 260 名前:デフォルトの名無しさん :2006/09/04(月) 00:36:46
- >>259
そうですか。ありがとうございます。
- 261 名前:デフォルトの名無しさん :2006/09/04(月) 00:43:58
- VC を使っているのですが、&& や || って、shortcut をするから、
ジャンプ命令が生成されるんだよね。たとえば、
if (x==y && y==z && z==w)
だと、2つのジャンプ命令が生成される。
そこで、これを bool の整数への昇格を利用して
if ((x==y) & (y==z) && (z==w))
のように実装したほうが、高速なコードが生成されるのだが、
こういうテクニックって一般的ですか?
- 262 名前:デフォルトの名無しさん :2006/09/04(月) 00:44:38
- if ((x==y) & (y==z) && (z==w))
は
if ((x==y) & (y==z) & (z==w))
の間違い。
- 263 名前:デフォルトの名無しさん :2006/09/04(月) 01:02:14
- >>261
一般的じゃないだろうね。使うんならコメントが無いと && に「修正」されちゃうよ。
ところで高速だというのは実験したの?
- 264 名前:デフォルトの名無しさん :2006/09/04(月) 01:16:15
- >>262
マジレスすると、JavaやC#は & にした方が速いが、CやC++では
何とも言えない。
- 265 名前:デフォルトの名無しさん :2006/09/04(月) 01:24:45
- >>263
ごめんなさい。速いと思ったら、3倍ぐらい遅かった。
9個の || を連結した簡単なテストコードで試してみた。
>>264
情報ありがとう。
- 266 名前:デフォルトの名無しさん :2006/09/04(月) 01:29:18
- >>265
速度は実測が基本。
やっぱり基本は大事だな。
- 267 名前:デフォルトの名無しさん :2006/09/04(月) 01:30:38
- コードが生成される、って言い切ってるから実験はしたんだろうけど……。
「&」と「&&」の微妙な挙動の差には注意しないとアカンよ。
- 268 名前:267 :2006/09/04(月) 01:31:10
- してへんかったんかい!('д`*)
- 269 名前:デフォルトの名無しさん :2006/09/04(月) 01:41:27
- 実測もちゃんと最適化しないとダメだし、
分岐予測の影響も考慮しないといけないし、
何で速くなるのかリスティングファイル見て調べないとな。
- 270 名前:デフォルトの名無しさん :2006/09/04(月) 01:54:39
- C/C++の条件式は最初にfalseが(Cなら0)検出された時に抜けて
しまうので、なるべくfalseになる確率が高いと思われる条件式から
先に書くようにすると、速くなりやすい。
- 271 名前:デフォルトの名無しさん :2006/09/04(月) 02:07:17
- 件のコードは、条件を整数(1/0)に直すコードが生成されちゃうんだろう。
普通に&&で書く場合、条件を判定するだけで
その結果を整数に直して代入したりはしないから。
ただ、&だとあまり使えないけど
(x != 0) | (y != 0) を (x|y) != 0 というのは
使い物になる場合があるかもね。
もちろんこれも、コメント必須なトリッキーなやり方だから
本当にそこまでする必要がある箇所なのかは、よーく考えるべきだけど。
- 272 名前:デフォルトの名無しさん :2006/09/04(月) 02:07:42
- ショートサーキットも、結局判断式の内容次第だな。
if(a && b && c) で、a式b式c式の間に依存関係が無いなら
if(a&b&c) はパイプラインに上手く乗っかって
判断cのコスト+a&b&cのコスト+アルファ程度で抜けるかもしれない。
だが世の中には分岐予測というものがありましてな。
- 273 名前:デフォルトの名無しさん :2006/09/04(月) 02:07:45
- それはJavaもC#も同じはず。
- 274 名前:デフォルトの名無しさん :2006/09/04(月) 02:08:44
- × (x != 0) || (y != 0) を (x|y) != 0
○ (x != 0) | (y != 0) を (x|y) != 0
だた。
- 275 名前:デフォルトの名無しさん :2006/09/04(月) 02:10:08
- 高速になるのであれば、
ショートサーキットしてもしなくても処理が変わらない状況なら
ショートサーキットを無視する可能性もあるのかな? 最適化で。
- 276 名前:デフォルトの名無しさん :2006/09/04(月) 02:18:14
- VC8とかintelコンパイラみたいな最適化に異常な執着を見せる
コンパイラなら、やってくれるのかもしれないなー。
試したわけじゃないが。
そうでなくても大体の状況において、どの組み合わせが最速となるかは
コンパイラ様が知っているでFAだろう。
- 277 名前:デフォルトの名無しさん :2006/09/04(月) 02:20:15
- まあ、「普通に書く」ことが、
コンパイラの最適化を阻害しないから、
一番いい高速化法なこともあるな。
- 278 名前:デフォルトの名無しさん :2006/09/04(月) 07:17:59
- >>253
thisの値を保持するだけなら問題ないので>>226は間違い。
- 279 名前:デフォルトの名無しさん :2006/09/04(月) 07:39:11
- >>278
参照を保持するだけなら問題ないので *this も this も危険性は同じ。
- 280 名前:デフォルトの名無しさん :2006/09/04(月) 13:44:10
- 質問させていただきます。
オーバフローをする部分があるのですが、
そのオーバフローは一体どのように検知すればよろしいのでしょうか?
たとえば、float型でオーバフローらしきことがおこり、
float f; のとき
if(f<0.0000001) {//オーバフロー処理}
といった感じにしたいのですが、オーバフローした場合、
やはりfloat型では検知できない?みたいなのですが、
こういう場合の対策法を教えていただけないでしょうか。
- 281 名前:デフォルトの名無しさん :2006/09/04(月) 13:59:36
- とりあえず使っている環境が、
C99 floating point rounding and exception handling
をサポートしているかどうか調べたら?
FE_OVERFLOWとかfegetexceptflag()とかぐぐってみて。
- 282 名前:デフォルトの名無しさん :2006/09/04(月) 14:08:50
- 単純なので良いなら
最大範囲が100
最初から入ってるのが70
次に加算しようとしてるのが50なら
if 50 > 100-70
return 警告
とか
- 283 名前:デフォルトの名無しさん :2006/09/04(月) 14:38:06
- >>282とnumeric_limitsを使う。
- 284 名前:デフォルトの名無しさん :2006/09/04(月) 16:51:35
- wchar_tをcharに変換するにはどうしたらいいでしょうか?
- 285 名前:デフォルトの名無しさん :2006/09/04(月) 18:30:11
- wchar_t wc;
char c = (char)wc;
これ以外に方法はない
- 286 名前:デフォルトの名無しさん :2006/09/04(月) 18:49:56
- >>284
keyword: wchar_t char use_facet
ttp://d.hatena.ne.jp/logion/20060208
ttp://www.tietew.jp/cppll/archive/568
- 287 名前:280 :2006/09/04(月) 18:59:14
- ありがとうございます。
結局、numeric_limitsでオーバーフロ-や丸め誤差が生じたときに
強引に戻すやり方にしました。
しかし、結局はどこでオーバーフローが生じているのか分からずじまいでした。
難しいものです。
- 288 名前:デフォルトの名無しさん :2006/09/04(月) 20:53:57
- >>287
>しかし、結局はどこでオーバーフローが生じているのか分からずじまいでした。
デバッガで調べるとかg++なら
ttp://www.k.mei.titech.ac.jp/~stamura/NumericalComputation-Tips.html#trapFPE
とか参考になるかも
- 289 名前:デフォルトの名無しさん :2006/09/04(月) 23:57:13
- >>287
このスレの最初の方でもオーバーフローの話し合ったよ
- 290 名前:デフォルトの名無しさん :2006/09/05(火) 02:54:36
- >>287
処理系によっては浮動小数点例外を有効化するだけで
発生箇所でとっ捕まえられるんじゃまいか。
コプロセッサが搭載されてない環境で
floatがソフトウエアエミュレーションされてるとかでないなら、
浮動小数点演算器の設定変えるだけでOK。
大抵の例外は捕まえられるぞ。
- 291 名前:デフォルトの名無しさん :2006/09/05(火) 07:46:50
- それは>>281。
- 292 名前:デフォルトの名無しさん :2006/09/05(火) 15:59:15
- double a[30];
int n = 30;
for(int i=0; i<n; ++i){
a[i] = i*1.4;
if(a[i] != (i*1.4)){
cout<<i<<endl;
}
}
これで出力があるのはどうしてなんでしょうか?
- 293 名前:デフォルトの名無しさん :2006/09/05(火) 16:11:59
- >>292
処理系によっては配列に格納するとき浮動小数点数の丸めが起こって、
i*1.4 の結果と比較した場合に違う値になったりするかも知れない。
ちなみに、VC6 では特に問題なかった。
- 294 名前:デフォルトの名無しさん :2006/09/05(火) 16:44:35
- >>293
そういうことなんでしょうか。
ちなみにgcc3.3.2のg++(VineLinux)を使ってます。
iの値によって出力されたりされなかったりっていう状態で、
危険だなぁと思ったもので。
- 295 名前:デフォルトの名無しさん :2006/09/05(火) 17:11:21
- >>294
#include <cfloat>
の中に入ってる DBL_EPSILON が誤差の最大値だから、
if(abs(a[i] - (i*1.4)) > DBL_EPSILON)
ってすれば回避できるよ
- 296 名前:デフォルトの名無しさん :2006/09/05(火) 17:15:00
- fabs() だったorz
- 297 名前:デフォルトの名無しさん :2006/09/05(火) 17:18:44
- >>294
80bit 浮動小数点数に格上げして比較してるのかもね。
- 298 名前:デフォルトの名無しさん :2006/09/05(火) 17:50:27
- >>295
DBL_EPSILON は 1 に足したとき値の変わる最小値だから、
if(fabs(a[i] - (i*1.4)) > DBL_EPSILON * fabs(a[i]))
みたいにオーダー揃えないとダメだよ。
- 299 名前:295 :2006/09/05(火) 18:03:46
- そいつはどーも知らんかった
- 300 名前:292 :2006/09/05(火) 20:36:38
- >>294-298
なるほど、そういうやり方があるんですね。
参考になりました。ありがとう
- 301 名前:デフォルトの名無しさん :2006/09/05(火) 22:18:26
- struct foo {
char c;
};
このとき、static_cast で foo* を char* に変換できるようにするには、
どうしたらいいですか?↓こんなことできますか?
template<>
char* static_cast<char*>(foo* p) { return (char*) p; }
- 302 名前:デフォルトの名無しさん :2006/09/05(火) 22:20:16
- operator char*
- 303 名前:デフォルトの名無しさん :2006/09/05(火) 22:21:33
- >>302
それだと foo を char* に変換することになりますよね。
やりたいのは foo* を char* にしたいんです。
- 304 名前:デフォルトの名無しさん :2006/09/05(火) 22:35:21
- >>301
思いつかないなぁ。
なんでそんなことしたいの?
- 305 名前:デフォルトの名無しさん :2006/09/05(火) 22:38:20
- return &p->c
って事?
reinterpret_castじゃだめなん?
- 306 名前:デフォルトの名無しさん :2006/09/05(火) 22:47:01
- >>304
うーん。理由は聞かないでってのじゃだめ?
>>305
そうそう。reinterpret_cast でもいいけど、
char* に変換可能なことを前提として作られているよ、ということを強調したい。
reinterpret_cast は外道だからね。
- 307 名前:デフォルトの名無しさん :2006/09/05(火) 23:01:52
- reinterpret_cast自体が外道なのではなくて、
reinterpret_castを使わざるを得ない状況が外道
つまり>>306、君のやろうとしてることが外道
>char* に変換可能なことを前提として作られているよ、ということを強調したい。
なら、まさにoperator char*が本道
- 308 名前:デフォルトの名無しさん :2006/09/05(火) 23:02:04
- >>306
static_cast で変換できても、そういう意図は伝わらないと思う。
外道とか正道とか考えるんなら、メンバ関数が正道じゃないか?
- 309 名前:デフォルトの名無しさん :2006/09/05(火) 23:05:38
- char*に正しく変換出来るのであれば、reinterpret_castをラップした
operatorなりなんなりを作ればいい
使う側は汚いキャストをしなくて済むし
- 310 名前:デフォルトの名無しさん :2006/09/05(火) 23:10:04
- >>306
伝わらないことないだろ。
>>307 >>309
だからー、foo を char* に変換したいんじゃなくて、
foo* を char* に変換したいの。
foo* pFoo = new foo[100];
char* pChar = static_cast<char*>(pFoo);
- 311 名前:ららら :2006/09/05(火) 23:11:50
- >>307
> reinterpret_cast自体が外道なのではなくて、
> reinterpret_castを使わざるを得ない状況が外道
それは分かるのら。しかし、
> つまり>>306、君のやろうとしてることが外道
ここの論理的つながりがないのら。
私は reintrepret_cast を使わないようにしたいのら。
- 312 名前:デフォルトの名無しさん :2006/09/05(火) 23:13:09
- static_cast<foo*>(static_cast<void*>(...))
- 313 名前:デフォルトの名無しさん :2006/09/05(火) 23:15:44
- T*からU*に変換するテンプレート書くとか
中身はreinterpret_castで書いて
- 314 名前:デフォルトの名無しさん :2006/09/05(火) 23:19:32
- foo*もらってchar*出す関数を別に作ればいいじゃん
- 315 名前:ららら :2006/09/05(火) 23:19:50
- >>313
これは、普通の関数で書くということですか?
char* ConvFooToChar(foo* p) { return reinterpret_cast<char*>(p); }
うーん、変換するたびにこれを呼ぶのは、ちょっとなー。
できれば static_cast にしたいなー。
- 316 名前:デフォルトの名無しさん :2006/09/05(火) 23:22:56
- >>310
どうして自分の意図が伝わると思うの?
全然別の目的で static_cast や C スタイルキャストを使っている template や
マクロの中でもコンパイルが通ってしまうことが考えられる。やめたほうがいい。
- 317 名前:400 :2006/09/05(火) 23:24:12
- foo_cast<char *>(p)とでもかけるようなテンプレ関数をこさえるとか。
- 318 名前:デフォルトの名無しさん :2006/09/05(火) 23:25:49
- 香ばしい奴が一人来てるな。
- 319 名前:デフォルトの名無しさん :2006/09/05(火) 23:27:05
- ポインタから char* への static_cast にユーザー定義コードの介入する余地は無い。
あきらめれ。
- 320 名前:ららら :2006/09/05(火) 23:28:30
- >>316
> 全然別の目的で static_cast や C スタイルキャストを使っている template や
> マクロの中でもコンパイルが通ってしまうことが考えられる。やめたほうがいい。
意味が分からないのら。何がまずいのか分からないのら。
サンプルコードを示してくれないかなのらー。
- 321 名前:デフォルトの名無しさん :2006/09/05(火) 23:29:00
- >>310
ソースで自分の意図を伝えたいと言い出す前に、
日本語で自分の意図が上手く伝えられそうになってください。
- 322 名前:ららら :2006/09/05(火) 23:29:12
- >>319
やぱーりそうかー。無理かー。
じゃー、あきらめるのらー。
- 323 名前:デフォルトの名無しさん :2006/09/05(火) 23:31:11
- らららはアレだな。
そう、えーっと・・・ぬるぽ。
- 324 名前:デフォルトの名無しさん :2006/09/05(火) 23:31:19
- >>310
ちなみにfoo*からchar*への変換演算子を定義することができないのは、foo*もchar*もポインタという組込型だから。
- 325 名前:デフォルトの名無しさん :2006/09/05(火) 23:40:57
- >>324
あ?
- 326 名前:デフォルトの名無しさん :2006/09/05(火) 23:45:18
- >>325
い?
- 327 名前:デフォルトの名無しさん :2006/09/05(火) 23:52:15
- >>326
Wooooooooooo!!!!
- 328 名前:デフォルトの名無しさん :2006/09/06(水) 00:01:14
- #define static_cast reinterpret_cast
- 329 名前:ららら :2006/09/06(水) 00:41:45
- >>328
ばかはおよびでないのらー
- 330 名前:デフォルトの名無しさん :2006/09/06(水) 01:15:23
- >>329
オマエモナー
- 331 名前:デフォルトの名無しさん :2006/09/06(水) 03:42:51
- のらーとかキモイ。
- 332 名前:デフォルトの名無しさん :2006/09/06(水) 19:36:41
- めんどくせーこといってんな。
普通は、>>306 みたいなのは、foo のインターフェイスとして用意しておくべきだろ。
速度面は inline 展開されるから、reinterpret_cast と同等の速度になるはず。
class foo {
template< typename Dest >
friend inline Dest * valid_cast( foo * p ) {
STATIC_ASSERT( boost::is_same< Dest, char >::value );
return reinterpret_cast< Dest * >( p );
}
};
//foo * pSrc;
//char * pDest = valid_cast< char * >( pSrc );
- 333 名前:デフォルトの名無しさん :2006/09/06(水) 20:03:48
- コンパイラにエスパーを求める奴が馬鹿なんだよ
- 334 名前:デフォルトの名無しさん :2006/09/06(水) 21:06:46
- それを言ったらおしめえよ
- 335 名前:デフォルトの名無しさん :2006/09/07(木) 01:46:23
- >>333
エスパーなコンパイラ...
欲しいな
- 336 名前:デフォルトの名無しさん :2006/09/07(木) 06:56:19
- >>335
未定義な操作を検出すると自動的かつ瞬時に上司に報告するコンパイラですか?
- 337 名前:デフォルトの名無しさん :2006/09/07(木) 14:41:37
- 時々サンプルコードで、
std::ofstream のインスタンスを作成するときに次のように
std::ofstream ofs("aaa", std::ios::out | std::ios::binary);
std::ios::out フラグを立てているものを見かけるのですが、
何か意味があるのでしょうか?
そもそも std::ios::in フラグとかまで立てられてしまうので、
気持ち悪いです。
- 338 名前:デフォルトの名無しさん :2006/09/07(木) 14:55:13
- ofstreamにおけるios::inは、入力用って意味じゃなく、
「同名ファイルを削除しない」って意味らしいが…。
ttp://www.microsoft.com/japan/developer/library/vclang/_iostream_ofstream.3a3a.ofstream.htm
これは標準なのかね。
- 339 名前:デフォルトの名無しさん :2006/09/07(木) 15:12:48
- >>338 あ、あれ?ほんとだ・・・
なんか俺根本的に標準ファイルストリームの
フラグについて間違った認識してるのかも。
fopen のフラグとの対応がわからん。
- 340 名前:デフォルトの名無しさん :2006/09/07(木) 15:32:32
- >>339
fopen()は割りと変態仕様だから、対応で考えない方がいいよ。
- 341 名前:デフォルトの名無しさん :2006/09/07(木) 16:21:58
- >>338
違う。マイクロソフトの勝手な拡張。
>>339
規格のtable 92に対応が書いてある。
- 342 名前:デフォルトの名無しさん :2006/09/07(木) 16:49:43
- >>337
std::ofstreamのデフォルトのフラグはstd::ios::out。
バイナリ出力を行うためにstd::ios::binaryとORをとってるだけ。
std::ios::inは立たない。
- 343 名前:338 :2006/09/07(木) 23:25:45
- >>341
まじっすか。
MSってこんなとこまで独自拡張してんのかよ('A`)
企画表実際見てみたら、ios_baseフラグとfopenのモードとの対応表があった。
ios::in | ios::outでは"r+"や"w+"と同じ扱いになるらしい。
>>342
立てられる=受身の意味ではなく可能性があるという意味では。
- 344 名前:デフォルトの名無しさん :2006/09/08(金) 00:00:06
- >>343
しかしなぁ、r+とw+では動作が異なるのだが。
- 345 名前:デフォルトの名無しさん :2006/09/08(金) 00:15:26
- 知ったかぶりしてんだよ。
- 346 名前:デフォルトの名無しさん :2006/09/08(金) 00:26:27
- MS独自拡張といえば、fopenに"R"や"S"とか。
- 347 名前:デフォルトの名無しさん :2006/09/08(金) 00:33:11
- >>343
ios::in | ios::out = "r+"
ios::in | ios::out | ios::trunc = "w+"
まで書けっていうんかい。
それぐらい自分で確認してくれ。
- 348 名前:デフォルトの名無しさん :2006/09/08(金) 09:55:18
- >>346
新たにフラグ作るのはいいけど、
既存のフラグに意味を付け足すのはまずいわな。
- 349 名前:デフォルトの名無しさん :2006/09/08(金) 12:10:17
- Javaとの戦いに懲りて、MSの拡張もまともになったかと思ったけど、
C#でのMS色の具合を見ると、まともになっているわけでもでもないなぁ・・
- 350 名前:デフォルトの名無しさん :2006/09/08(金) 13:22:22
- 別にC#で何やってもいいじゃね
- 351 名前:デフォルトの名無しさん :2006/09/08(金) 13:29:50
- C#ってjisとかで規格になってるんでしょ?
何やってもいいとかは言いすぎな感じ・・
それも規格になってないjavaは www.jcp.org コミュニティーで慎重に話し合って
合意を取り付けている。
そういうのからすると、だいぶ異色に映る。
- 352 名前:デフォルトの名無しさん :2006/09/08(金) 13:51:51
- ECMAにversion 1だけ規格通して、
後はやりたい放題ってのは、
以前からMSがやっている手法です。
オープンだそうですw
- 353 名前:デフォルトの名無しさん :2006/09/08(金) 16:00:50
- 漏れは無駄に時間を食う java のやり方が一義的に優れてるとは思わないけどなぁ・・
次世代 Cobol という位置づけを考えると、確かにそれで良いのだろうけど。
- 354 名前:デフォルトの名無しさん :2006/09/08(金) 16:48:50
- >>353 無駄に時間を食うってどういうこと?
バイトコードでってのを指して言ってるのかな?
で、俺は何に期待しているかというと、
断然 C++/CLI ちゃん!
- 355 名前:デフォルトの名無しさん :2006/09/08(金) 16:56:39
- >>354
仕様策定にかかる時間の話。
- 356 名前:デフォルトの名無しさん :2006/09/08(金) 17:11:26
- >>355 あ〜そういうことか。
ごめんな、Java の仕様策定のやり方ってのが
全然分かってないや、俺。
- 357 名前:デフォルトの名無しさん :2006/09/08(金) 17:31:29
- jcp.org行けば分かるよ。
- 358 名前:デフォルトの名無しさん :2006/09/08(金) 19:41:25
- 一致団結して力を見せつけるのか
独走で唯我独尊を見せつけるか
あなたは、どっちがお好みってことよ♪
- 359 名前:デフォルトの名無しさん :2006/09/08(金) 19:50:59 ?2BP(200)
- 一致団結すればいいんだけどね。
- 360 名前:デフォルトの名無しさん :2006/09/08(金) 20:05:08
- C#でそれはナンセンス。C++ならなおさら
いっちゃだめ!
- 361 名前:デフォルトの名無しさん :2006/09/08(金) 20:06:25
-
つ [http://www.jcp.or.jp/]
- 362 名前:デフォルトの名無しさん :2006/09/08(金) 21:13:42
- C#はどうせMS独占言語なんだからMSが勝手にさっさと
突っ走ってくれればいいんじゃね
- 363 名前:デフォルトの名無しさん :2006/09/08(金) 21:31:44
- >>361
開発中のデバドラ落ちと混ざって赤紫になっちゃったけどどうしてくれるのよ!
- 364 名前:デフォルトの名無しさん :2006/09/08(金) 21:39:23
-
はんたーい!
かくめー!かくめー!
かいかくー!
とういつー!
どくそー!
- 365 名前:デフォルトの名無しさん :2006/09/09(土) 00:00:29
- #include<windows.h>
class cwindow
{
int kazu;
int x;
public:
HWND * hWnd;
cwindow(int x) :kazu(x){HWND *hWnd = new HWND[kazu];};
void STATIC_screen(HINSTANCE *);
~cwindow(){delete hWnd;};
};
void cwindow::STATIC_screen(HINSTANCE *hInstance)
{
*hWnd = CreateWindow(
TEXT("STATIC") , TEXT("Kitty on your lap") ,
WS_CAPTION ,
100 , 100 , 200 , 200 , NULL , NULL ,
*hInstance , NULL
);
ShowWindow(*hWnd , SW_SHOW);
}
コンパイルはできますが実行するとCreateWindowのところでエラーを起こしてしまいます。
この部分のどこかが間違っているようですが何処が間違っているのかわかりあmせん
Visual C++ 2005 Express Edition
- 366 名前:デフォルトの名無しさん :2006/09/09(土) 00:07:53
- >>365
cwindow のコンストラクタでメンバの hWnd じゃなくて
ローカル変数 hWnd に new の戻り値を入れているので、
メンバ変数 hWnd の値は不定。そのまま STATIC_screen を
呼び出せば *hWnd が不定なポインタを使うことになって
不正な処理となる。
- 367 名前:デフォルトの名無しさん :2006/09/09(土) 00:09:38
- >>365
環境依存で初心者はスレ違い。↓逝け。
【初心者歓迎】C/C++室 Ver.30【環境依存OK】
http://pc8.2ch.net/test/read.cgi/tech/1156145524/
- 368 名前:デフォルトの名無しさん :2006/09/09(土) 00:37:25
- class Test{
static list<Test*> s_list;
Test()
{
- 369 名前:デフォルトの名無しさん :2006/09/09(土) 00:39:16
- class Test
{
static list<Test*> s_list;
Test()
{
s_list.insert(this);
}
}
と書いて別のところで
グローバルにTest のオブジェクト宣言すると
Testのコンストラクタでs_listが出来取らんのでエラーが出ます
どうしたらいいですか?
- 370 名前:デフォルトの名無しさん :2006/09/09(土) 00:45:56
- >>369
エラーの内容書けよ。
グローバルオブジェクトの初期化順が問題になっているんだろう。
両方ポインタにして、最初に使うときに new で生成するような関数で
ラップするとか?
- 371 名前:デフォルトの名無しさん :2006/09/09(土) 00:52:34
- >>370
エラーは、ヌルポの予感
順番の問題はわかってるけど
順番って制御できないのかな
Testクラスは、グローバルで気軽に作りたいので
listをshared_ptrとかでやってもいいけどboost入れないといけないし
ぬうう
- 372 名前:デフォルトの名無しさん :2006/09/09(土) 00:53:55
- >>371
いや、普通のポインタでも auto_ptr でもいい。
むしろ private な static ポインタ変数に shared_ptr 使う意味がわからん。
- 373 名前:デフォルトの名無しさん :2006/09/09(土) 00:57:28
- それはまったくもってごもっとも。
- 374 名前:デフォルトの名無しさん :2006/09/09(土) 01:00:10
- >>371
static list<Test*>& Test::global_list()
{
static auto_ptr< list<Test*> > p;
if(!p.get()) p.reset(new list<Test*>);
return *p;
}
Test::Test()
{
global_list().insert(this);
}
- 375 名前:デフォルトの名無しさん :2006/09/09(土) 01:07:18
- 普通ポインタだとdeleteタイミングが特定しづらい
auto_ptrでやってみたけど
auto_ptrが作成される前にアクセスしてしまう
auto_ptrは、=で代入できないし(初期のinsert直前でnewで作った物を代入できない)
- 376 名前:デフォルトの名無しさん :2006/09/09(土) 01:08:15
- うお
>>374でやってみます。
ありがとうございます
- 377 名前:374 :2006/09/09(土) 01:09:01
- static 付けた定義はエラーになる。適当に宣言と定義に分けてね。
insert(this) も通らんな。
- 378 名前:デフォルトの名無しさん :2006/09/09(土) 01:09:54
- if( !s_list.get() )
s_list.reset(new ResourceList );
s_list->insert(this);
でいけました。
お騒がせしました。
dクス
- 379 名前:デフォルトの名無しさん :2006/09/09(土) 02:25:08
- >374
static list<Test*>& Test::global_list()
{
static auto_ptr< list<Test*> > p(new list<Test*>);
return *p;
}
もっと言うなら
static list<Test*>& Test::global_list()
{
static list<Test*> l;
return l;
}
じゃ駄目なの?
- 380 名前:374 :2006/09/09(土) 02:56:17
- >>379
生ポインタをベースにして考えていったんで、面倒なことになってた。
そっちのがいいな。
- 381 名前:デフォルトの名無しさん :2006/09/09(土) 06:31:46
- ところで、コンテナに入れることができるための要件って、
代入演算子とデフォルトコンストラクタが定義されていることだっけ?
- 382 名前:デフォルトの名無しさん :2006/09/09(土) 09:23:51
- >>381
いや。コピーコンストラクタが使えれば要件は満たす。
代入演算子もデフォルトコンストラクタもいちおうオプションだが、
多くの操作で必要とされる。
- 383 名前:デフォルトの名無しさん :2006/09/09(土) 09:34:38
- >>382 あれ、コピーコンストラクタだけでよかったのか。
「一応オプションだが多くの操作で必要とされる」
というのは resize() しようと思ったら、とかいうこと?
- 384 名前:デフォルトの名無しさん :2006/09/09(土) 09:37:13
- Containerの要素の要件のCopyConstructibleは、
「コピーコンストラクタを持っている」だけじゃないので注意してね。
t is a value of type T, and u is a value of type const T.
Table 4 -- CopyConstructible requirements
+----------------------------------------------------+
|T(t) t is equivalent to T(t) |
+----------------------------------------------------+
|T(u) u is equivalent to T(u) |
+----------------------------------------------------+
|t.~T() |
+----------------------------------------------------+
|&t T* denotes the address of t |
+----------------------------------------------------+
|&u const T* denotes the address of u |
+----------------------------------------------------+
が必要。
- 385 名前:デフォルトの名無しさん :2006/09/09(土) 09:40:31
- >>383
T::value_typeがAssignableでなければいけません。
Associative containerのキーもAssignable。
- 386 名前:デフォルトの名無しさん :2006/09/09(土) 09:50:56
- ううむ、ちゃんとSTLの規格を読まなきゃ駄目だな、俺。
今までエラーがでたらエラーはいてるテンプレートの定義を見て
「おお、このテンプレートを特殊化しようとしてエラーか。
じゃ、このメソッド(もしくは演算子)宣言しておかなきゃな」
なんて行き当たりばったりでやってたからなぁ。
「ええい、めんどくさい、無意味に boost::shared_ptr でくるんでやれ」
とか逃げたこともしばしば。
- 387 名前:デフォルトの名無しさん :2006/09/09(土) 10:54:28
- fstreamのファイル名がstd::stringというのはイヤガラセですかねえ
- 388 名前:デフォルトの名無しさん :2006/09/09(土) 11:17:25
- >>387
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1934.html
- 389 名前:386 :2006/09/09(土) 12:14:17
- すんまそん、よく考えたら STL のスレッドがあったんですよね。
なんかスレ違いっぽいんでそっちいきますは。
- 390 名前:デフォルトの名無しさん :2006/09/09(土) 12:43:38
- 全然スレ違いじゃない
- 391 名前:デフォルトの名無しさん :2006/09/09(土) 12:52:45
- C++ は初心者スレとかいろいろあって、
「これはコンパイラ依存の話だから」
「これは初心者っぽいかなぁ」
とかかんがえるのがマンドイ
- 392 名前:デフォルトの名無しさん :2006/09/09(土) 12:58:53
- まんどいだけならともかく、初心者にはそもそも区別がつかないっぽい。
- 393 名前:デフォルトの名無しさん :2006/09/09(土) 14:17:48
- JavaやRUBYなら簡単なのに!!!
- 394 名前:デフォルトの名無しさん :2006/09/09(土) 14:26:00
- キミにはお似合いだよ。
- 395 名前:デフォルトの名無しさん :2006/09/09(土) 15:45:20
- C++書くマになりたいんですが、
どんな仕事でC++使うんですか?
- 396 名前:デフォルトの名無しさん :2006/09/09(土) 15:46:41
- 比較的パフォーマンスが要求されるシステム
- 397 名前:デフォルトの名無しさん :2006/09/09(土) 18:14:18
- >>395
昔はC=マイコン系、C++=GUIなイメージだけど
C++=工場系(漏れの仕事もそうだが、工場の機械をWinで操る、組み込みC++も増える希ガス)
スクリプト=プログラマ
ブログ、Wiki、サーバ作る=SE
ネットわからない=ITこんさるたんと
てなると思う。初めHTMLは素人用だったが、いまややこしくなってきたね
- 398 名前:365 :2006/09/09(土) 21:22:47
- cwindow(int x) :kazu(x){hWnd = new HWND[kazu];};
dクス
- 399 名前:デフォルトの名無しさん :2006/09/10(日) 00:47:23
- C++を勉強しようと思うんですけど
まずCからちゃんと覚えたほうがいいですかね?
- 400 名前:デフォルトの名無しさん :2006/09/10(日) 00:57:37
- 仕事ではPHP+DBとかだけのヘタレプログラマだけど
時々趣味で自作アプリとかC++(VC++&MFC)で作ってるけど
流石に仕事で使うのは大変そうだなーと思うよ。
とても自分には無理そう。というかC++で仕事してる人尊敬するよ。
- 401 名前:デフォルトの名無しさん :2006/09/10(日) 01:02:29
- 個人的にはいきなりC++でもいいと思うけど、
構造化手法のことはよく理解しといたほうがいいような気がする
- 402 名前:デフォルトの名無しさん :2006/09/10(日) 01:19:00
- C++がある程度分かる様になったら、他の言語を勉強した時、本当にすんなり覚えられる。
Rubyなんか楽しくて仕方ないし、PHPは普通にいきなり使えた。まぁスクリプト言語を引き合いに出してもアレだが。
でも高級言語でC++程難解な言語は無いでしょう?
- 403 名前:デフォルトの名無しさん :2006/09/10(日) 01:46:42
- C++使いだけど、Haskellに苦労してる。
- 404 名前:デフォルトの名無しさん :2006/09/10(日) 01:47:14
- >>402 高級言語と思うから難解なのでは?
オブジェクト指向アセンブラと思えばどうだろうか。
- 405 名前:デフォルトの名無しさん :2006/09/10(日) 01:49:46
- イベントの種類とパラメータと戻り値をひとまとめにしてクラスで
表現しようと思い、以下のようにしてみました。
template <class paramType, class resultType>
class Event {
int type_;
paramType param_;
mutable resultType result_;
public:
// paramType を取るコンストラクタとかもろもろ...
const paramType& Param() const { return param_; }
const resultType& Result() const { return result_; }
void SetResult(const resultType& result) const { result_ = result; }
};
イベントを受け取るハンドラー側は、
void Handler(const Event& event) {
resultType foo;
// ... 処理 ...
event.SetResult(foo);
}
となるのですが、あんまり直感的じゃないですよね。かと言って、
ハンドラーを void Handler(Event& event); とするのは気持ち悪いなぁ
というところで悩んでます。妙案はござらぬか。
- 406 名前:デフォルトの名無しさん :2006/09/10(日) 01:56:04
- >>405
そもそも戻り値までまとめるところがダメだと思う。
- 407 名前:デフォルトの名無しさん :2006/09/10(日) 02:45:32
- >>405
なんで無理矢理constにしたいのかが分からん。
Eventは純粋に起きた出来事を記述するだけにとどめるべき、と考えるなら、
template<class eventType, class resultType>
class EventArgs
{
const eventType event_;
resultType result_;
//略
};
void Handler(EventArgs &args)
{
resultType foo;
//処理
args.setResult(foo);
}
くらいじゃダメ?
- 408 名前:デフォルトの名無しさん :2006/09/10(日) 04:01:57
- そこまで無理やりconstにして、結局返り値がmutableなのは典型的な駄目コードだろう。
constの前提が全部ぶっ壊れるんだから、クラス外部に影響の出ない本当に一部の例外以外は
使っちゃ駄目ぽだよ。
非constと同じコードが生成されるから、性能面でもまったくメリットないし。
>>407程度でいいと思う。
受け取ったイベントに返り値を運ばせるのは賛否が分かれそうだけど、
イベントの種類によっては、それなりに現実的なんじゃないかな。
実は全部intか、もっと言うとboolで十分だったなんてオチは、いかにもありそうだけど。
- 409 名前:デフォルトの名無しさん :2006/09/10(日) 08:21:59
- >>403 パラダイム違いすぎ
それはそうと、 const だけで3杯くらいご飯食えるよな。
const のおかげで不用意な代入のバグを回避できたことも多いし。
BOOST_STRONG_TYPEDEF も不用意な代入によるバグを回避するのに
ずいぶん役だってくれたな。実際にはそれをちょっと自分用に
カスタマイズしたマクロを使ってるけど。
とかくと、boost 厨死ね、このクズが、ってののしられるんだろうな。
快感。
- 410 名前:デフォルトの名無しさん :2006/09/10(日) 08:26:45
- >>407
引数から const を外すなら、そうするしかないですよね、やっぱり。
どうも const に拘りすぎて、const 馬鹿になっていたようです。
>>408
mutable なメンバ変数がインタフェースになってるってのも、確かに
気持ち悪いんですよね。>>407 の方向でやってみます。
- 411 名前:デフォルトの名無しさん :2006/09/10(日) 08:53:04
- std::auto_ptr<int> func(void){
std::auto_ptr<int> p(new int);
return p;
}
void test(void) {
std::auto_ptr<int> p = func();
}
こうやったとき、new で確保したオブジェクトの所有権は
戻り値用の一時オブジェクトを介して(実際はRVOが働く?)
ちゃんと移動されて test() から抜けた時点で解放されるんですよね?
- 412 名前:デフォルトの名無しさん :2006/09/10(日) 09:24:42
- >>411 うん。
- 413 名前:デフォルトの名無しさん :2006/09/10(日) 09:32:13
- >>412 よかった。これで心おきなく
auto_ptr<T> を戻り値として使えます。
ポインタを生のまま返すと、
「たのむ〜、このポインタ、ちゃんと解放してくれよ」
って祈るしかないし。
- 414 名前:デフォルトの名無しさん :2006/09/10(日) 10:49:27
- 文字列の$と$で囲まれた部分(「あいうえお$かきくけこ$さしすせそ」の「かきくけこ」)を取り出したいのですが
「最初の$以降の文字列」はstrstrで取り出すとして
「後の$以降の文字列」をそれから取り除くにはどうしたらいいでしょうか?
mbsnbcpy使うのかな?
- 415 名前:デフォルトの名無しさん :2006/09/10(日) 10:54:43
- >>414
自分で試せ。それ C++ なのか?
- 416 名前:414 :2006/09/10(日) 11:01:02
- 追記
もとの文字列、切り出し後の文字列ともにchar*型ですが
双方unsigned char*にキャストしてmbsnbcpy使うとなぜか
切り出し後の文字列が空文字列になってしまいます。
- 417 名前:デフォルトの名無しさん :2006/09/10(日) 11:03:33
- >>416
エスパー募集じゃなければソース貼れ。
C++ 関係ないなら別スレに逝け。
- 418 名前:デフォルトの名無しさん :2006/09/10(日) 11:06:43
- >>411
その辺の話はExceptional C++に詳しく載ってるよ。
全く同じことやってる例がある。
- 419 名前:414 :2006/09/10(日) 11:10:05
- char[100] motobun;
strcpy(motobun,"あいうえお$かきくけこ$さしすせそ")
char[100] kiribun;
kiribunにmotobunの中の「かきくけこ」を入れるということでお願いします。
- 420 名前:デフォルトの名無しさん :2006/09/10(日) 11:13:24
- >>419
エスパー募集じゃなければソース貼れ。
C++ 関係ないから別スレに逝け。
- 421 名前:デフォルトの名無しさん :2006/09/10(日) 11:24:07
- memcpyの質問というより「NULL+6がどうなるか」という質問になるかもしれませんが
memcpy(NULL + 6, "abc", 4);
これはどうなりますか?
memcpy(NULL, "abc", 4);
と解釈されますか?
- 422 名前:デフォルトの名無しさん :2006/09/10(日) 11:29:54
- >>421
解釈されない。
何が起きるか分からない。
- 423 名前:デフォルトの名無しさん :2006/09/10(日) 11:30:03
- >>421
ヌルポインタ + 6 なら未定義動作。
NULL + 6 は 0 + 6 で、ただの整数 6 になってコンパイルエラーになる。
- 424 名前:デフォルトの名無しさん :2006/09/10(日) 11:30:04
- いやアドレス0x00000006へコピーしようとする。
いずれにせよ、不正アクセスであぼーん。
- 425 名前:デフォルトの名無しさん :2006/09/10(日) 11:31:46
- >>424 でたらめ言うな。
- 426 名前:デフォルトの名無しさん :2006/09/10(日) 11:35:00
- >>419
char *p = strchr(s1, '$');
char *q = strchr(p+1, '$);
memcpy(buf, p, q-p);
buf[q-p] = '\0';
- 427 名前:デフォルトの名無しさん :2006/09/10(日) 11:37:35
- 425の考えをキボン。
- 428 名前:425 :2006/09/10(日) 11:40:09
- >>427 ん? >>423 に同意だな。コンパイルエラーも確認した。
- 429 名前:デフォルトの名無しさん :2006/09/10(日) 11:40:53
- >>423-425
C++でNULLが0にdefineされているというのは、実際にはほぼ間違いないけど
規格的にはどうなの?
Cでは(void *)0もアリでしょ。
で、もし、(void *)0な処理系が存在するなら
(void *)0 + 6 という値になって、(gcc以外なら)voidへの演算エラーになるよね。
いずれにしろ、(gcc以外では)>>424にはならない。
もちろん、ほぼ全ての処理系は>>423だろうけど。
- 430 名前:デフォルトの名無しさん :2006/09/10(日) 11:41:07
- 423は矛盾がある。
NULL + 6 は 0 だと言い張るのにmemcpy(0, "abc", 4);が未定義動作だと言う。
もし NULL + 6 が 0 なら、アドレス0x00000000へコピーしようとするよ。
- 431 名前:デフォルトの名無しさん :2006/09/10(日) 11:41:14
- >>427
425じゃないけど
C++だとNULLは#define NULL 0と定義されているのが普通。
だからNULL + 6 は0 + 6となり、整数畳み込みで6になる。
で、6からポインタへの暗黙の変換は存在しないのでエラー。
ようするに>>423
- 432 名前:デフォルトの名無しさん :2006/09/10(日) 11:44:10
- >>430
> NULL + 6 は 0 だと言い張るのにmemcpy(0, "abc", 4);が未定義動作だと言う。
だれもそんなこと言ってない。
- 433 名前:デフォルトの名無しさん :2006/09/10(日) 11:44:49
- >NULL + 6 は 0 だと言い張るのに
誰がそんな妄言、言い張ってるんだ?
- 434 名前:デフォルトの名無しさん :2006/09/10(日) 11:46:16
- >>429
C++ では (void*)0 は NULL の中身にはなり得ない。
- 435 名前:デフォルトの名無しさん :2006/09/10(日) 11:48:32
- >>421がなんでこんな事を聞きたかったのかに話を戻そう
- 436 名前:デフォルトの名無しさん :2006/09/10(日) 11:52:54
- >>434
仕様に書いてある?
- 437 名前:デフォルトの名無しさん :2006/09/10(日) 11:53:40
- 出くわした場面は以下です。memcpy()の前にif(buf)が必要ですか?
main(){
char *buf = NULL;
if(何か){
buf = (char*)malloc(8);
}
//ここにif(buf)が必要?
memcpy((void*)(buf + 6), "\r\n", 2);
free(buf);
- 438 名前:デフォルトの名無しさん :2006/09/10(日) 11:54:37
- C は void* から別のポインタへの暗黙のキャストがあるから NULL は (void*)0 の定義も許されてる。
C++ はそれができないから NULL は 0 と定義するしか無いという仕様に変更された。
- 439 名前:デフォルトの名無しさん :2006/09/10(日) 11:57:07
- 「何か」の部分に0を入れてテストしたら実行時エラーになりました。
アドレス0x00000006へコピーしようとする の説が正しいように思いました。
- 440 名前:デフォルトの名無しさん :2006/09/10(日) 11:57:44
- >>436
18.1.3 が NULL マクロについての記述。
"The macro NULL is an implementation-defined C++ null pointer constant in this International Standard (4.10)."
これに注釈で
"Possible definitions include 0 and 0L, but not (void*)0."
と明記されている。
- 441 名前:デフォルトの名無しさん :2006/09/10(日) 12:00:21
- >>437 必要。
>>439 それは気の迷いということにしておけ。
- 442 名前:デフォルトの名無しさん :2006/09/10(日) 12:02:28
- >>440
ありがとう。
- 443 名前:デフォルトの名無しさん :2006/09/10(日) 12:02:30
- 441そうだね。
- 444 名前:デフォルトの名無しさん :2006/09/10(日) 12:06:13
- >>439
「NULL + 6」と
「(char *)NULL + 6」は
全然違うだろ。
皆、おまえが最初に書いた前者を前提に話していたのに。
最初からそう書けよ。
- 445 名前:デフォルトの名無しさん :2006/09/10(日) 12:07:08
- >>438
C では (void*)0 がヌルポインタ定数として( 0 と同等に)機能すると特別扱いされている。
そのおかげで、データポインタからの変換が認められていないはずの
関数ポインタも (void*)0 でヌルが設定できたりする。
- 446 名前:デフォルトの名無しさん :2006/09/10(日) 12:07:55
- > 「(char *)NULL + 6」は
なんだか目の悪いやつがいるようだな。
- 447 名前:デフォルトの名無しさん :2006/09/10(日) 12:14:05
- >>446
それはおまえのことか?
>>437をちゃんと見てるんだよな?
- 448 名前:デフォルトの名無しさん :2006/09/10(日) 12:17:10
- スマンカッタ
- 449 名前:デフォルトの名無しさん :2006/09/10(日) 12:18:27
- まあ初心者がヌルポインタと NULL (ヌルポインタ定数)を混同するのはわからんでもない。
- 450 名前:デフォルトの名無しさん :2006/09/10(日) 12:37:18
- 意味があるのかわからん議論だな
- 451 名前:デフォルトの名無しさん :2006/09/10(日) 12:56:20
- どっちでもいーっしょじゃーん
- 452 名前:デフォルトの名無しさん :2006/09/10(日) 13:30:31
- 確かにCだとNULLは(void *)0なので
ポインタに対する整数加算は
ポインタの指す型のサイズ倍のアドレス増加となり
sizeof (void)は得られないので
NULL+6はエラーだが
C++だとNULLは0だからNULL+6は整数6で、ポインタではなくなるな
- 453 名前:デフォルトの名無しさん :2006/09/10(日) 13:36:39
- だから何?
- 454 名前:デフォルトの名無しさん :2006/09/10(日) 13:40:18
- >>452
C でも NULL を 0 と定義するのは可能。
- 455 名前:デフォルトの名無しさん :2006/09/10(日) 13:47:27
- >>452
てか、ちょっと前のレスで既に何度も言われてることなんですけど。
お前のような奴を知識披露厨と言うんだろうな。
職場等でウザがられてない?
- 456 名前:452 :2006/09/10(日) 14:00:52
- >>437以降を見ずに書いてたが
なんだ、質問自体が違ったのか
- 457 名前:デフォルトの名無しさん :2006/09/10(日) 14:16:59
- >>437以前に、既に何度も同じ事がかかれているわけだが。
- 458 名前:452 :2006/09/10(日) 14:24:27
- >>457
だから「確かに」で単にまとめてただけなんだが。必然的に繰り返しになる。
それにこのスレはそもそも殆どの話題が以前出たことがあることばっかりで
繰り返しを楽しむスレなんじゃないの?w
- 459 名前:デフォルトの名無しさん :2006/09/10(日) 14:28:52
- まあどうでもいい
- 460 名前:デフォルトの名無しさん :2006/09/10(日) 14:30:18
- STLつかうと一気に実行ファイルサ(ry
- 461 名前:デフォルトの名無しさん :2006/09/10(日) 14:33:19
- >>458
まとめると言うほどの内容は無いようですが。
- 462 名前:デフォルトの名無しさん :2006/09/10(日) 14:36:01
- がんばって素直にごめんなさいが言える大人になろうね。
- 463 名前:452 :2006/09/10(日) 14:54:10
- ごめんなちゃい
- 464 名前:デフォルトの名無しさん :2006/09/10(日) 15:05:20
- ごめんね
- 465 名前:デフォルトの名無しさん :2006/09/10(日) 16:48:36
- 無理やり話題のレベル上げようとするの禁止
- 466 名前:デフォルトの名無しさん :2006/09/10(日) 17:10:19
- じゃあ以降レベルは腹ばい気味で。
- 467 名前:デフォルトの名無しさん :2006/09/10(日) 17:45:06
- C++ でクラスを書いて、コピーができないようにした。
そんで、本当にコピーできないことを確認するために、
テストコードを書いて、そのテストを自動化したい。
そんなこと C++ だけでできるぅー?
- 468 名前:デフォルトの名無しさん :2006/09/10(日) 17:51:29
- 質問したい事があります。
file1.h
file2.h
file3.h
とヘッダを作成し、
--file1--------
#include "file2.h"
--file2--------
#include "file3.h"
--file3--------
#include "file1.h"
--main-------
#include "file1.h"
#include "file2.h"
#include "file3.h"
とインクルードさせるとfile1で宣言した型がfile3でintと仮定されてしまいます。
file1,2,3ともお互いに宣言した型をメンバ内で使っている状態です。
多重インクルードは回避してあります。
なんとなく、型を認識する前に別のファイルでの型が書かれている部分を認識しようとしているのかなぁ…と思うのですが、
これを何とか通したいのですが何か方法があれば教えていただきたいです。
- 469 名前:デフォルトの名無しさん :2006/09/10(日) 17:52:04
- >>467
コンパイルエラーを捕らえることになるから C++ だけじゃできなさそうだねぇー。
- 470 名前:デフォルトの名無しさん :2006/09/10(日) 17:54:36
- >>468
C++ では int の仮定なんてしないはず。何を見てそう思ったの?
「宣言した型」ってのもよくわからん。 class か enum か typedef か、とか。
問題が再現するコード貼ってくれると話が早い。
- 471 名前:デフォルトの名無しさん :2006/09/10(日) 18:04:47
- ファイル入出力を<<演算子で行うと、どうにも遅くて困ってます。
結局大きめのファイルを扱うとなると、Cに戻るか、小細工が必要なんでしょうか?
<<演算子による操作自体は、読みやすくて好きなのですが
- 472 名前:デフォルトの名無しさん :2006/09/10(日) 18:07:01
- >>471
自分で<<を定義し、その中でCのfprintf()とか使えば速くなるじゃん。
sync_with_stdioとか必要になるが。
- 473 名前:デフォルトの名無しさん :2006/09/10(日) 18:13:06
- ありがとうございます。ちょっと残念ですが、fprintf等、Cの関数を使うことにします。
- 474 名前:デフォルトの名無しさん :2006/09/10(日) 18:16:04
- >>470
VS2005を使ってまして、エラーで
[ 型指定子がありません - intと仮定しました。 メモ: C++は int を既定値としてサポートしていません ]
と、出ています。よくみたら>>470さんの言うように仮定してないみたいです。
--file1.h-------
#include "file2.h"
class FILE_1 { void func(FILE_2& _file){ ... } };
--file2.h-------
#include "file3.h"
class FILE_2 { ... };
--file3.h-------
#include "file1.h"
class FILE_3 { ... };
file1でFILE_2が型として認識されていない状態です。
- 475 名前:デフォルトの名無しさん :2006/09/10(日) 18:23:31
- その手のエラーはたいてい
型情報が必要な所でエラーになってる
(関数の戻り値の型を書くのを忘れているとか)事が多い
Cの規格では省略時はintとみなされる→C++はダメ
- 476 名前:デフォルトの名無しさん :2006/09/10(日) 18:28:24
- >>474
参照を使うだけなら、ヘッダのインクルードを前方宣言で置き換えるといい。
- #include "file2.h"
+ class FILE_2;
- 477 名前:デフォルトの名無しさん :2006/09/10(日) 18:35:47
- >>474
なんだこれ
循環includeで
include guardなし?
どうしてFILE_2を参照してるところに到達できてるんか
- 478 名前:デフォルトの名無しさん :2006/09/10(日) 18:37:40
- いちおう >>468 で「多重インクルードは回避してあります。」と言っている。
コードに対してコンパイルエラーが出るってことは、循環 include にはなっていないんだろう。
- 479 名前:デフォルトの名無しさん :2006/09/10(日) 18:48:40
- >>474
#include "file2.h"をすると
file2でまず多重インクルード防止のdefineでもされてから
(まだclass FILE_2宣言に到達していない)
#include "file3.h"が実行され
その中で#file include "file1.h"が実行され
file1.hの中の#include "file2.h"は
すでにdefine済みということで通過。
class FILE_1に来たときはFILE_2はまだ宣言されてない。
>>476方式で。
直接宣言が嫌なら<iosfwd>みたいに参照のみ用ヘッダ書くってのもありか
- 480 名前:デフォルトの名無しさん :2006/09/10(日) 18:58:42
- [ 認識できない型 'name::Class_name ' が使われています。 ]
とエラーになってしまいました。
あーもう、こんがらがってきました('д')
そもそもこんな設計になる時点で良くない気がします。
全部見直してみます。どうもお騒がせしました。
- 481 名前:デフォルトの名無しさん :2006/09/10(日) 19:04:38
- >>480
それがいいだろうね。
整理し直してヘッダを書き直してみるのが、結果的に一番よさげな希ガス。
- 482 名前:デフォルトの名無しさん :2006/09/10(日) 19:06:48
- namespace を超える前方宣言は、 namespace name { class Class_name; } って感じに
しないと駄目だよ。
- 483 名前:デフォルトの名無しさん :2006/09/10(日) 19:09:05
- namespace::Class_nameじゃダメなん?
- 484 名前:デフォルトの名無しさん :2006/09/10(日) 19:10:46
- つーか、
class name::Class_name;
でいい
- 485 名前:デフォルトの名無しさん :2006/09/10(日) 19:11:40
- >>480
相互依存の排除には interfaceと派生した実装クラスに分離するって手があるよ
今回の場合に当てはまるか分からんけど
ifile2.h:
class IFILE_2 {};
file1.h:
#include "ifile2.h"
class FILE_1 { ... IFILE_2を参照 };
file2.h:
#include "ifile2.h"
class FILE_2: public IFILE_2 {};
- 486 名前:デフォルトの名無しさん :2006/09/10(日) 19:44:21
- namespace name {
class FILE_1;
class FILE_2 { ... };
}
FILE_1も同じ name でnamespaceしてます。
こんな感じで前方宣言してたのですが、よろしくないでしょうか?
- 487 名前:デフォルトの名無しさん :2006/09/10(日) 19:48:23
- >>486
コンパイルできるんならいいんじゃね?
コンパイルできないならエラーメッセージ貼れ。
- 488 名前:デフォルトの名無しさん :2006/09/10(日) 19:55:51
- >>487
エラーは>>480で怒られたものです。
[ 認識できない型 'name::Class_name ' が使われています。 ]
そして以下のようにすると、
class name::FILE_1;
namespace name {
class FILE_2 { ... };
}
[ 'name' : 識別子がクラス名でも名前空間でもありません。 ]
と怒られてしまいます。
VS使っているのですが、:: でインテリセンス出てくるんですが…
- 489 名前:デフォルトの名無しさん :2006/09/10(日) 20:02:15
- そりゃnameがnamespace名であることを知らなきゃ、そういうメッセージになるわな。
つーか、>>482がやり方説明してるだろ。
- 490 名前:デフォルトの名無しさん :2006/09/10(日) 20:05:40
- >>482でやると>>486と同じエラーになります。
となると、>>486でもコード的には間違いではないと思うのですが。
やっぱり設計しなおしてみます。書き込んでくださったみなさん、お手数おかけしました。
- 491 名前:デフォルトの名無しさん :2006/09/10(日) 20:09:33
- それ絶対別の場所なりでなんか変なことしてるだろ。
そうじゃなきゃ、そんなエラー出るわけないし。
あ、関係ないとは思うけど、
(たぶん今の言語仕様では) typedef名とclass内classは
どうやっても先行宣言できないから。
- 492 名前:デフォルトの名無しさん :2006/09/11(月) 03:17:08
- namespace name1{
class FILE_1;
}
namespace name2{
class FILE_2{ name1::FILE_1* f1; };
}
namespace name1{
class FILE1{ };
}
上はVC2005でやったら通るけど、こういうことじゃない?
- 493 名前:デフォルトの名無しさん :2006/09/11(月) 09:21:07
- >>452
> 確かにCだとNULLは(void *)0なので
違う。0です。
(void *)0とすることも可能と併記されている。
- 494 名前:デフォルトの名無しさん :2006/09/11(月) 09:25:08
- >>449
あなたのは見当違いです。
規格では、
null pointer constant
null pointer value
しかインデックスには出てこない。
null pointer constantの話をしているところに
"null pointer"という単独の単語は出てこない。
NULLマクロとの関係は>>440にある通り。
- 495 名前:デフォルトの名無しさん :2006/09/11(月) 09:25:41
- >>493 >>445,>>454 で既出。「0です」と言い切るのも間違い。
- 496 名前:デフォルトの名無しさん :2006/09/11(月) 09:29:50
- >>492
それで問題ない。VC2005以外でも。
- 497 名前:デフォルトの名無しさん :2006/09/11(月) 09:30:19
- このスレどころか世界中でさんざん既出なので、
もうこれでぬるぽのはなしはおしまいにしてもらえませんか?
http://www.kouno.jp/home/c_faq/c5.html
- 498 名前:デフォルトの名無しさん :2006/09/11(月) 09:40:59
- >>495
規格上、0です。
(void *)0も可能と併記。
- 499 名前:デフォルトの名無しさん :2006/09/11(月) 09:46:00
- >(void *)0
だーかーらぁー
- 500 名前:デフォルトの名無しさん :2006/09/11(月) 09:47:27
- >>498
C99 の定義は以下のとおり。
"An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant."
たとえば 0L も、 gcc の __null もヌルポインタ定数であり、 NULL の中身になれる。
■過去ログ置き場に戻る■
1- 前250
次250
最新50