C++相談室 part43

このエントリーをはてなブックマークに追加
1v(^・^)v
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
テンプレートライブラリ(STL含む)に関する質問は
専用の別スレにお願いします。
IDE(VC++など)などの使い方の質問もその開発環境のスレに
お願いします。

前スレ part41(実質42)
http://pc8.2ch.net/test/read.cgi/tech/1120190961/

過去スレ、関連スレ、関連リンクなどは >>2-20 あたり
2v(^・^)v:2005/08/15(月) 22:52:34
3v(^・^)v:2005/08/15(月) 22:53:14
4v(^・^)v:2005/08/15(月) 22:54:01
5v(^・^)v:2005/08/15(月) 22:54:58
■基本■
[C++ FAQ]
 http://www.parashift.com/c++-faq-lite/
 http://www.bohyoh.com/CandCPP/FAQ/ (日本語)
  Cとその仕様を比較しながらの解説なので分かりやすい。
  ***** 質問の前に必ずこの二つに目を通してください *****

[禿 Stroustrup]
 http://www.research.att.com/~bs/
[C++ International Standard]
 http://www.kuzbass.ru/docs/isocpp/
 http://www.kuzbass.ru/docs/ansi_iso_iec_14882_1998.pdf
 http://www.iso.org/iso/en/CatalogueDetailPage.CatalogueDetail?CSNUMBER=38110&ICS1=35&ICS2=60&ICS3=
[JTC1/SC22/WG21 - C++]
 http://www.open-std.org/jtc1/sc22/wg21

[C/C++ Users Journal]
 http://www.cuj.com/
[cppll (ML)]
 http://www.trickpalace.net/cppll/ (日本語)
6v(^・^)v:2005/08/15(月) 22:55:40
7v(^・^)v:2005/08/15(月) 23:02:58
8v(^・^)v:2005/08/15(月) 23:03:47
9v(^・^)v:2005/08/15(月) 23:04:44
10v(^・^)v:2005/08/15(月) 23:05:37
■関連スレ■
【C++】template 統合スレ -- Part6
http://pc8.2ch.net/test/read.cgi/tech/1101384692/
C/C++の宿題を片づけます 49代目
http://pc8.2ch.net/test/read.cgi/tech/1123661447/
C/C++でのWindowsPrograming議論スレ(質問お断り)
http://pc8.2ch.net/test/read.cgi/tech/1049790146/
managed C++ やろうぜ!!
http://pc8.2ch.net/test/read.cgi/tech/1014486422/
ATL/WTL Part3
http://pc8.2ch.net/test/read.cgi/tech/1095442366/
11デフォルトの名無しさん:2005/08/15(月) 23:27:14
STLつかうと一気に実行ファイルサイズが10倍に?!
12デフォルトの名無しさん:2005/08/15(月) 23:28:17
環境によるだろ。
俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力
ランタイムを使用するようにして使っているが、例えばstd::vectorを
使っても使わない時と比べ10Kほどしか増えない。
13デフォルトの名無しさん:2005/08/15(月) 23:30:00
すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。
14デフォルトの名無しさん:2005/08/15(月) 23:31:55
C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。
とかいうエラーが出るんだけどこれってどうすればいいの?
15デフォルトの名無しさん:2005/08/15(月) 23:33:26
#include <stdafx.h>

後氏ね。
16デフォルトの名無しさん:2005/08/15(月) 23:47:39
>>13
嘘は言ってないな。
17デフォルトの名無しさん:2005/08/15(月) 23:48:57
>>15
言葉が悪いな。それで教えているつもりか。
まぁヒントぐらいにはなったな。
うむごくろう。
18>>1-10:2005/08/15(月) 23:53:07
>>11-15,17


後半(>>6-10)は携帯から書き込んだわけだが…スレ立ての時に限っては
もうちょっと連投規制を緩くして欲しいな。
19デフォルトの名無しさん:2005/08/16(火) 01:27:43
>>1
20デフォルトの名無しさん:2005/08/16(火) 04:27:22
wstringの文字列で、指定したn文字目の文字が何バイト文字かを調べたいのですが
どうしたらよいでしょうか。
21デフォルトの名無しさん:2005/08/16(火) 04:59:51
>>20
ま た お ま え か !
22デフォルトの名無しさん:2005/08/16(火) 07:28:03
n文字目をいきなり判定することは出来ない。
先頭から順番にチェックしていくしかない。
23デフォルトの名無しさん:2005/08/16(火) 09:51:56
あるだろその関数・・・
24デフォルトの名無しさん:2005/08/16(火) 11:15:25
wstringならそもそも格納が文字単位なので
普通にインデックスとればそれが文字位置。

あとwstringはワイド文字で格納されているので
あえて言うなら全部sizeof(wchar_t)バイト文字。
その文字がマルチバイト文字に変換して何バイトかっていうのなら
エンコードによるし。UTF-8で日本語なら3バイトが多いとか。
25デフォルトの名無しさん:2005/08/16(火) 12:41:32
>>24
エンコードがUTF-16だった場合。
26デフォルトの名無しさん:2005/08/16(火) 13:00:48
ウインドウ内で画像を移動させたいのですが何度やっても上手くいきません。
色々調べてみましたが結局詰まってしまったのでご助言をお願いします。

以下描画部分(メッセージ処理の一部)を書きますが、それ以外で必要な部分があれば言ってください。
case WM_CREATE:
 SetLayeredWindowAttributes(hWnd, RGB(255, 0, 255), 0, LWA_COLORKEY);          //紫を透明に
 SetTimer(hWnd,1,100,NULL);
 break;

case WM_PAINT:
 hdc = BeginPaint(hWnd, &ps);
 ExtFloodFill(hdc, 1, 1, RGB(255, 255, 255), FLOODFILLSURFACE);
 hbmp = (HBITMAP)LoadImage(hInst, "BITMAP1",IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
 hdc_mem = CreateCompatibleDC(hdc);
 SelectObject(hdc_mem, hbmp);
StretchBlt(hdc, POSX, 0, 100, 100, hdc_mem, 0, 0, 100, 100, SRCCOPY);             //POSXは変動
 EndPaint(hWnd, &ps);
 break;

--続く
27デフォルトの名無しさん:2005/08/16(火) 13:01:52
続き--

case WM_TIMER:
 hdc = BeginPaint(hWnd, &ps);
 ExtFloodFill(hdc, 1, 1, RGB(255, 255, 255), FLOODFILLSURFACE);
 hbmp = (HBITMAP)LoadImage(hInst, "BITMAP1",IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
 hdc_mem = CreateCompatibleDC(hdc);
 SelectObject(hdc_mem, hbmp);
StretchBlt(hdc, POSX, 0, 100, 100, hdc_mem, 0, 0, 100, 100, SRCCOPY);             //POSXは変動
 EndPaint(hWnd, &ps);
 break;

紫を透明色にし、ウインドウのメニュー・枠線を消して画像だけを表示させることをしようとしています。
WM_TIMERは何度も通っているのを確認、POSXの値は変わっています。
一度WM_PAINTで描画するとどうやってもウインドウ内の位置は変わらないようです。
環境はWindowsXP VC++.NETです。
28デフォルトの名無しさん:2005/08/16(火) 13:07:41
>>24
とりあえずatとかsubstrでn文字目を取り出すことができるっぽいことは発見しました。
実は簡単なテキストエディタを作ろうと思っているのですが、
折り返し部分(ウィンドウ幅に合わせて自動で折り返したい)やカーソルの指している部分が
何バイト文字で先頭から何ドット目であるかなどを調べて、
その部分で文字列を分けたり挿入したりしたいです。
結局そういったことをするにはテキストを何型で持ってればよいのでしょうか。
あちらを立てればこちらが立たずという感じでワケがわからなくなってきました。
29デフォルトの名無しさん:2005/08/16(火) 13:09:00
>>26-27
スレ違い、なんだけども、誘導先のスレがわからない。
↓これでいいか?
★初心者にVisual C++を教えるスレ★ Part20
http://pc8.2ch.net/test/read.cgi/tech/1120222322/
30デフォルトの名無しさん:2005/08/16(火) 13:12:30
>>29
誘導ありがとうございます。
そちらに書いてきます。
31デフォルトの名無しさん:2005/08/16(火) 13:16:50
>>28
wstring で持ってて「こちらが立たず」という例は、どれだ?
3226-27:2005/08/16(火) 13:56:42
誘導先のスレにて解決できましたので報告までに。
33デフォルトの名無しさん:2005/08/16(火) 13:58:49
>>26
WM_PAINTに応答するとき以外はBeginPaint, EndPaintを呼んでは駄目だ。
どうせ更新領域が空でなにも描画されてないんだろ。
3428:2005/08/16(火) 14:19:15
>>31
もちろん私が知らないというだけできちんと方法はあるのかもしれませんが、
例えばマウスクリックした位置にエディタのカーソル(キャレット)を移動し、
そこに文字列を挿入したいとします。
マウスの座標を取得し「その座標の位置にある文字が何文字目であるか」が
取得できればinsertとか使えると思うのですが、
wstringの場合、文字列の先頭から1バイト文字かマルチバイト文字かを判断し
1バイトなら8ドット、2バイトなら16ドットのように足していって
座標値を割り出すことができないのでマウス座標との判定ができなそう、、、など。

あとはIMEで漢字変換したとき、WM_CHARが連続して流れてくるみたいなんですが、
WPARAMをwstringの文字列に突っ込んでもうまくいかないようで、
文字化けしたようになってきちんと表示できませんでした。
stringの場合はそのまま突っ込んでもきちんと表示できていたので、
じゃあstringを使おうかなと思ったのですが、
これだと今度はマルチバイト文字を使った時に「文字単位」で操作できないし、、、
などです。
35デフォルトの名無しさん:2005/08/16(火) 14:26:47
>34
そんなことしなくともテキストエディタ作ってやればいいんじゃないかな?
SetDlgItemTextで貼り付けてやって、そいつを編集後、
GetDlgItemTextで取得
テキストエディタなら入門本にいくらでもある
それとも、テキストエディタじゃ駄目なのかな?
3628:2005/08/16(火) 14:31:16
>>35
ゲーム作ろうと思ってるので、それほど高度なものは必要ないのですが、
Windowsのコントロールの貼り付けとかせずに自前のものを作りたいのであります。
37デフォルトの名無しさん:2005/08/16(火) 17:59:07
stringでいいんじゃね?
っていうかGetTextExtentPoint32使えばいいんじゃね?
GetCharWidth32とかも使えるんじゃね?
38デフォルトの名無しさん:2005/08/16(火) 18:20:24
もの凄いくだらない質問なのですが、
配列を、ある地点から降順で検索するときの、「スマートな」書き方があれば教えて頂けないでしょうか
(ある地点が0(先頭)の場合もあります)
3938:2005/08/16(火) 18:29:21
Cスレにすべきだた…私のスマートじゃ無さそうなのはこんな感じです
なんか上手い人ならfor文だけでできそうな気がするんです

if( a_position == 0 ) //a_position : インデックスのある地点
 hoge( *array );
else
 for( int i = a_position; i >= 0; --i ) hoge( array[i] );
40デフォルトの名無しさん:2005/08/16(火) 18:42:06
[begin, a_position + 1)で探索するだけやがな…
41デフォルトの名無しさん:2005/08/16(火) 18:43:21
検索?用語は正しく使ってくれ…
4238:2005/08/16(火) 18:50:01
>>40
降順でやりたいので…
>>41
手元の教本(英語)だとretrieveとあったので

スレ違いっぽいですし質問撤回します
43デフォルトの名無しさん:2005/08/16(火) 20:09:32
>>38
リバースイテレータ
44デフォルトの名無しさん:2005/08/16(火) 20:40:57
>>34
バイト数で文字幅が決まるとは限らない。
そうなるように設計されたエンコーディングと描画処理を使ってるなら別だが。

WM_CHAR はマルチバイトシーケンスが1バイトずつ送られてくるから、
チェックとバッファリングが必要
ってこのサイトに書いてあったよ。
http://www.google.co.jp/search?q=WM%5FCHAR+Multibyte
45デフォルトの名無しさん:2005/08/16(火) 20:41:29
>>36
高度なものが必要ないなら、なおさらOSやライブラリに任せるべきじゃないの?
46デフォルトの名無しさん:2005/08/16(火) 21:16:25
>>39
これって条件分岐に何の意味があるん?
4728:2005/08/16(火) 21:19:40
>>37
GetTextExtentPoint32とか調べてみたのですが
描画もフォント作成もDirectXをつかうのでhdcを渡さないといけないのが何か。。。
なのでやはり先頭から順にバイトで調べる方法が使える型の方がいいのかなーとか
考えてるんですが整理できないです。
>>44
文字の大きさ指定して等幅フォントつかったとしても
バイト数だけでは判断できるとは限らないって事でしょうか?
例えば2バイト文字でも半角幅の文字がある、とか。
>>45
機能面で高度なもの(アンドゥとかコピペとか)はいらないのですが、
DirectXと標準コントロールを混在させると画面がちらついたり
するらしいし、見た目も気に入らないのでちょっと自作に拘りたいのです。
48デフォルトの名無しさん:2005/08/16(火) 22:31:13
>47
文字を自前描画しているなら、wcharのあるコードポイントが
何ドットを占めているかは簡単に調べられるだろう。
 あとは、だんだん延ばして(減らして)いって変換するだけではないのか?
4928:2005/08/16(火) 22:51:35
>>48
よくわからないのですがwcharってwstringみたく半角アルファベットとかでも
マルチバイトで持ってるんじゃないんでしょうか?
簡単に調べられるというのは具体的にどうやって調べればよいでしょうか。
自前描画といっても、フォントと文字サイズを指定してconst char*を渡すと
勝手に書いてくれるDirectXの関数を使っているだけなのですが、、、
50デフォルトの名無しさん:2005/08/16(火) 22:59:58
とりあえず、もうちょっと詳しく状況を寄越せ。後でボロボロ追加情報を出すな。
あとはスレ違いだからあっち逝け
http://pc8.2ch.net/test/read.cgi/tech/1122031254/l50
51デフォルトの名無しさん:2005/08/16(火) 23:12:15
>>47,49
さんざん言われてるキーワード「エンコーディング」ぐらい調べてから出直せ。
5228:2005/08/16(火) 23:23:06
>>50
自前描画してるなら〜と言われたので、
描画はただDXの関数使ってるだけだしそれがドット数調べたいのと
何の関係があるのかなーと思いつつ説明しただけでして、
あとはDirectXは標準コントロールを使えない理由として
挙げただけですからDirectXスレは全然関係ないと思うのですが。

>>51
エンコーディングって言うと文字コードの話でないでしょうか?
型の事とはまた少し別なような気がするのですが。。。
53デフォルトの名無しさん:2005/08/16(火) 23:27:06
文字列を、DirectXの関数(どーせGDIラッパのID3DXFontだろうけど)
つかって描画をしている。その(部分)文字列の長さがほしい。
なら、当然DirectXスレか、3歩譲って、Win32APIスレだろ。
54デフォルトの名無しさん:2005/08/16(火) 23:29:02
>>52
何が関係が有るのか無いのか判断できるほどオマエは賢くない。
もう一度言うが、まずはここで言われたことを自分で調べて、理解し、
それでもC++に関する質問が残っていればまた来い。
5528:2005/08/16(火) 23:31:09
文字列操作とか型の相談でして
別に描画に何を使おうが関係ない話だと思うんですが。
56デフォルトの名無しさん:2005/08/16(火) 23:33:38
>>55 オマエが思ったことなら正しいとでも言うつもりか?いいかげんにしろよ。
57デフォルトの名無しさん:2005/08/16(火) 23:37:38
wstring使え。環境との間で問題が出るのは、wstringの使い方が間違ってる。以上。
これでいいのか?
5828:2005/08/17(水) 03:49:09
そんなにここで質問するのが気に入らないんですか?
気に入らないなら見なきゃいいじゃないですか。
59デフォルトの名無しさん:2005/08/17(水) 04:45:19
>>28はプログラムのお勉強の前に
日本語の読み取り能力とコミュニケーション能力を養え
60デフォルトの名無しさん:2005/08/17(水) 05:48:48
そして誰一人として納得させられる回答を提示できないという事実。
それどころか質問の意図すら汲み取れず
しまいにゃ意味不明な逆切れで全然関係ないスレに誘導。
61デフォルトの名無しさん:2005/08/17(水) 08:09:30
回答の意図を汲み取れない人発見。
負け犬の言い訳はいつも同じだな。
62デフォルトの名無しさん:2005/08/17(水) 08:35:01
>>34
>wstringの場合、文字列の先頭から1バイト文字かマルチバイト文字かを判断し
>1バイトなら8ドット、2バイトなら16ドットのように足していって
>座標値を割り出すことができないのでマウス座標との判定ができなそう、、、など。

もちろんその方法では出来ない。
wchar_tの幅(ピクセル数)を得る標準的な方法は存在しない。
よってスレ違い。

>あとはIMEで漢字変換したとき、WM_CHARが連続して流れてくるみたいなんですが、
>WPARAMをwstringの文字列に突っ込んでもうまくいかないようで、
>文字化けしたようになってきちんと表示できませんでした。

IME、WM_CHAR、WPARAMと言っている時点で当然スレ違い。

>stringの場合はそのまま突っ込んでもきちんと表示できていたので、
>じゃあstringを使おうかなと思ったのですが、
>これだと今度はマルチバイト文字を使った時に「文字単位」で操作できないし、、、
>などです。

できないのではなく、やりにくいだけ。
マルチバイト文字をどう判別したらいいかはエンコーディングや環境に依存する。
よってスレ違い。

このようにスレ違いのオンパレードにもかかわらず、多くの人が親切にもヒントを与えてくれている。
>>28はもう少し自分で考え、分からない事を明確にした上でもう一度質問してくれ。
どうやるか迷っているのは分かるが、決めるのはあなただ。
63デフォルトの名無しさん:2005/08/17(水) 08:37:37
本買って勉強しる
64デフォルトの名無しさん:2005/08/17(水) 11:54:37
スレ違いって言われた時点でとっとと移動しないところが一番悪いな。
それは〜の話だって言われてもググりもせずに関係ないとか言って無視してるし。
65デフォルトの名無しさん:2005/08/17(水) 12:38:53
UTF8とかシフトJISはstd::string?wstring?
どっちにしてもatとかfindは機能しなくない?
66デフォルトの名無しさん:2005/08/17(水) 12:51:03
DXスレに誘導してた馬鹿が一人で頑張ってますね。
67デフォルトの名無しさん:2005/08/17(水) 13:00:58
そもそもテキストエディタを作るのに、無理にbasic_stringを使う必要はない。
適していると思うデータ構造を自分で選んで使いなさいw
68デフォルトの名無しさん:2005/08/17(水) 13:03:57
それを決めあぐねて助言を求めてるんだろう?
69デフォルトの名無しさん:2005/08/17(水) 13:21:54
エディタの人ではないのだが。
いつもユニコードに変換してCStringとかBSTRで処理してるから
標準ライブラリ使ってる人はどうしてんのかと思っただけ
70デフォルトの名無しさん:2005/08/17(水) 13:37:47
>>65
UTF-8は普通UCSに戻して処理するだろ。
SJISは場合によっては16bit化してwstringにつっこむこともある。
7165:2005/08/17(水) 14:00:22
了解。
72デフォルトの名無しさん:2005/08/17(水) 14:13:44
あとはマルチバイトに対応した文字処理関数とか文字列クラスを自分で作るくらいかなぁ。
7328:2005/08/17(水) 17:05:29
えー、なにやら偽者が出てますが、テキストはwstringをとりあえず使っとけ
ということだったのでとりあえずそれを使うことにしました。
あと文字幅を調べるのは教えていただいたGetTextExtentPointを使って調べる事にしました。
これはhdcを作ったりDirectXに渡すのと同じフォントを重複して作るのが
気持ち悪くてなんとなく使うのが嫌だったのですが、
これだと太文字使っても文字幅とれるみたいで予想外に便利でした。
長々とお世話様でした。
74デフォルトの名無しさん:2005/08/17(水) 17:22:27
まったく関係ない話だが、
マルチバイト文字を操作する場合、対応するイテレータ
( Readable ( Forward or Bidirectional ) Traversal Iterator)
を最初に作成しておくと楽。
特に MS系コンパイラのマルチバイト文字列を扱う関数なんかは、
1文字を int で要求することが多いので、dereference で int を返すようなモノを
作成しておくと、後々便利なことも多い。
75デフォルトの名無しさん:2005/08/17(水) 17:25:05
なるへそ
76デフォルトの名無しさん:2005/08/17(水) 19:14:10
マルチバイトってBOMあるの?

77デフォルトの名無しさん:2005/08/17(水) 19:37:07
これもどうでもいい話だけど、Boost.Regex が ICU に対応したらしい。


78デフォルトの名無しさん:2005/08/17(水) 20:11:32
ここは相談スレだから関係ない独り言はスレ違いです。
はやくDXスレに行って下さい。
79デフォルトの名無しさん:2005/08/17(水) 20:14:00
>>78
ならばお前もだな
80デフォルトの名無しさん:2005/08/18(木) 00:27:14
>>76
Unicodeもマルチバイトだって事を知らないの?
81デフォルトの名無しさん:2005/08/18(木) 09:09:09
>>74
Bidirectionalって可能なの?
……一文字戻るのに定数時間で終わらなくてもいいなら可能かな?
82デフォルトの名無しさん:2005/08/18(木) 09:28:45
>>81
UTF-8 なら、1文字進めるのとほぼ同コストで可能。
SHIFT_JIS なら、MSコンパイラには _mbsdec がついてくるけど、
文字列の先頭位置へのポインタを要求するので、こちらは線形時間が必要。
83デフォルトの名無しさん:2005/08/18(木) 09:42:25
なるほど、UTF-8は判別できるようになっているんですね。
thx.
84デフォルトの名無しさん:2005/08/18(木) 10:17:40
EUCなら定数時間で判別できるのにねぇ。
SJISでも先頭からではなく、遡るアルゴリズムならかなり改善されるけど_mbsdecはどうなんだろ。
85デフォルトの名無しさん:2005/08/18(木) 10:43:42
>>84
CRTのソースを見る限り遡ってるみたいよ。
2バイト前がマルチバイト文字1バイト目でなければ、前の文字は確実に1バイト文字なので、1バイト戻る。
以降、マルチバイト文字1バイト目でないものが奇数バイト前に見つかれば、2バイト戻る。
偶数バイト前に見つかれば、1バイト戻る。
86デフォルトの名無しさん:2005/08/18(木) 16:04:39
インデントに全角空白を使ってますがご容赦を

class House{
  struct Hage{
  };
  class Oil{
  public:
    Hage* hage_generator();
  };
  Oil oil;
public:
  void hoge(){
    Hage* wonderful_hage = oil.hage_generator();
  }
};

Hage* House::Oil::hage_generator(){
  return new Hage;
}

クラス内クラスなんですが、これはコンパイル通りませんでして、解決には
hage_generatorをclass内で記述するか、Hageの宣言をHouseの外に出せば良いわけですが、
それ以外の方法でどうにかならないでしょうか

Houseでしか使えないHageを、出来ればHouseの外に出したくないんです
87デフォルトの名無しさん:2005/08/18(木) 16:06:19
>>86
ワロス
88デフォルトの名無しさん:2005/08/18(木) 16:08:49
>>86
House::Hage* House::Oil::hage_generator(){
^^^^^^^
89デフォルトの名無しさん:2005/08/18(木) 16:10:09
>>86
  return new House::Hage;
^^^^^^^
書き忘れ。ここも。
90デフォルトの名無しさん:2005/08/18(木) 16:12:55
>>88
お付き合いありがとうございます

実はそれも試したのですが、Hageはprivateだからダメよと窘められまして
もしかしてコンパイラのせいなんですかねぇ、規格斜め読み中です
91デフォルトの名無しさん:2005/08/18(木) 16:18:54
>>89
おお、そちらはやってませんでした
やっぱり通らないのですが、恐らく>>89氏の環境では通っていると思いますので
うちのコンパイラが古いせいっぽいですね

重ねて感謝です
92デフォルトの名無しさん:2005/08/18(木) 21:35:33
hageにかつらをかぶせたらprivateになった
93デフォルトの名無しさん:2005/08/18(木) 21:51:47
class Hage{
friend class House;
//以降全てprivate
private:



>Houseでしか使えないHageを、出来ればHouseの外に出したくないんです

つりか・・・
94デフォルトの名無しさん:2005/08/19(金) 12:50:51
hook 関連でSTLちっくに整理されてるライブラリーってないの?
95デフォルトの名無しさん:2005/08/19(金) 15:20:30
派生クラスでオーバーライドした仮想関数内で、delete *this;としたい状況にあるんですが、
派生クラスのコレクション(list<Base*>型)から削除するのが問題で、どのように書いたらいいのか困っています。

// 考えてみた方法1(Baseにコレクションを持たせるのはどうか?)
class Base {
public:
virtual ~Base()=0;
virtual void F()=0;
static list<Base*> obj_;
};

class Derived : Base {
public:
void F() {
obj_.erase(find(obj_.begin(), obj_.end(), this));
}
};
9695:2005/08/19(金) 15:22:03
// 考えてみた方法2(オブジェクト毎に関数ポインタを持つオーバーヘッドが気になる)
class DoSomething {
public:
void Unregister(Base*);
void Action() {
obj_.push_back(Derived<DoSomething>(&DoSomething::Unregister));
//以下略
}
private:
list<Base*> obj_;
};

template <class Manager>
class Derived : Base {
Derived((typename Manager::*Unregister)(Base*)) : Unregister_(Unregister) {}
void F() {
(*Unregister_)(this);
}
private;
void (typename Manager::*Unregister_)(Base*);
};

どういう設計が良いのでしょうか?
97デフォルトの名無しさん:2005/08/19(金) 15:34:27
>>96 何がやりたいのかよくわからん
98デフォルトの名無しさん:2005/08/19(金) 15:48:21
質問の下手なやつばかりだなあ
99デフォルトの名無しさん:2005/08/19(金) 16:00:59
>>95
何がしたいかわからんが、Baseに任せた方がいいんじゃない?

class Base {
public:
virtual ~Base() { obj_.erase(find(obj_.begin(), obj_.end(), this)); }
virtual void F()=0;
static list<Base*> obj_;
};

class Derived : Base {
public:
void F() { delete this; }
};
10095:2005/08/19(金) 16:23:41
>>99
すみません、仮想デストラクタをDerivedクラスでオーバーライドした場合でも、基底クラスのデストラクタはちゃんと呼ばれるんですか?

やりたかったことですが、
本来、list<Base*> obj_は継承階層にあるクラスとは関係ないクラスが持つもので、
継承階層にあるクラスからobj_へのアクセスが、循環依存?になるんじゃないかと設計に困りました。
10195:2005/08/19(金) 16:33:01
あ、95の例は、
list<Base*>::iterator it = find(obj_.begin(), obj_.end(), this);
delete *it;
obj_.erase(it);
じゃないとだめですね。
102デフォルトの名無しさん:2005/08/19(金) 16:33:31
>>100
仮想デストラクタはもちろんトップレベルまで順次呼ばれる

循環依存? まだ何を問題にしているのかわからん
10395:2005/08/19(金) 16:42:21
>>102
>> 仮想デストラクタはもちろんトップレベルまで順次呼ばれる
なるほど

>> 循環依存? まだ何を問題にしているのかわからん
まず、>>95の例は、Baseがstaticでコレクションを持つことに疑問を感じます(ポリモフィズムを利用するクラスが持つべき)。
ポリモフィズムを利用するクラスがコレクションを持つことになると、>>100の最後の1行。
そこで考えたのが>>96の例です。
104デフォルトの名無しさん:2005/08/19(金) 16:43:36
>>95
うーん、そういう設計の問題って、ソースに現れるようなものだけを提示しても仕方ないと思うよ。
105デフォルトの名無しさん:2005/08/19(金) 16:55:43
そもそも、どういう目的でコレクションを使うのかとか
格納されるオブジェクトは何なのか(なぜ派生するのか)
どういうときに削除したいのか
その辺を説明して欲しいな
106デフォルトの名無しさん:2005/08/19(金) 16:58:58
>>95
delete thisは避けて
listを持っているクラスが中のインスタンスもろとも消すのが適当だと思う
たとえばbool delete_meとかいうフラグを立てておくとか、
list経由でアクセスされる関数において削除要請を意味する値を返すとか。
107デフォルトの名無しさん:2005/08/19(金) 17:41:39
コンテナに入ったオブジェクトが自殺したいってことかな?
ならowner(listを持っているオブジェクト)に削除メソッドDeleteを持たせ
格納されたオブジェクトはownerへのポインタを持って、owner->Delete(this);
だろうなあ。

ただこれを呼んだ後returnするまでが危ないっていうなら、Delete()では
list_からdelete_list_に移し変えるだけにして
各オブジェクトの呼び出しが終わったらdelete_list_を一括deleteとかかね

参照カウントで同様の結果を得る方法もあるな
10895:2005/08/19(金) 20:53:19
>>106
なるほど、理にかなってると思います。

>>107
Ownerクラスのあるメンバ関数内ではDerived::F()の呼び出し。
Derivedクラスのあるメンバ関数内ではOwnar::Delete()の呼び出し。
両方のクラスに、相手クラスの関数名を記述しあうことになり、気持ち悪さを感じるんですが、
その辺は、気にしなくてもいいことなんでしょうか。


「listへ格納するクラス」に削除フラグを返す関数を書いて、「listを保持・使用するクラス」から削除する事にします。
レス下さった方、ありがとうございました。
109デフォルトの名無しさん:2005/08/19(金) 21:43:08
>>108
終わったみたいだけど

>両方のクラスに、相手クラスの関数名を記述しあうことになり、気持ち悪さを感じるんですが、

直接参照するのがいやなら、インターフェイスとなる抽象クラスを間にかませば良いんじゃない?
110デフォルトの名無しさん:2005/08/19(金) 22:23:51
この質問後をたたないな。。
111デフォルトの名無しさん:2005/08/19(金) 22:39:53
実行速度について質問があります

Microsoft VisualC++6.0にて開発しています。
ファイルの読み込みについてなんですが
fstream経由で読み込むのと完全にC流で読み込むのではC流で読み込んだ方が
早い気がするんですが常識ですか?
112デフォルトの名無しさん:2005/08/19(金) 22:54:24
>>111
ライブラリ次第。
VC6.0付属のやつはfopen系使って実装されてるので
fstreamのオーバーヘッド分遅くなる。
113デフォルトの名無しさん:2005/08/20(土) 00:21:58
まあ、画期的な技術が開発されない限りは、

HDDのアクセス速度 >> fstreamやfopenのオーバーヘッド

であるのだろうけどね。
114デフォルトの名無しさん:2005/08/20(土) 00:36:46
継承と前方宣言について質問があります。

Aを継承したBというクラスを作ろうとして、
B.hのファイルでclass A;というプロトタイプ宣言をしたのですが、

コンパイラ エラー C2504
'class' : 定義されていない基本クラスが宣言されています。

と言われ、コンパイルできません。継承の対象クラスは実体を宣言しないとだめなのでしょうか?
115デフォルトの名無しさん:2005/08/20(土) 00:44:20
>>114
そのとおり
クラスが'定義'されていないと継承できない
116111:2005/08/20(土) 00:45:18
>>112
>>113
即レスありがとうございました
fstreamとfopen両方の関数を適時つかえるようにするといった対処をすることにします
117114:2005/08/20(土) 00:52:03
>>115
即レスありがとうございます。
ではそういう場合どのようにコーディングするのですか?
同じファイルに継承したクラスを記述するしかないのでしょうか。
118デフォルトの名無しさん:2005/08/20(土) 00:54:14
>>117
class Aなら a.hに書いて b.hでinclude "a.h"じゃろ
119デフォルトの名無しさん:2005/08/20(土) 01:08:56
>>118
たしかにその方法でできるのですが、
そうなるとmain.hのほうで宣言していた
#include "a.h"
#include "b.h"
のところで

コンパイラ エラー C2011'identifier' : 'type' 型の再定義
識別子が既に type として定義されています。このエラーは、タイプ ライブラリを同じファイルに 2 回以上インポートした場合にも発生します。

のエラーがでてしまいます。これはb.hだけインクルードすればよいのですか?
120デフォルトの名無しさん:2005/08/20(土) 01:12:11
>>119 ヘッダにインクルードガードつけろ。
121デフォルトの名無しさん:2005/08/20(土) 01:12:38
#ifndef
#endif
122114:2005/08/20(土) 01:13:09
>>120
即レスありがとうございました。
ググってきます。ノシ
123114:2005/08/20(土) 01:29:13
>>115,118,120,121
問題解決できました。
親切な回答ありがとうございました。
124デフォルトの名無しさん:2005/08/20(土) 02:28:09
メンバ関数へのポインタをSTLを使って管理したいのですが、
文法上 どうかけばいいのかわかりません。

現在
CGame
{
 public:
  static void Test();
};

vector< void (CGame::*)() > g_vFuncTable;

g_vFuncTable.push_back( &CGame::Test );

と コンパイルしてみたところ コンパイルエラーがでます。

代入が悪いのか、宣言が悪いのか、教えてもらってもいいでしょうか?
125デフォルトの名無しさん:2005/08/20(土) 02:35:11
何をやったらどんなエラーが出たわけ?
126デフォルトの名無しさん:2005/08/20(土) 02:45:15
>>124
メンバ関数の型は static かどうかで変わる。
その例だと、 CGame::Test の宣言が悪い( static が要らない)可能性が高いな。
127124:2005/08/20(土) 02:46:49
>>125
上記のソースコードをコンパイルしたところ

g_vFuncTable.push_back( &CGame::Test );
のところで

以下のエラーがでました。
error C2664: 'push_back' : 1 番目の引数を 'void (__cdecl *)(void)' から 'void (__thiscall CGame::*const & )(void)' に変換できません。 (新しい機能 ; ヘルプを参照)
理由: 'void (__cdecl *)(void)' から 'void (__thiscall CGame::*const )(void)' へは変換できません。
この変換が可能なコンテキストはありません。

エラー内容が理解できないので、対処ができません。
128124:2005/08/20(土) 02:58:55
>>126
CGame::Test の static 修飾子をはずしたら無事コンパイルできたのですが、

g_vFuncTable.push_back( &CGame::Test );

の次の処理

g_vFuncTable.at(0)();

の部分で

error C2064: 関数ポインタとして評価されない式を使って、関数を呼び出そうとしました。

という コンパイルエラーがでてしまいました。

g_vFuncTable 変数を使って 代入した CGame::Test メンバ関数を呼びだしたのですが

どう書けばいいのでしょうか?

2重質問すいません
129デフォルトの名無しさん:2005/08/20(土) 03:09:31
>>128 .* または ->* いずれかの演算子を使う。
130デフォルトの名無しさん:2005/08/20(土) 03:10:22
>>127
普通の関数とクラスのメンバ関数ではポインタの型が違う。
ただの関数だとアドレスはひとつに決まるが、
クラスのメンバ関数だと
CGame dq;
CGame ff;
って二つあったとしたらどっちのTest関数やねんって感じ。
んで当然エラー。

>>128
んでC++ならあまりメンバ関数のポインタなんて使わない
そーゆーときは
interface ITest {
  virtual void Test() = 0; //インタフェースの定義
};

class CGame : public ITest {   //インタフェース継承して
 virtual void Test();         //インタフェースの実装
};
vector<ITest*> g_InterfaceTable;
とでもする。
眠いのでもう寝るけど適当にググってHP探すか
いろいろC++の解説本でも読んでください。
131デフォルトの名無しさん:2005/08/20(土) 03:10:46
132124:2005/08/20(土) 03:30:56
勉強不足ですね
どうもありがとうございました。
133デフォルトの名無しさん:2005/08/20(土) 19:14:48
名前空間の中にある変数はextern宣言できないんですか?
134デフォルトの名無しさん:2005/08/20(土) 19:46:49
>>133
できる
135デフォルトの名無しさん:2005/08/20(土) 20:13:18
どうやって?
136デフォルトの名無しさん:2005/08/20(土) 20:19:39
検索したらexternしなくても大域変数みたいでした
137デフォルトの名無しさん:2005/08/20(土) 20:30:33
>>136
意味不明
ここは貴様のチラシの裏じゃない
138デフォルトの名無しさん:2005/08/20(土) 23:42:24
宣言と定義の区別がついていないようだな
139デフォルトの名無しさん:2005/08/21(日) 18:18:24
namespace ns { struct X {}; }
のように構造体が宣言されているとき、あるブロックで
using ns::X;
と using 宣言するのと
typedef ns::X X;
のように型を定義するのでは何か違いがでるでしょうか?
140デフォルトの名無しさん:2005/08/21(日) 18:26:24
typedefだとfriendの対象にならなかったような気がする。
141デフォルトの名無しさん:2005/08/21(日) 18:32:31
>>139
理由は不明だが int X; って追加してコンパイルしてみると
using が通って typedef が通らない。
142デフォルトの名無しさん:2005/08/21(日) 18:59:22
gcc 3.4.4 だと、順番で挙動が異なる。
MSVCだと、どっちでも通る。

// OK
namespace ns { struct X; }
using ns::X;
int X;

// NG
namespace ns { struct X; }
int X;
using ns::X;

だめだ。 using を使いこなす自信が無い。
143デフォルトの名無しさん:2005/08/21(日) 19:22:32
コンパイラ依存だから使わないが吉
144デフォルトの名無しさん:2005/08/22(月) 00:28:52
>>142

X hoge ;//<-型はどっちになるんだろう?
145デフォルトの名無しさん:2005/08/22(月) 00:36:53
>>144 自分でやってみないのか?
146デフォルトの名無しさん:2005/08/22(月) 00:39:26
すまん、int Xか……。
ボケてた。
147デフォルトの名無しさん:2005/08/22(月) 00:52:27
struct A {
 int i;
 A(int x) : i(x) {}
 A() {}
};

struct B : public A {
 B(int x) : i(x) {}
};

で、Bのi(x)でエラーが出るのはなぜですか?
Aの i がそのままBに継承されると思ったのですが・・・・
148デフォルトの名無しさん:2005/08/22(月) 00:57:39
>>147
それができるなら
 B(int x) : A(0), i(x) {}
こんな場合に i の初期化が2通り存在してしまう。
149デフォルトの名無しさん:2005/08/22(月) 01:47:02
>>148
14882:2003§12.6.2.2.当たりでしょうか。

If a mem-initializer-id is ambiguous because it designates both a direct non-virtual base
class and an inherited virtual base class, the mem-initializer is ill-formed.

言われてみれば確かにそうです。Bの初期化リスト中にAのコンストラクタを
呼び出すようにするのが正しいようです。曖昧さを持たせないようにします。
ありがとうございました。
150デフォルトの名無しさん:2005/08/22(月) 03:58:14
JAVAをobjectorientまでやって今度はC++を学ぼうとしています。
JAVAはでっかいライブラリのページがあって
googleで使いたいメソッドの名前を予想したりして
打ってメソッドからメソッドへ(またはクラス)リンクで飛べてすぐに探せたのですが、
C++では探すのに結構苦労しています。
普段どのように探してるのか教えてください。
compilerとしてvisual studioを使ってます。
151デフォルトの名無しさん:2005/08/22(月) 04:45:40
>>150
MSDN
ってか、割れですか?
152デフォルトの名無しさん:2005/08/22(月) 08:03:37
>>150
一行目から既に意味不明
153デフォルトの名無しさん:2005/08/22(月) 11:23:35
今、ライブラリを作っているんだがコメントのつけ方で悩んでいる。
関数の詳しい説明を、
1) ヘッダファイルの関数宣言部分に書く
2) 関数の実装部に書く
このどちらがいいんだろう?

例えばhoge()があった場合、

(hoge.h) // 1)の場合の例
/*
 hogeする関数。
 [param]
   a : hogeのa用
*/
void hoge( int a );

(hoge.cc) // 2)の場合の例
/*
 hogeする関数。
 [param]
  a : hogeのa用
*/
void hoge( int a )
{
 hogehoge(a);
}

ライブラリと言っても、ほとんど自分専用で変更も多いので
.libファイルとかにまとめない予定。
おまいらならどうする?
154デフォルトの名無しさん:2005/08/22(月) 12:13:36
>>153
ちゃんと整備する気があるなら、利用者にソースを公開しない可能性を考えてインクルードファイルに書くのがいいのでは?
で、できればDoxygenスタイルに統一するといいかも。

あくまでも自分専用だと言うなら、使い方まで書きゃしないだろうから実装に書いた方がいいかも知れないけど。
155デフォルトの名無しさん:2005/08/22(月) 12:47:42
俺はヘッダーファイルを関数一覧表として見やすく保っておきたいから
実装部に書いてるな。

関数の使われかた(インタフェース)に関するコメントであって、実装
に関するコメントではないと考えるのならヘッダーファイルに書くのも一理あると思う。

どのみちDoxygenでドキュメントを生成するならどちらに書いても同じかもしれない。

ここ数年Doxygenというか、javadocスタイルでコメントを書いているけど
自分だけだったらソースを直接見た方が早いのであまりドキュメントを生成していなかったりする。

というか、コーディング規約スレか?
156デフォルトの名無しさん:2005/08/22(月) 13:09:53
ドキュメント生成なら、NaturalDocs マジオススメ。

157デフォルトの名無しさん:2005/08/22(月) 15:47:04
Doxygenよりもか?
158デフォルトの名無しさん:2005/08/22(月) 17:43:08
NaturalDocs はコメントの形式がきれいなのですき。

//
// Function: regex_replace
// -------------------------------------
// 正規表現置換を行う。
// -------------------------------------
// Parameters:
//  rex - 正規表現パターン
//  src - 置換対象文字列
//  rep - 置換文字列
//
// Returns:
//  置換された文字を返す。
//
string regex_replace( regex const & rex, string const & src, string const & rep )
{
 ...
}

ソースだけ見ても分かりやすい。
159デフォルトの名無しさん:2005/08/22(月) 18:39:33
見やすいかもしれんが
長い…
160デフォルトの名無しさん:2005/08/22(月) 22:52:01
プログラマの皆さん

関数やクラスの名前、はたまたプロジェクトやソフトウェアのいろいろな名前、

名前は飾りですか?

それとも、その機能(特徴)を的確に表し 短く覚えやすい名前をつけますか?


いざ名前をつけるとなると、自分の場合悩んで決めあぐねて困っています

私はこう付ける等のアドバイスやヒントを教えてください。お願いします。

161デフォルトの名無しさん:2005/08/22(月) 22:59:43
>>160
1行空け読みづらいな。しかも飾りですかって煽りですか
というかスレ違い
162153:2005/08/22(月) 23:11:50
トンクス。
NaturalDocsよさげだな。
JavaDocでドキュメントを作ったことがあるんだが、
コメント形式が好きじゃないんでコメントからドキュメント作成は諦めてた。

ドキュメントが作れるならどっちに書いてもいいと思うんで、
なるべくヘッダを見やすくしたい俺は実装部に書くことにしました。

>> 160
名前は長くてもわかりやすいのを付けるようにしている。
といってもまだ学生で、プロジェクトに参加したことがないので
どんな形がいいのかよくわからないのですが。。。
163デフォルトの名無しさん:2005/08/22(月) 23:25:32
>>160
関数やクラスはその機能にあった名前をつける(というか、それ以外どうしろと)
ソフトの名前は、趣味で勝手に汁
164160:2005/08/23(火) 00:24:25
>>161
煽りではないです 読みづらいのはすみません。

>>162 163
二人のレスをよく呼んで気づかされたんですが、 私が悩んでいたのは
関数やクラス名ではなくて、ソフト・プロジェクト名だったようです。
機能にあったわかりやすい名前を関数・クラスに付けるのは当たり前ですね。
さて、いよいよスレ違いくさくなってきたのでこれで最後のレスにします。

>>ソフトの名前は、趣味で勝手に汁
この言葉結構参考になりました。
165デフォルトの名無しさん:2005/08/23(火) 00:45:50
>>164
おまえキモイ
166デフォルトの名無しさん:2005/08/23(火) 00:50:13
禿同
167デフォルトの名無しさん:2005/08/23(火) 01:48:41
operator=の実装などでオブジェクト自身の参照を返したい場合、戻り値は
return *this;
と書けば希望通りに動作してくれるのでしょうか?

自分で試したいけど、PCぶっ壊れて試せない(;´Д`)
168デフォルトの名無しさん:2005/08/23(火) 01:50:03
OK
169デフォルトの名無しさん:2005/08/23(火) 09:22:55
>>167
operator=の戻り値の型をきちんと参照型にしておけよ?
170デフォルトの名無しさん:2005/08/23(火) 12:19:59
どうでもいいけど、何故そこに疑問符をつけるのだろう……
171デフォルトの名無しさん:2005/08/23(火) 12:52:21
自分に自信が持てないから
172デフォルトの名無しさん:2005/08/24(水) 20:54:13
OpenPNLコンパイルするだけで30分近くかかってるんですが
そういうものなの?
templateを多用されてるから?
173デフォルトの名無しさん:2005/08/24(水) 20:59:10
>>172
Firbirdのコンパイル(gcc3.3のコンパイル含む)に12時間かかった漏れに喧嘩売ってますか( ^ω^)
PHPやApacheのコンパイルも1時間以上余裕でかかるorz

つミP54C-133
174デフォルトの名無しさん:2005/08/24(水) 21:53:25
ペン4 2G とかでも30分かかります
175デフォルトの名無しさん:2005/08/24(水) 23:01:54
>>172,173,174
マシン余ってるならdistccを使おう
176デフォルトの名無しさん:2005/08/24(水) 23:09:14
>>175
稼働可能機がEPSON PC-286V-STDしか‥‥(;^ω^)
177デフォルトの名無しさん:2005/08/25(木) 15:39:40
上手なincludeの仕方(モジュールの分け方?)みたいなのが解説されている
サイトや書籍があったら教えて頂けないでしょうか。
172氏じゃないですが、どうもその辺が下手なせいで、コンパイル時間が長い気がしてなりません。

今のところ、ヘッダには、インラインを使う必要が無い限り、なるべく他のヘッダをincludeしないで
型宣言だけで済ます…くらいしか工夫をしていません(これ自体も良いのか悪いのか…)。
178デフォルトの名無しさん:2005/08/25(木) 15:42:17
コンパイル時間を減らすためなんてアフォラシス
179デフォルトの名無しさん:2005/08/25(木) 15:48:17
>>177
プリコンパイルヘッダとか活用汁
180デフォルトの名無しさん:2005/08/25(木) 15:53:08
依存度を下げる事が再コンパイル時間を減らす事につながるので、
コンパイル時間を減らすことはオブジェクト指向言語として、
最大の目標といっていい。
181デフォルトの名無しさん:2005/08/25(木) 16:03:00
>>179
やってはいるのですが、どうも…マシンが非力なせいもあるのですが

>>180
なるほど、コツとか近道は無くて、結局設計の腕を上げるしか無いと言うことですか

お二人ともありがとうございます
182デフォルトの名無しさん:2005/08/25(木) 16:34:49
>>178
お前がアフォ
183デフォルトの名無しさん:2005/08/25(木) 16:53:48
  _, ._
( ゚ Д゚) …
184デフォルトの名無しさん:2005/08/25(木) 17:33:17
というか、ヘッダファイルという考え方自体が、古いんだけどな。
どうしてもコンパイルが遅くなる。
苦肉の策としてVCはプリコンパイル済みヘッダという仕組みで早くしているけどね。

D言語とかうらやましい。
185デフォルトの名無しさん:2005/08/25(木) 18:07:53
かといって、#include がなくなると、

class bind_t
{
 ...
 #define BIND_RETURN return
 #include "bind/bind_template.hpp" // <- スクリプトでつくった実装ファイル
 #undef BIND_RETURN
};

のような事が出来なくなっちゃうので モジュール読み込み形式と、
テキスト展開方式の2パターンが欲しいところ。
186デフォルトの名無しさん:2005/08/25(木) 18:23:27
BCB使ってるけどC++コードとPascalコードじゃコンパイル速度洒落にならないほど違うしなあorz
187デフォルトの名無しさん:2005/08/25(木) 18:45:09
>>177
設計というより、実践寄りのものとして

大規模C++ソフトウェアデザイン
ttp://www.amazon.co.jp/exec/obidos/ASIN/4894711249/

ビルドに1週間かかるシステムとかそういうものに対して、
徹底的に依存関係を減らす方法を説明してある。
188デフォルトの名無しさん:2005/08/25(木) 19:14:43
#nullpo
189デフォルトの名無しさん:2005/08/26(金) 12:34:04
#include "Global.h"

とかやってた事のある奴挙手
190デフォルトの名無しさん:2005/08/26(金) 14:43:56
cout << hex << 100 << endl;
ってやると16進数での100の表示が出ますが、
この結果をchar配列に詰めたいときはどうすればいいんでしょうか。

文法的には間違ってますが、
イメージとしては
char[10] buf;
buf << hex << 100;
みたいな感じ。
191デフォルトの名無しさん:2005/08/26(金) 14:50:40
>>190
stringstream
192デフォルトの名無しさん:2005/08/26(金) 14:56:09
char[]にこだわるなら処理系がstrstream使えるか調べろ。
193デフォルトの名無しさん:2005/08/26(金) 15:03:57
sprintf(buf, "%X", 100);
194190:2005/08/26(金) 15:16:03
>>193
あ、むっちゃ簡単じゃないですか。
ありましたね、そういうの。すみません。

>>191-192
ありがとうございます。
195デフォルトの名無しさん:2005/08/26(金) 20:07:06
テンプレートクラス内で型定義して

template <class T>
class Hoge{
  typedef vector<int> Array;   //新しい型の定義
  static Array staticData;    //定義した型の静的メンバ変数を使う
};

//cppファイルで静的メンバ変数の実体を
template<class T>
vector<int>     Hoge<T>::staticData;
ならOKですが

template<class T>
Hoge<T>::Array   Hoge<T>::staticData;
とやってもHoge<T>::Array型を作る事ができずエラーになってしまいます。
この場合の書式はどのようにすればいいのでしょうか?
コンパイラはVC2003です。
196デフォルトの名無しさん:2005/08/26(金) 20:13:36
>>195
template<class T>
typename Hoge<T>::Array Hoge<T>::staticData;
197デフォルトの名無しさん:2005/08/26(金) 20:53:04
>>196
なるほど、typenameですか。
どうもありがとうございました。
198デフォルトの名無しさん:2005/08/26(金) 20:56:40
hoge.hhに

class hoge {
private:
static const string name[3];
};

とあって、hoge.cc内に

const hoge::name[0] = "aho1";
const hoge::name[1] = "aho2";
const hoge::name[2] = "aho3";

とやると
error: conflicting types for `const std::string
hoge::name[1]

と怒られます。
member内のstatic constに配列は扱えないのですか?
199198:2005/08/26(金) 21:09:18
const hoge::name[3] = {"aho1", "aho2", "aho3"};
で出来ました。スレ汚しスマソ。
200デフォルトの名無しさん:2005/08/26(金) 21:55:56
クラステンプレートの中にメンバテンプレートを持たせたとき、
メンバの宣言と定義をわけて書く場合は、下のような感じでいいんでしょうか。
(これが一般的でしょうか、という意味です。試行錯誤でコンパイルが通るようになった結果がこれです)

template <class T> class A{
public:
A(T t){ }
template <class S> void f(S s);
};

template <class T> template <class S> void A<T>::f(S s)
{
}

「template <class T>」「template <class S>」の位置はこれでいいのかな、と。
たとえば「const C&」と「C const&」が同じ意味を持つように、上の例でも
他の書き方があったりしますか?
201デフォルトの名無しさん:2005/08/26(金) 22:56:34
>>197
なぜ typename が必要かわかってるのかなあ?

>>200
template<typename T> template<typename S> void A<T>::f(S s)
って、およびでない?
202200:2005/08/26(金) 23:12:41
>>201
(・∀・;)あぁ、それも他の書き方ですね。
キーワードの順序的にはこれしかない(これが普通)ってことですか。
203デフォルトの名無しさん:2005/08/27(土) 19:06:21
Fedora Core 2でUSB<->Serial変換を使って制御をやっています。
自前のclassですが、基本はC標準のread()とwrite()を使ってのやり取りです。
Win 2kのハイパーターミナルで通信するのに比べると、
FC2でreadする動作速度が遅いようです。

何かreadを高速化させる方法と言うのがあるんでしょうか?
タイミングの問題でしょうか。
204デフォルトの名無しさん:2005/08/27(土) 20:35:52
>>203

UNIXプログラミング質問すれ Part6
http://pc8.2ch.net/test/read.cgi/tech/1116908090/
205203:2005/08/27(土) 22:29:11
>>205
逝ってきます。
206デフォルトの名無しさん:2005/08/27(土) 23:18:31
1つ以上の要素を持つ STL コンテナから end() で反復子を取得し、それをデクリメント
した場合、その反復子はコンテナの最後の要素を示すようになるのでしょうか?
207デフォルトの名無しさん:2005/08/27(土) 23:21:05
>>206
そのコンテナのイテレータが ForwardIterator なら、大丈夫。
標準コンテナならすべて大丈夫。
208デフォルトの名無しさん:2005/08/28(日) 00:57:26
>>207 さんありがとうございます。

ということは std::list のようなノード型コンテナはダミーのノードを内部に持っているのでしょうか?
もしくは反復子の内部にノードのポインタ以外の情報も持っているのでしょうか?
209デフォルトの名無しさん:2005/08/28(日) 01:03:03
>>208
std::list なら実装がヘッダファイルに書いてあるはずだから、それを見るといいよ。
210デフォルトの名無しさん:2005/08/28(日) 01:45:13
exportが使えるようになるのはいつだろう…
211デフォルトの名無しさん:2005/08/28(日) 01:50:52
>>207
Bidirectional iteratorsの間違い?
212207:2005/08/28(日) 01:53:31
>>211
あ、そうか。 ForwardIterator だけじゃデクリメントが無いな。間違い。
213デフォルトの名無しさん:2005/08/28(日) 08:08:54
214デフォルトの名無しさん:2005/08/28(日) 16:26:51
質問させてください。
以下のようなプログラムを作り、g++でコンパイルして動作確認をしました。
//////// ここから////////
#include <iostream>

class Test {
public:
  void print(char *msg) {
    std::cout << msg << std::endl;
  }
};

int main() {
  Test t1; t1.print("First print()");
  Test().print("Second print()");
  (new Test)->print("Third print()");

  return 0;
}
//////// ここまで ////////
質問内容は次のレスに続きます。
215デフォルトの名無しさん:2005/08/28(日) 16:36:58



















続かねーよバーカ。
216214:2005/08/28(日) 16:44:20
main関数内1行目は普通に宣言してメソッドを使っているので
うまく動いて当然であり、なんら疑問はありません。

main関数内3行目は、
Test *pt = new Test;
という記述が使えることと、operator newがポインタを返すことから
(new Test)が新しいTestオブジェクトへのポインタであると予想して
記述しました。結果は予想どうりうまく動きましたが、本当に
この予想はあっているのでしょうか?

一番の疑問点はmain関数内2行目で
コンストラクタは返り値が無いはずなのにTest()があたかも
オブジェクトそのものである様に働いている点です。
いったいこれはどういう理屈なのでしょうか?

本屋で立ち読みして答えを探そうとしたのですが、
キーワードが分からずどこを探せばよいのか分かりませんでした。
もしよろしければ、何か手掛かりになるものを教えてもらえないでしょうか?
217デフォルトの名無しさん:2005/08/28(日) 17:01:05
>>216
new Test については、予想も何も「新しいTestオブジェクトへのポインタ」を返すのが new の仕様。
予想はあっているが、予想して使うものではない。
あと、一般的には new で得たポインタは後で delete できるように扱うべき。

Test() は Test 型のテンポラリオブジェクト(一時オブジェクト)を作る式。
つまり Test() はオブジェクトそのものとみなせる。
218デフォルトの名無しさん:2005/08/28(日) 17:03:56
>>216
そのTest()はコンストラクタじゃなくて一時オブジェクト。
219デフォルトの名無しさん:2005/08/28(日) 17:05:02
2分もたってかぶってたスマソ
220デフォルトの名無しさん:2005/08/28(日) 17:05:13
>>216
>結果は予想どうりうまく動きましたが、本当に
>この予想はあっているのでしょうか?
合ってる。

>一番の疑問点はmain関数内2行目で
>コンストラクタは返り値が無いはずなのにTest()があたかも
>オブジェクトそのものである様に働いている点です。
>いったいこれはどういう理屈なのでしょうか?
Test()は一時オブジェクトの明示的生成。
Test().print("Second print()")
という式全体の評価が終わったあと自動的に解体される。
221220:2005/08/28(日) 17:06:10
うおw 俺もスマソ
222デフォルトの名無しさん:2005/08/28(日) 17:09:09
一時オブジェクトってスタックに取られるんだろうなやっぱ。
でかいオブジェクトを一時オブジェクトで作ると、スタックいっぱい消費する?
223デフォルトの名無しさん:2005/08/28(日) 17:13:03
>>222
スタックに配置される処理系なら、そうなる
(そうでない処理系は使ったことないが)
224214:2005/08/28(日) 18:15:46
>>217,218,220
みなさん解説有難うございます。

つまり、例えば
Test t = Test();
これだと、一時オブジェクトを引数としてコピーコンストラクタが
呼ばれるということですね?

ところで、今回の「一時オブジェクト」はどの程度のレベルの本になら
書いてあるのでしょうか?中〜上級ぐらいの本でしょうか?
225デフォルトの名無しさん:2005/08/28(日) 18:20:30
もうちょっとマシな聞き方はできないのか?
プログラミング言語C++でも読んどけ。
226デフォルトの名無しさん:2005/08/28(日) 18:32:07
>>224 このサイトにいろいろ載ってるよ。 http://www.google.com/
227デフォルトの名無しさん:2005/08/28(日) 18:35:04
入門書にはあんまり載ってないかもね。
STL本だと結構使うから、さらっと説明される。
228214:2005/08/28(日) 21:15:30
>>225,227
そのあたりの本を見てみます。
有難うございました。
229デフォルトの名無しさん:2005/08/28(日) 21:56:32
勉強のために、他人が書いた上手いコードを探しています。
感動したPDSやソースコードを紹介していただけますか?
230デフォルトの名無しさん:2005/08/28(日) 21:57:26
>>229 www.boost.org
231デフォルトの名無しさん:2005/08/28(日) 21:57:45
Loki
232デフォルトの名無しさん:2005/08/28(日) 22:23:13
Lokiもう一票
これ読んだ前後でC++観が変わった
233デフォルトの名無しさん:2005/08/28(日) 23:30:11
>>230, 231, 232
どうもありがとうございます。
コツコツみていきます。
234デフォルトの名無しさん:2005/08/29(月) 00:42:45
文字をURLエンコードするにはどうすればいいのでしょうか。
235デフォルトの名無しさん:2005/08/29(月) 00:45:03
void urlencode(char moji, char kekka[3])
{
 sprintf("%%%02X", (unsigned char)moji);
}
236デフォルトの名無しさん:2005/08/29(月) 00:45:39
↑ごめん、kekka[4]の間違い
237デフォルトの名無しさん:2005/08/29(月) 01:06:31
>>236
kekkaを使ってないし、sprintfの引数おかしいし。
238デフォルトの名無しさん:2005/08/29(月) 01:18:31
void urlencode(unsigned char moji, char kekka[3])
{
 sprintf(kekka, "%%%02X", moji);
}
239デフォルトの名無しさん:2005/08/29(月) 01:48:03
結果が返らんだろそれは。
240デフォルトの名無しさん:2005/08/29(月) 03:18:43
241デフォルトの名無しさん:2005/08/29(月) 12:51:33
結果は引き数経由で渡すから使い勝手は悪いな。
242デフォルトの名無しさん:2005/08/29(月) 13:03:03
std::string urlencode(char moji)
{
std::ostringstream oss;
if (moji == ' ')
oss << '+';
else
oss << '%' << hex << setw(2) << static_cast<int>(moji);
return oss.str();
}
こんなのとか(動作確認なし)
243デフォルトの名無しさん:2005/08/29(月) 13:53:09
文字列対応
std::string urlEncode1(const char * str)
{
std::ostringstream oss;
while (str[0] != '\0') {
if (str[0] == ' ') {
oss << '+';
} else {
oss << '%' << std::hex << std::setw(2) << static_cast<int>(str[0]);
}
++str;
}
return oss.str();
}

std::string urlEncode2(const char * str)
{
std::string rtn;
while (str[0] != '\0') {
if (str[0] == ' ') {
rtn += '+';
} else {
char tmp[4];
sprintf(tmp, "%%%02x", str[0]);
rtn += tmp;
}
++str;
}
return rtn;
}
244デフォルトの名無しさん:2005/08/29(月) 17:42:59
グローバルに
struct Map {
 int x;
 int y;
 //などなど
};

Map g_Map[4096*4096];  //もっと広いかもしれない
とかいう馬鹿でかいデータの確保に挑戦して失敗した場合
例外をキャッチするのは無理なのでしょうか?
どこかの関数内で動的に確保したほうがいいのかな。
245デフォルトの名無しさん:2005/08/29(月) 17:45:42
>>244
そこは一般にヒープではないし、起動に失敗するだけで例外は飛ばないかと
246デフォルトの名無しさん:2005/08/29(月) 18:01:24
でも大抵のコンパイラでデフォルト設定だとスタックオーバーフロー起こしそうだな‥‥
247244:2005/08/29(月) 18:27:34
やばそうなので関数内で確保するようにしておきます。
248デフォルトの名無しさん:2005/08/29(月) 18:40:29
グローバル変数でいくらでかい変数とってもスタックオーバーフローにはならんだろ。
249デフォルトの名無しさん:2005/08/29(月) 19:09:22
>>247
関数内でとるのもいいけど、あんまりでかいデータを自動変数にすると、
スタックオーバーフロー起こす可能性があるから、ヒープに領域確保しておけ。
std::vector<Map> map( 4096 * 4096 ); みたいに。


250デフォルトの名無しさん:2005/08/29(月) 19:20:13
>>249
おとなしくvectorにしておきます。
ところで馬鹿でかい領域でもvectorのメモリアドレス連続性は保障されているのでしょうか?
std::vector<Map> map( 4096 * 4096 );
memset( &map[0], 0, sizeof(Map) * map.size() );
とやっても大丈夫でしょうか?

251デフォルトの名無しさん:2005/08/29(月) 19:23:26
>>250
一応現在は保障されているが
Mapがclassでデフォルトコンストラクタが定義されているなら
vector<Map>の構築時に全要素分呼ばれるので
Mapのコンストラクタでゼロ初期化するようにしとけばいい
252デフォルトの名無しさん:2005/08/29(月) 19:28:49
>>250
Mapがゼロクリアを保証できるならいいが、そうでないならstd::fill()を使うのが無難。
253デフォルトの名無しさん:2005/08/29(月) 19:35:46
C++はゼロクリアすると危険な場合があるので
(自分または継承元が仮想関数を持つなどでRTTI情報、vTblを持つ場合、
及びそういうオブジェクトをメンバとして一つでも持つ場合)
Mapがそれに該当するならmemsetだろうとfillだろうと危険ですな
254250:2005/08/29(月) 19:40:20
>>251-253
とにかくセル数が多くvTblのバイト分も馬鹿にならないので
継承や仮想関数は禁止でやってますが、
おとなしくコンストラクタで0クリアしておきます。
どうもありがとうございました。
255デフォルトの名無しさん:2005/08/29(月) 19:48:20
>>251
vector<T> a(n);は、T()で一時オブジェクトを作って
それを全要素分コピーコンストラクタで塗るので
通常のコンストラクタが全要素数分呼ばれるわけではないな
256デフォルトの名無しさん:2005/08/29(月) 19:58:42
mallocやnew char[]でいいやん
257デフォルトの名無しさん:2005/08/29(月) 20:21:18
>256
それは悪い意味でのCの慣習だ
258デフォルトの名無しさん:2005/08/29(月) 20:52:08
Win32のメモリ領域確保系関数って一回も使った事ないな

スレ違いですねすいません
259デフォルトの名無しさん:2005/08/29(月) 22:23:32
スレ違いが続くが。
コンストラクタでHeapCreateしてデストラクタでHeapDestroyするAllocatorを作ってみようかなと思案している。
260デフォルトの名無しさん:2005/08/29(月) 22:55:11
>コンストラクタでHeapCreateして
うわ!
>デストラクタでHeapDestroyするAllocator
うわわわわ!!
261デフォルトの名無しさん:2005/08/29(月) 22:56:08
>>253
fill()は代入だよ。
262259:2005/08/29(月) 23:03:06
>>260
何か問題でも?
263デフォルトの名無しさん:2005/08/29(月) 23:07:12
260じゃないけどそんなバカ正直なアロケータ書いても糞重いだけだと思う
264デフォルトの名無しさん:2005/08/30(火) 01:10:23
>>262
標準のコンテナに渡す場合、 non-static データメンバを持つ allocator は使えない。
265デフォルトの名無しさん:2005/08/30(火) 12:29:17
>>264
そうですか。
ではHeapCreate〜HeapDestroyはシングルトンにすることにします。
266デフォルトの名無しさん:2005/08/30(火) 13:24:35
typedef CTypedPtrArray<CObArray,CNode*> NodeArray;
class CNode {
public :
  NodeArray* GetChileNode();
}

このように書くと、「1行目でCNodeが見つからないよ」とコンパイラにはじかれてしまします。

CNode内のメソッドでNodeArray型を使用したいので、CNodeの前にNodeArrayを宣言したい。
しかし、CNodeの前にはNodeArrayが宣言できない。
という状態なのですが、どのようにすればこの状態を解決できるでしょうか?

アドバイスよろしくお願いいたします。
267デフォルトの名無しさん:2005/08/30(火) 13:27:56
class CNode;
とだけ宣言したらどうだろう。
268デフォルトの名無しさん:2005/08/30(火) 13:34:07
>>267
ありがとうございます。
先頭行に、「class CNode;」の宣言を入れたら、コンパイルが通りました。

クラス宣言を2回以上しても大丈夫な事を知りませんでした。
勉強になりました。
269デフォルトの名無しさん:2005/08/30(火) 13:35:43
>>268
一応
クラス宣言
class Hoge;
クラス定義
class Hoge { ... };

宣言と定義は違うってことで
270デフォルトの名無しさん:2005/08/30(火) 13:40:00
>>269
なるほど。
そういう扱いになる訳ですね。

ありがとうございました。
271デフォルトの名無しさん:2005/08/30(火) 13:42:20
>>269
定義は宣言でもあるってことも忘れてはいけない。

あと、クラス宣言、クラス定義については歴史的に混乱があるようなので、
古くからC/C++を使ってきた人と話すときは明確な区別をあてにしないほうがいい。
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#379
272デフォルトの名無しさん:2005/08/30(火) 13:54:29
>>271
定義は宣言を含むってのは
関数定義がプロトタイプ宣言を含むのと同じだね
273デフォルトの名無しさん:2005/08/30(火) 14:04:51
質問です。

struct X {};
typedef X * Handle;
typedef const Handle HandleA;
typedef Handle const HandleB;

上記定義において、
HandleA と HandleB の型が同一であることは規格で保障されていますか?
274デフォルトの名無しさん:2005/08/30(火) 16:24:59
>>273
もちろん。
そこで並べる順番は関係ない。
275273:2005/08/30(火) 18:35:28
>>274
ありがとうございます。
const Handle が、const X * に、
Handle const が、 X * const にそれぞれ展開されるんじゃないかと
悩んでいたのですっきりしました。
276デフォルトの名無しさん:2005/08/30(火) 21:02:21
メンバ関数ポインタを介して、基底クラスの関数を呼び出したいのですが
どうやっても上手くいきません。仮想関数では無理なのでしょうか。VC6使ってます。

#include <iostream>
using namespace std;

class Base
{
public:
  virtual void Foo()
  {
    cout << "Base::Foo" << endl;
  };
};

class Bar : public Base
{
public:
  virtual void Foo()
  {
    cout << "Bar::Foo" << endl;
  };
};

int main()
{
  Bar *pBar = new Bar;
  void (Base::*pFoo)() = pBar->Base::Foo;
  (pBar->*pFoo)(); // pBar->Base::Foo()
  delete pBar;
  return 0;
}
277デフォルトの名無しさん:2005/08/30(火) 21:16:20
>>276
おまいは、メンバ関数ポインタの定義の仕方をちゃんと調べたのかと(r
278276:2005/08/30(火) 21:34:21
>>277
戻り値の型 (クラス名::*)(引数リスト)

こう解釈してますが…何か違うのでしょうか?
279デフォルトの名無しさん:2005/08/30(火) 21:37:43
>>278
初期化子が変

それから、仮想関数へのポインタはvtblの先頭からのオフセット
280デフォルトの名無しさん:2005/08/30(火) 21:40:39
>>279
thisどこ?
281デフォルトの名無しさん:2005/08/30(火) 21:51:48
>>280
何が言いたい
282276:2005/08/30(火) 21:57:57
void (Base::*pBaseFoo)() = Base::Foo;
(pBar->*pBaseFoo)();

void (Bar::*pBarFoo)() = Bar::Foo;
(pBar->*pBarFoo)();

デバッガで追ってみましたがどちらも最終的にBar::Fooに。

Baseにキャストしても元がBarなんで、結局Bar::Foo

やっぱり無理なんですかねぇ...
283デフォルトの名無しさん:2005/08/30(火) 21:58:01
>>276
void (Base::*pFoo)() = &Base::Foo;じゃないとコンパイルが通らないと思うが。
そうしてメンバへのポインタを使ったところであれだ。自分で試してみろ。
284デフォルトの名無しさん:2005/08/30(火) 21:58:59
>>282
そりゃそうだ。じゃなきゃ仮想関数の意味がない。
285デフォルトの名無しさん:2005/08/30(火) 22:00:59
アップキャストしたらできないか?
286276:2005/08/30(火) 22:17:32
pBar->Base::Foo();
↑のように直接記述したり、virtual外せば問題ないのにな。

融通きかないみたいなんで別の方法考えます。
お騒がせしました。
287デフォルトの名無しさん:2005/08/30(火) 22:20:10
>>286
メンバへのポインタで仮想関数が適切に呼ばれないほうがよっぽど融通きいていないだろ。
288デフォルトの名無しさん:2005/08/31(水) 01:13:46
派生クラスが意図的に基底クラスのメソッド呼び出さないようにとかしてたら偉いことが起きそうだな‥
289デフォルトの名無しさん:2005/08/31(水) 01:47:50
明示的になら呼び出せても良さそうな気はするが。
290デフォルトの名無しさん:2005/08/31(水) 02:48:02
いや、明示的には呼び出せるけどその記述の仕方が気に入らないらしい
291デフォルトの名無しさん:2005/08/31(水) 10:51:07
>>282の書いてるプログラムの設計が気になる
292デフォルトの名無しさん:2005/08/31(水) 11:41:14
C++の例外処理機構って、ifとgotoでやれることのシンタックスシュガーみたいなもん?
もちろん関数を越えてジャンプできるのは凄いけど。
293デフォルトの名無しさん:2005/08/31(水) 11:42:30
>>292
そのとおりだけど、それを言うとあらゆる制御構造がifとgotoのシンタックスシュガーだな。
294デフォルトの名無しさん:2005/08/31(水) 11:48:00
>>293
でも他の制御構造は一応条件を判断する要素は残ってるでしょ?
C++の例外処理機構はそういうのすら画しちゃってるから。
295デフォルトの名無しさん:2005/08/31(水) 11:58:55
>>294
言いたいことがよくわからない。
例外処理の場合はソース中には分岐の条件が明示されないけど、
実際には分岐が行われる。
296デフォルトの名無しさん:2005/08/31(水) 12:48:16
>>295
例外 or setjmp/longjmpそれ自体は分岐じゃねーだろ。アフォ?
297デフォルトの名無しさん:2005/08/31(水) 12:50:19
まともに学ぶ気がない奴が言い訳を探してるだけだろ。
298デフォルトの名無しさん:2005/08/31(水) 12:53:10
話がかみ合わないスレはここですか?
299デフォルトの名無しさん:2005/08/31(水) 13:21:39
>>296
どのcatchに捕捉されるかの分岐があるだろ。
300デフォルトの名無しさん:2005/08/31(水) 13:29:13
>>292
更に遡るときローカル変数のデストラクタを呼んでいくのを忘れるな。
301デフォルトの名無しさん:2005/09/01(木) 04:15:26
>>300
それは例外処理とは別の話
302デフォルトの名無しさん:2005/09/01(木) 14:30:49
例外処理とstack unwindingは切っても切れない関係にあると思うけど
303デフォルトの名無しさん:2005/09/01(木) 16:44:30
{}ブロックから抜けるときにスコープの変数解放するってだけの話じゃん。例外とか関係ないし。
304デフォルトの名無しさん:2005/09/01(木) 17:01:15
>>303
はあ、それをするのが例外処理の重点のひとつじゃないか
何言ってんの
305デフォルトの名無しさん:2005/09/01(木) 17:16:25
ifだろうがgotoだろうがthrowだろうがブロック抜けるときにやる処理は変わらねーんだよ
例外処理機構だけが特別になにかするわけじゃないっ話だよ
筋読め
306デフォルトの名無しさん:2005/09/01(木) 17:17:03
つかシンタックスシュガーであるか無いかからどんな価値のある結論が出るというのか
307デフォルトの名無しさん:2005/09/01(木) 17:38:38
Stack unwinding (wikiの定義)

関数がreturnするときのスタックの調整
(大昔からの用語だと思われる)

stack unwinding (C++の定義)

tryからcatchに移るときにデストラクタが自動で呼ばれるプロセス
(標準文書で、例外が"return"中のときのいろんな制限の説明のために
用意された用語。7ヶ所出てくる)


wikiの定義で語っている多くの本が間違っていると思われる。
wikiの定義で語るならreturnの説明のときにするべきだから。
308デフォルトの名無しさん:2005/09/01(木) 17:43:50
なんか、言語の機能としての「例外処理」と、広義の「例外処理」とがごっちゃになっているなあ
言語の「例外処理」機能が話の主題のはずだか、
スタックの巻き戻しが無関係とかいってる奴はそこいら変を勘違いしてる

309デフォルトの名無しさん:2005/09/01(木) 18:38:16
>C++の例外処理機構って、ifとgotoでやれることのシンタックスシュガーみたいなもん?

setjmpとlongjmpのようなものだよ派
 |
 +- stack unwinding について触れる派
 |
 +- 掲示板で難しい話はしない派

catch節にgotoでジャンプするようなものだよ派
 |
 +- 関数を越えてジャンプできるのは凄いよ派
 |
 +- if や goto と全く同じだよ派
310デフォルトの名無しさん:2005/09/01(木) 19:58:55
>なんか、言語の機能としての「例外処理」と、広義の「例外処理」とがごっちゃになっているなあ

誰もそこはごっちゃにしてないと思うが
311デフォルトの名無しさん:2005/09/01(木) 20:13:10
一連の流れを読んでいて、「C#で実現してることなんて全部
Cでできることばっかりじゃないか、たいしたことないね」、
と言って何も学ぼうとしない前職の上司(44歳、Cとawkしか
使えないので役に立たない)を思い出した。
312デフォルトの名無しさん:2005/09/01(木) 20:19:33
>>310
じゃあ、何で例外処理機能の話をしてるのに、「stack unwinding は関係ない」という話が出てくるんだ?
勘違いしてるとしか思えん
313デフォルトの名無しさん:2005/09/01(木) 21:20:44
すべての言語はチューリング等価だよ。
314デフォルトの名無しさん:2005/09/01(木) 21:28:17
そもそもシンタックスシュガーって何よ。
315デフォルトの名無しさん:2005/09/01(木) 21:31:05
316デフォルトの名無しさん:2005/09/01(木) 21:36:19
>>305
setjump〜longjumpでデストラクタが呼ばれないのはどうお考えで?
317デフォルトの名無しさん:2005/09/01(木) 21:46:58
つか>>315の説明から判断すると高級言語全体がそもそもシンタックスシュガーだろ。
重箱の隅つついてどうでもいい話引き伸ばすなっての
318デフォルトの名無しさん:2005/09/01(木) 22:06:56
>高級言語全体がそもそもシンタックスシュガーだろ
これが元の話と何の関係もないのは言うまでも無いが、どうでもいい話というのは同意
319デフォルトの名無しさん:2005/09/01(木) 22:10:07
例外機構はifとgoto、それからグローバル変数とか戻り値とかを使えば
「ほとんど同じ」ことは出来るので、シンタックスシュガーと言えるかもね。だから何>>292

となると次に興味が沸くのはなぜC++には例外が導入されたか、
どのように使い分けるのが良いか、といったところかな。
320デフォルトの名無しさん:2005/09/02(金) 15:31:21
例外といえば、前から気になっていたことがあるので質問します。

access_violation
break_point
derived_by_zero
page_error
stack_overflow

の各種例外を定義するとき、
それぞれどの標準例外クラスから派生するのが妥当でしょうか?

stack_overflow は std::overflow_error、
derived_by_zero は logic_error かなと考えていますが。
皆さんの意見を聞かせてください。
321デフォルトの名無しさん:2005/09/02(金) 15:40:04
runtime_error
322デフォルトの名無しさん:2005/09/02(金) 18:37:06
exception
323デフォルトの名無しさん:2005/09/02(金) 18:59:34
null_pointer
324320:2005/09/02(金) 19:01:57
derived_by_zero ってなんだ。素で間違えた
正しくは divide_by_zero です。

access_violation は runtime_error
break_point は domain_error
divide_by_zero は logic_error
page_error は runtime_error
stack_overflow は domain_error

今のところ、上記のような感じで考えてますけど、
厳密に区分けするのは面倒なので、>>322 さんの言うとおり
全部 exception から派生させるのもひとつの手かも。
325デフォルトの名無しさん:2005/09/02(金) 19:05:31
>>324
OSかエミュレータでも作ってるん?
stack_overflowはruntime_errorっぽい気はするが
326デフォルトの名無しさん:2005/09/03(土) 13:41:11
C++でコンストラクタから別のコンストラクタを呼ぶにはどうすればいいですか?

class Test
{
private:
int value_;


 public;
 Test()
 {
  //Javaだとここにthis(150)と書けば↓のコンストラクタが呼べる 
 }

 Test(int value) : value_(value)
 {
 }

}
327デフォルトの名無しさん:2005/09/03(土) 13:46:37
別のコンスラクタは呼べない。
328326:2005/09/03(土) 13:50:58
ガーン…

ということは
Test(int a, double b, std::string c, T d, … U w) : a(a), … w(w)
{
 //長ったらしいいろんな初期化処理(数十行)
}
というコンストラクタがあって


Test(int a, double b, std::string c, T d, … U w, V x)
というコンストラクタを作りたくなったら
処理は全部コピペするしかないということですね…

やっぱC++は設計が古いんだな…
329デフォルトの名無しさん:2005/09/03(土) 13:53:17
>>326
C++オブジェクトモデルでは、オブジェクトのライフタイムが
コンストラクタが完了した時点で始まると定義されている。

コンストラクタからコンストラクタが呼び出せるとすると、
オブジェクトのライフタイムが定まらない。

例えば this(150) のあと、 Test() の続きで例外がスローされた場合に
デストラクタが実行されるかどうかが定まらなくなる。
330デフォルトの名無しさん:2005/09/03(土) 13:53:36
プライベートメンバ関数に初期化処理を分離すりゃええやん
331デフォルトの名無しさん:2005/09/03(土) 13:55:15
*this = Test(150);
332デフォルトの名無しさん:2005/09/03(土) 14:06:09
非コンストラクタなメンバ関数だとメンバ変数の初期化できないけどな。
333デフォルトの名無しさん:2005/09/03(土) 14:17:21
>>328
初期化メソッド作れ
334デフォルトの名無しさん:2005/09/03(土) 14:19:18
>>330,333
代入と初期化の違いはわかってて言ってるのか?
335デフォルトの名無しさん:2005/09/03(土) 14:26:04
どうしても初期化が必要ならポインタで管理すればいいんじゃ
そのあたりは設計の妥協点
336デフォルトの名無しさん:2005/09/03(土) 15:06:27
コピペするくらいだったらマクロ使えばいいじゃん。
337デフォルトの名無しさん:2005/09/03(土) 15:59:14
>>326
それができるんだったら、そもそもメンバ初期化リストの意味がないんじゃない?
: value_(value) は value_ = value; とは違う。
初期化はそのオブジェクトの一番最初の構築を意味するわけで、
コンストラクタからコンストラクタを呼べたら二回メンバ変数を初期化する事になってしまう。

そもそもJavaでは : value_(value) とは書けないので、その例でJavaでは呼べると言っても意味がないと思うけど。
コンストラクタの持つ意味自体がC++とJavaでは少し違っているんじゃないのかなぁ。
いつメンバが初期化(最初の構築)されるのかとか。
Javaはメンバとなるオブジェクトを基本型以外は参照型で持つし、
C++ほど定数性にこだわっていないから、その辺の違いから来ているのかもね。
338デフォルトの名無しさん:2005/09/03(土) 17:22:44
>>328
そのクラスをインターフェイス・クラスと内部実装クラスに分離して、インターフェイスが内部実装を非公開継承もしくはメンバとして持つという手段もある。
インターフェイスの各コンストラクタで共通する部分を内部実装のコンストラクタに落とし込むわけだ。
339デフォルトの名無しさん:2005/09/03(土) 19:05:59
これだからJava厨は。
340デフォルトの名無しさん:2005/09/03(土) 19:34:19
何!さっきからどうもJava臭いと思っていたらやっぱりそうか。
341デフォルトの名無しさん:2005/09/03(土) 20:03:54
総合的に言って、Javaのほうが優れているというのは常識なのでしょうか?
342デフォルトの名無しさん:2005/09/03(土) 20:09:01
>>341
評価基準による。自分に合った評価基準で言語は選ぶものだ。

っていうか総合的って何だ。っていうか釣りだろ。
343デフォルトの名無しさん:2005/09/03(土) 20:10:43
つーか釣られんな
344デフォルトの名無しさん:2005/09/03(土) 20:35:16
つーかJavaに限らずD言語とかでもthis()できるよ
345C初心者です:2005/09/03(土) 21:18:09
質問です。
NT系のOSってノートパッドに書き込める容量は制限されて無いみたいなんですけど、
Meってノートパッドに書き込みすぎるとメモリ不足って言う表示がでてしまい、それ以上書けなくなってしまいます。
そこで、Meで動作する容量の制限されないノートパッドをC言語で作ってるんですけど、イマイチ作れません。
だれか作り方教えてください。お願いします。
346デフォルトの名無しさん:2005/09/03(土) 21:21:36
>>345
ここもスレ違い。タイトルを読むってことはできないのか?
347デフォルトの名無しさん:2005/09/03(土) 21:23:31
まず根本的にだ。
おまいがやりたいのはCでメモ帳もどきを作ることなのか、
容量制限のないメモ帳を使いたいのかということ。

前者なら自分で勉強しろとしか言えん。つかその程度のことを調べられないのなら
根本的にプログラミングは向いていない。
Win32APIとか、Windowsプログラミングでググればいくらでも参考になるページは出てくるから。

後者なら、んなものいちいち自作しないで既存のエディタ使え。
秀丸でもEmEditorでもxyzzyでもTeraPadでも、メモ帳とは比較にならない
レベルのエディタが腐るほどあるから。
348C初心者です:2005/09/03(土) 21:28:03
>>347
そうですか。回答ありがとうございます。
ちなみに、容量制限のないメモ帳をVCなど使わないで作りたかっただけです。
349デフォルトの名無しさん:2005/09/03(土) 22:50:18
とりあえずその話題はこっちか?

【初心者歓迎】C/C++室 Ver.21【環境依存OK】
http://pc8.2ch.net/test/read.cgi/tech/1125743714/

ただ、あまりにも質問が漠然としてるからそのままじゃまともなレスは期待できないだろうな。
350デフォルトの名無しさん:2005/09/03(土) 23:43:15
VCなど使わないで作りたかったとは、BCCを使っているとか、GCCでやっているとかか?
351デフォルトの名無しさん:2005/09/04(日) 07:55:11
CよりC++やC#やJavaやHSPを使った方がいいんジャマイカ
352デフォルトの名無しさん:2005/09/04(日) 11:27:31
HSPてなに?
353デフォルトの名無しさん:2005/09/04(日) 11:29:17
Hなスピード
354デフォルトの名無しさん:2005/09/04(日) 11:57:42
C++やC#やJavaと同列に置くのが解せん
355C初心者です:2005/09/04(日) 12:08:12
レス遅れてスイマセン。
>>349
もうちょっとソース組み立ててから相談します。
>>350
BCCでコマンドプロントを使ってコンパイルしてます。
>>351
説明間違えてました、C++で作ってます。
356デフォルトの名無しさん:2005/09/04(日) 13:17:57
>>354
最近は構造体や関数もあるらしいよ
357デフォルトの名無しさん:2005/09/04(日) 13:38:18
それだけじゃまだOOPLになってない
358デフォルトの名無しさん:2005/09/04(日) 13:46:01
>>356
って、昔は構造体も関数もなかったのかよ!
よくそんなもんを使おうと思う人間がいたものだ。
359デフォルトの名無しさん:2005/09/04(日) 17:35:41
タダで楽ですから。この二つの単語に人間は惹きつけられる
360デフォルトの名無しさん:2005/09/04(日) 20:05:44
弟子食いの古賀先生w
361デフォルトの名無しさん:2005/09/04(日) 22:44:38
こんばんわ、質問があります。
環境C++6.0 windowsxp
今、ハードディスクやCDの容量を調べるプログラムを組んでいます。
GetDiskFreeSpaceExをつかって、ハードディスクの使用量と空き容量は入手できたのですが、
焼かれたCDの空き容量が0になってしまうのです。マイコンピュータのCDドライブのところから、
プロパティを開くと空き容量が表示されるのですが、プログラムでそれを入手することが出来ないのです。
基本的な質問ですが、知恵をお貸し願えませんでしょうか?
よろしくお願いします。
362デフォルトの名無しさん:2005/09/04(日) 22:51:38
363デフォルトの名無しさん:2005/09/04(日) 23:05:51
ありがとうございます >>362
364デフォルトの名無しさん:2005/09/05(月) 02:22:31
たとえば以下のようなセルからなるマップというクラスがあるとして
class Map {
  struct Cell {
    
  };
  friend class Cell;
  int WorldWidth;   //世界の大きさなどはMapクラスが管理
  int WorldHeight;
  Cell* pCell;     //格CellへのアクセスをMapクラスが抽象化する。
};

ここでCellクラス内のメンバ関数が親のMapクラスの情報が欲しいとなれば
void Hoge(Map* pMap)
{
 pMap->WorldWidth;
}
と、関数の引数にもらってthisポインタのように使う以外に何かいい方法ありますか?
MapクラスへのポインタをCellクラスのメンバ変数に持たせるのはメモリの無駄遣いだと思うし、
静的メンバ変数などにすると複数のMap、(裏の世界とか、夢の世界とか)に対応できないような気もします。
関数の引数でアクセスするのが一番素直なようにも思うんですが、
Cellのメンバ変数が再帰しまくったときにスタックに積みまくるのもなんか無駄なような気がしてます。
なんかこう書くとエレガントだとか、効率的だとかあればご教授お願いします。
365デフォルトの名無しさん:2005/09/05(月) 03:55:05
>>364
訂正
>Cellのメンバ変数が再帰しまくったときに
Cellのメンバ関数が再帰・・・
です。
366デフォルトの名無しさん:2005/09/05(月) 04:41:06
>>364
CellがMapを関知しちゃイカンだろ
CellにはMap側で計算済みの値を渡すべき
367デフォルトの名無しさん:2005/09/05(月) 04:55:46
>>364
基本的に>>366の言うとおりだし、
そもそもスタックが気になるほど再帰しまくるならデータ構造から見直すべき。
しっかりした構造なら大抵は再帰の深さなんてせいぜいlog(セルの個数)程度のオーダーだと思われ。
それを超えるなら簡単に再帰を使うべきではない。
つまり引数にすること自体は問題なし。
368デフォルトの名無しさん:2005/09/05(月) 17:23:26
VC7.1+STLPortなんですが、
stringstreamのポインタ操作が機能しません。
具体的には下記のコードでp0とp1が共に0を返し
seekpが機能しません。
結果"abcdefgh"と出力されます。
strstreamの場合正常に機能します。
なぜでしょうか?

std::stringstream stream( std::ios::out );
const std::ios::pos_type p0 = stream.tellp();
stream << "abcde";
const std::ios::pos_type p1 = stream.tellp();
stream.seekp( -3, std::ios::cur );
stream << "fgh" << std::endl;
369320:2005/09/05(月) 18:19:26
>>325
非常に遅くなりましたけど、
Win32 の構造化例外を、C++ の例外に変換する際のはなしです。
普通は華麗にスルーするところですが、どうしても捕捉しておく必要があったので。


370デフォルトの名無しさん:2005/09/05(月) 20:48:09
>>368
STLPortのバグ
VC6.0ならともかくVC7.1なら付属のほう(dinkumware)がむしろ安定してるからそっち推奨
371デフォルトの名無しさん:2005/09/05(月) 21:42:34
>>370
嘘つくなタコ。std::ios::outを指定すると、:ostream iteratorが
指定されるだろ。これはramdom access iteratorではないので、
シークができないし、現在位置も知る事ができない。
従って、tellp()をすると、std::string::nposが返る。

正しく動かすには、std::stringstream stream( std::ios::out | std::ios::in );
としないとだめ。

むしろ、このまま正しく動くような動作をするdinkumwareの方が糞だろ。
少なくとも俺の環境でVC7.1+STLport4.6.2では、上のようにフラグを指定
すれば正しく動作する。
372デフォルトの名無しさん:2005/09/05(月) 21:44:31
あ、失礼
×std::string::npos
○std::ios::pos_type(-1)
373370:2005/09/05(月) 22:11:07
すまん。質問のios::outの指定を完全に見逃してた。
370は撤回させてくれ。371のとおり。
374368:2005/09/05(月) 22:40:58
>>372-373
お答えありがとうございました。
勉強になりました。
375デフォルトの名無しさん:2005/09/05(月) 23:48:48
ポインタの参照先に実体があるかどうかを調べる関数はありますか?
376デフォルトの名無しさん:2005/09/06(火) 00:03:07
ない。
377デフォルトの名無しさん:2005/09/06(火) 00:04:26
サンクス
378デフォルトの名無しさん:2005/09/06(火) 00:24:33
コレじゃ無理かな。
今環境無いから試せないけど。VC++限定で

template< typename T > bool is_valid_pointer( T const volatile * p )
{
 __try{ (void)(*p); }
 __except( EXCEPTION_EXECUTE_HANDLER ) { return false; }
 return true;
}
379デフォルトの名無しさん:2005/09/06(火) 00:26:15
自分で管理するという方法もある。
俺ならスマートポインタを素直に使ってそんな状況そのものを発生させないが

#include<set>
template<typename T>
struct valid{
    static std::set<const valid*>check;
    valid(){check.insert(this);}
    ~valid(){check.erase(this);}
    static bool isValid(const T*p){return check.count(p)!=0;}
};
template<typename T>
std::set<const valid<T>*> valid<T>::check;

こんな風に定義して

//有効か確認機能付の構造体
struct X:valid<X>{};

X::isValid(p);//pが有効か確認
380デフォルトの名無しさん:2005/09/06(火) 00:41:02
xをy(≠整数)乗するにはどうしたらいいのでしょうか?
381デフォルトの名無しさん:2005/09/06(火) 00:51:27
パワー、パワー
382デフォルトの名無しさん:2005/09/06(火) 00:52:49
#include <math.h>
#include <stdio.h>

void main( void )
{
double x = 2.0, y = 3.0, z;

z = pow( x, y );
printf( "%.1f to the power of %.1f is %.1f\n", x, y, z );
}
383デフォルトの名無しさん:2005/09/06(火) 00:59:34
>>381-382
お二方ありがとうございました
384364:2005/09/06(火) 02:12:33
>>366さんの
おっしゃるとおりだと思いますが、
元々の形はすべてのCellで共通のデータをstaticとして持つでした。
しかしstaticで持ってしまうと、複数のマップ対応に拡張できない。
ということで364の形式、MapクラスはCellクラスからなる、
Cellの共有データはMapクラスが管理ということで
Map Omote_no_sekai;
Map Ura_no_sekai;
というように書けるようにしてみました。
今のところCellがMapを関知することのデメリットはよく分かりません。
静的メンバ変数に比べると関数引数で受け取る必要があるので面倒ですが・・・。

>>367
確かにlogのオーダーなので、それほど問題ないようならこのままいってみます。

蛇足になりますが、静的メンバ変数をあるグループごとに複製したい場合
テンプレートのを使うのは邪道でしょうか?
つまり
template<int WorldSize, int MapType>
class Cell
{
  static int arekore;
};
として
Cell<256, 0> Omoteno_sekai[256*256];
Cell<256, 1> Urano_sekai[128*128];
Cell<128, 2> Yume_no_sekai[128*128];
としてしまう手です・・・。

385デフォルトの名無しさん:2005/09/06(火) 02:56:05
>>371,373
> std::ios::outを指定すると、:ostream iteratorが指定される

これ、何の話?さっぱりわからない。
「:ostream iterator」って何?
何に「:ostream iterator」が指定されるの?

> std::stringstream stream( std::ios::out | std::ios::in );

これはつまり std::stringstream stream こうしとけばいいってことだな。
386デフォルトの名無しさん:2005/09/06(火) 03:28:14
>蛇足になりますが、静的メンバ変数をあるグループごとに複製したい場合
テンプレートのを使うのは邪道でしょうか?

その方法はあまりいいものとはいえない。
Cellをテンプレートにすると、当然それを含むMapもテンプレートにしなければならなくなる。
すると、そのMap、Cellを引数にするような関数もテンプレートにせねばならない、などと
際限がなくなってしまう。

struct MapInfo{ int nWorldHeight; int nWorldWidth; };
struct Cell
l
void Hoge(const MapInfo* p)
{....}
.};
class Map
{
MapInfo m_mapInfo;
Cell* m_pCellArray;//Cellのコレクションをメンバに持つ。
};
・CellをMapの外に出す。
・friend class はできるだけ使わない。
って感じで、テンプレートを使わない場合はできるだけMapとCellとの癒着をなくす方がいい。
387デフォルトの名無しさん:2005/09/06(火) 04:23:52
>>371
自分もちょっとわかりません。
それはC++の仕様なのでしょうか?
それともSTLPortの仕様なのですか?

STLPortのソースを追ってみると
STLPortのstringstreamは、内部にstringとは別の小さいバッファを持っていて
何らかの条件でバッファの中身をstringにフラッシュするみたいです。
tellpが返すポインタはその小さいバッファのものである為
いままで書き込んだ文字列を考慮した位置を返してくれる訳ではないみたいです。
388デフォルトの名無しさん:2005/09/06(火) 04:24:34
>>385
先頭の ':' は明らかに typo だろ。

>これはつまり std::stringstream stream こうしとけばいいってことだな。

その通り。それがデフォルト・パラメータになっている。わざわざ std::ios::inを
外したオープンフラグを指定したものだから、std::ostringstreamと同じに
なってしまった。それだけの話だ。
389デフォルトの名無しさん:2005/09/06(火) 04:25:26
>>387
反復子(iterator)について勉強し直せ。自然と理解できる。
390デフォルトの名無しさん:2005/09/06(火) 04:31:15
>>389
basic_ostringstreamはbasic_ostreamの派生クラスですよね?
そのbasic_ostreamのメンバであるtellpが
basic_istreamを派生することによって使えるようになるなんて
なんか解せないんですが、それが正しい動作なんですか?
391デフォルトの名無しさん:2005/09/06(火) 04:45:19
いろいろ調べてみましたが
basic_ostringstreamがbasic_ostreamのメンバアクセスに制限があるという
資料は見つけられませんでした。
basic_stringのiteratorはランダムアクセスイテレータですから
実装不可能だとも思えません。
やっぱりSTLPortのせいだと思うんですが・・
392デフォルトの名無しさん:2005/09/06(火) 04:49:59
>>390
それは勘違い。std::basic_ostreamの反復子は出力反復子(ostream iterator)のため、
tellp()、seekp()メンバ関数の意味を正しくインプリメントできないのだ。

同様にして、std::basic_istreamの反復子は入力反復子(input iterator)のため、
tellg()、seekg()メンバ関数の意味を正しくインプリメントできない。

tellp()、tellg()、seekp()、seekg()は、前方反復子(forward iterator)でのみ、正しい
本来の意味のある値を返す。この前方反復子を備えているクラスは、std::basic_fstreamと
std::basic_stringstreamだけだ。

>>371の、random access iteratorというのは間違い。そこまで厳しい要件を必要と
しない。しかし、おっしゃる通り、std::basic_ostreamとstd::basic_istreamを継承した
クラスでないと、tellp()〜seekg()メンバ関数が使えない。従ってstd::vectorのような
ストリームを継承したのではないくコンテナは、それらの特別なメンバ関数がない。

当然std::listのような双方向反復子(bidirectional iterator)を備えたクラスでも、
seek?()、tell?()が使えない。
393デフォルトの名無しさん:2005/09/06(火) 04:51:38
あーでもこの時間だしな・・・・誰かISO/IEC調べてもらえませんか?俺はもう
寝なければならないので。
394デフォルトの名無しさん:2005/09/06(火) 06:32:04
>>388
typo だとは思うが、あまりにも脈略が無いんで何を打とうとしたのか想像できない。
std::ostringstream と同じになったと言われても、 std::ostringstream の
tellp() が 0 を返す理由になるとは思わない。
(>371,372 が正しければ -1 が返るらしいが、 >368 では 0 が返ると言われている)

>>389
うーん。 iterator はよく知っているつもりだけど、 >371 の意味は理解できない。

>>392
「std::basic_ostream の反復子」の時点で意味不明なわけだが。
std::basic_ostream::iterator のようなメンバは存在しない。

>>393
今までは何を根拠に言ってたんだ?
395デフォルトの名無しさん:2005/09/06(火) 06:44:05
cygwin g++ 3.4.4 で試してみた。
以下のコードで 'abfgh' が出力された。
やっぱ STLport のバグじゃないの?
>370,373 は、なんで >371 で納得したんだろう?

#include <sstream>
#include <iostream>

int main()
{
  std::stringstream stream( std::ios::out );
  const std::ios::pos_type p0 = stream.tellp();
  stream << "abcde";
  const std::ios::pos_type p1 = stream.tellp();
  stream.seekp( -3, std::ios::cur );
  stream << "fgh" << std::endl;

  std::cout << stream.str() << std::endl;
  return 0;
};
396デフォルトの名無しさん:2005/09/06(火) 09:04:37
iostreamはアイオーストリーム

じゃあ、curses ってなんて読むの
397デフォルトの名無しさん:2005/09/06(火) 09:21:54
>>396 辞書で調べれ
398デフォルトの名無しさん:2005/09/06(火) 10:08:34
397>>
辞書に載ってないから聞いたんだ〜!!
ちなみに、cygwin も皆さんは何て読んでいるのですか?
399デフォルトの名無しさん:2005/09/06(火) 10:14:30
400デフォルトの名無しさん:2005/09/06(火) 11:25:26
basic_ostream の tellp の説明を読むと、以下のように書いてある。

> basic_iosのメンバ関数 fail()がtrueを返すと、tellp() は、
> pos_type(off_type(-1))を返して失敗を伝えます。
> それ以外の場合は、rdbuf()-> pubseekoff(0,cur, out)を呼び出して、
> 出力シーケンスのカレントの位置を返します。

よって tellp の実装は、streambuf の実装に依存する。
basic_stringbuf の seekoff の実装は、

> オープンモードがin | outの場合、
> 入力、出力両方のシーケンスのストリーム ポジションを変更します。
> オープン モードがinのときは、入力シーケンスのストリーム ポジションのみ変更し、
> outのときは出力シーケンスのストリーム ポジションのみ変更します。
> 新しいポジションは、off(ずれ)とway(参照ポイント)の2つのパラメタを組み合わせて計算します。
> 位置変更前にシーケンスのカレントの位置が無効の場合、
> オペレーションは失敗し、pos_type(off_type(-1))が返り値になります。
> それ以外の場合は、カレントの新しい位置を返します。

とあるから、>>368 は STLport 側の問題のような気もする。
401デフォルトの名無しさん:2005/09/06(火) 17:36:30
あるでかいライブラリを二つ使って一つのプログラムを作りたいんですが、
片方で定義しているrealが他のライブラリでも定義されてしまっているらしく、
error: `typedef double real' redeclared as different
というエラーが出ます。片方の名前をreal2とかに変えれば解決しそうなんですが、
もっと良い解決方法があったらおしえてチョ!
402デフォルトの名無しさん:2005/09/06(火) 17:42:04
namespaceも使ってないライブラリは糞
403デフォルトの名無しさん:2005/09/06(火) 17:42:21
>>401
namespace A
{
#include <A.h>
}

namespace B
{
#include <B.h>
}
404デフォルトの名無しさん:2005/09/06(火) 17:54:21
>>403
そうして、Aのtypedef double realを使いたくて
using namespace A;
とやると、B.hのなかの他の定義ファイルは使えなくなってしまうんですよね?
B.hの他の定義は使いたいんだす。
405デフォルトの名無しさん:2005/09/06(火) 18:05:08
>>404
A::real って書けばいいじゃん。
406デフォルトの名無しさん:2005/09/06(火) 18:11:33
>>404
君もC++プログラマなら聞き分けたまえ。
407デフォルトの名無しさん:2005/09/06(火) 18:23:34
がんばって名前変えるかな。。。
408401:2005/09/06(火) 18:24:17
サンクス>all
409デフォルトの名無しさん:2005/09/06(火) 20:25:51
>>400
いやだからさ、俺のVC7.1+STLportでは、0を返さず、ちゃんと正常に-1を
返すわけよ。>>368と結果が違うというのはどういう事なのかと。
410デフォルトの名無しさん:2005/09/06(火) 20:52:11
>>409
STLportのインストール方法が違うとか。DLLでビルドしたか、
ビルドせずに使っているかで結果が違うとか。
411デフォルトの名無しさん:2005/09/06(火) 21:07:10
>>410
知らん。俺はビルドして使ってるけど正常動作した。それを言いたいだけ。
ビルドせずに使ってて不具合起きたんなら、同じビルドせずに使ってる奴に聞け。
412デフォルトの名無しさん:2005/09/07(水) 00:09:34
すみません、行き詰ってしまって質問します。

現在、ビットマップ画像を読み込んで画像処理をした後に保存するプログラムを作成中なのですが、
ビットマップを表示させるところまでは出来たのですが、再描画ができません。

そこで画像処理をした画像をビットマップに保存して、再描画されるようにしたいのですがどうしたらいいでしょうか?
以下にソースを載せます。(環境はVC++6.0です)
413デフォルトの名無しさん:2005/09/07(水) 00:11:01
まて
414デフォルトの名無しさん:2005/09/07(水) 00:12:40
ソースはスレに書かないで別のファイルに書いてアップしたほうがいいんじゃないか?
長くなりそうだし…。
415デフォルトの名無しさん:2005/09/07(水) 00:13:07
//ビットマップの初期化
void CWallChangerDlg::InitializeBitmap()
{
SaveBitmap.DeleteObject();
CRect ClientRect;
GetClientRect(ClientRect);
m_height = ClientRect.bottom-90;
m_width = ClientRect.right-10;

CClientDC dc(this);
CDC MemDC;
MemDC.CreateCompatibleDC(&dc);
SaveBitmap.CreateCompatibleBitmap(&dc,m_width,m_height);
MemDC.SelectObject(&SaveBitmap);
MemDC.PatBlt(0,0,m_width,m_height,WHITENESS);
}
初期化したSaveBitmapに読み込んで画像処理したものを保存したいのです。
(その後OnPaintで呼び出します。)
416デフォルトの名無しさん:2005/09/07(水) 00:15:28
待てと言われたのに…
417デフォルトの名無しさん:2005/09/07(水) 00:16:29
激しくスレ違い
418デフォルトの名無しさん:2005/09/07(水) 00:19:22
>>413、414、416
申し訳ない。書き込んでから気づきました。

あと補足。
ダイアログベースで、読み込んだ画像がダイアログ中央に出てきます。
それをSetPixel等を使って2値化 ・・・までは出来ました。
でも再描画されない・・・orz
419デフォルトの名無しさん:2005/09/07(水) 00:20:35
>>418
イヤマテ勘違いしてる、ソースを貼るのがどうこうじゃなくて、>>417
420デフォルトの名無しさん:2005/09/07(水) 00:22:40
>>417,419
スレ違いだったのですか・・・。板で質問するの初めてだったのでわからず、スミマセン。
421デフォルトの名無しさん:2005/09/07(水) 00:24:07
どうやら2chも初めてらしい
422デフォルトの名無しさん:2005/09/07(水) 01:27:18
C++でWindows上で動くファイアウォールは作れますか?
423デフォルトの名無しさん:2005/09/07(水) 01:29:30
坊や…良い子だから早く寝な
424デフォルトの名無しさん:2005/09/07(水) 06:33:09
C++で童貞捨てられますか?
425デフォルトの名無しさん:2005/09/07(水) 06:56:40
>>424
順番が逆だ。まず童貞を捨ててからC++をやれ。そうすれば立派に禿げる。
426デフォルトの名無しさん:2005/09/07(水) 08:36:12
>>409,411
名無しで「俺」とか言われても誰だかわからん。
tellp() が -1 を返すのが正しいと言う根拠は何?
427デフォルトの名無しさん:2005/09/07(水) 10:58:20
it++
http://itpp.sourceforge.net/latest/
をMKLなしで使う方法ないでしょうか?
428427:2005/09/07(水) 10:59:24
バージョン3-8-1をwindowsから使いたいのです
429デフォルトの名無しさん:2005/09/07(水) 21:00:17
インスタンシエートされたオブジェクトの、静的でないメンバ関数ポインタの呼び出しは
出来るのでしょうか?
430デフォルトの名無しさん:2005/09/07(水) 21:13:18
>>429
分かりにくい表現をしてるが、ごく普通のメンバ関数ポインタのことか
呼べなかったら意味ないね
431429:2005/09/07(水) 21:23:48
ごめんなさい。
やりたいことは、クラスのメンバ関数ポインタに、生成されたオブジェクトのメンバ関数を入れたい。

class A;

class B {
public:
void (A::*func)();
};

class A {
public:
void print() {
printf("hoge\n");
}
};

int main() {
A a;
B b;
b.func = a.print;
(b.*func)();
return 0;
}


432デフォルトの名無しさん:2005/09/07(水) 21:27:34
>>431
C#でいうトコの delegate でそ?
それはただのメンバ関数ポインタでは無理。
boost::function 使えば出来ると思う。

まぁ単に A* と A:*func のペアを保持しといて p->(*func) とするのが、
(格好は良くないが)シンプルだと思うけど。
433デフォルトの名無しさん:2005/09/07(水) 21:36:56
>>432
× p->(*func)
○ (p->*func)
434デフォルトの名無しさん:2005/09/07(水) 21:56:50
boost::functionとかを使うとこうなる。
#include <cstdio>
#include <boost/function.hpp>
#include <boost/bind.hpp>
using std::printf;

class A;

class B {
public:
    boost::function<void ()> func;
};

class A {
public:
    void print() {
        printf("hoge\n");
    }
};

int main() {
    A a;
    B b;
    b.func = boost::bind(&A::print, a);
    b.func();
    return 0;
}
435429:2005/09/07(水) 22:13:36
>>432~434
ありがとう。なんとか動きました。
うーん、回りくどいことになっているのは、私の設計に問題があるらしいですね。もう一度見直してみます。
436デフォルトの名無しさん:2005/09/08(木) 11:24:30
>>435
単なる予想として、インタフェースを導入してBはそれを持つのがいいような。

class Func {
public:
 virtual void exec() = 0;
};

class A : public Func {
public:
 virtual void exec() { … }
};
437デフォルトの名無しさん:2005/09/08(木) 11:53:53

unsigned long field[4];
という、128ビット長の整数配列 field をもとに、
std::bitset<128> を構築する場合、どのようにするのが良策でしょうか?
今のところ、以下のように構築してますが、ほかにいい方法はありませんか?

bitset<128> y =
 ( bitset<128>(field[3]) << 96 ) |
 ( bitset<128>(field[2]) << 64 ) |
 ( bitset<128>(field[1]) << 32 ) |
 ( bitset<128>(field[0]) );
438デフォルトの名無しさん:2005/09/08(木) 16:24:37
>>437
考えたけど、あまり良い方法が思い浮かばん

#include <bitset>
#include <string>
#include <limits>

template<typename T>
std::string binary(T t)
{
    std::bitset<std::numeric_limits<unsigned char>::digits*sizeof(T)> b(t);
    return b.template to_string<char, std::char_traits<char>, std::allocator<char> >();
}

int main()
{

    unsigned long field[4] = { 1, 1, 1, 1 };


    std::bitset<128> y( binary(field[3]) +
                    binary(field[2]) +
                    binary(field[1]) +
                    binary(field[0]) );


    std::cout << y << std::endl;

}
439デフォルトの名無しさん:2005/09/08(木) 18:24:57
初心者です。VirtualAllocを使用し、構造体にメモリを割り当てようをしています。割り当ての成功or失敗は戻り値がNULLかどうかで判定できますが、何バイト割り当てられているのか@で知る方法がわかりません。
下記@の(int)sizeof(*pBmp)では、構造体のバイト数40が返ってくるので実際にアロックされたバイト数がしりたいのですが…。
/* 定数・変数定義 */
#define MAP_MAXSIZE (50L*1024L*1024L)
/BITMAPINFOHEADER *pBmp;
map *pMap;
// メモリ獲得処理
if ((pBmp = (BITMAPINFOHEADER*)VirtualAlloc(NULL, MAP_MAXSIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE)) == NULL) {
return (-1);
} else {/* ----- @ここで割り当てられたバイト数を知りたい ----- */
sprintf(logMsg, "メモリリソース獲得後: pointer = BITMAPINFOHEADER %x / size = %d", pBmp, (int)sizeof(*pBmp));
pMap = (map *)pBmp;
}
/* 構造体定義 */
typedef struct tagBITMAPINFOHEADER{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;
typedef struct tag_map {
BITMAPINFOHEADER biInfo;// Bitmap Info Header
BYTE bData[1];// 実際には約10MB分
} map;
440デフォルトの名無しさん:2005/09/08(木) 18:27:13
失礼しました。Aの個所を訂正です。
/* 定数・変数定義 */
#define MAP_MAXSIZE (50L*1024L*1024L)
BITMAPINFOHEADER *pBmp;// ←頭のスラッシュが余分でした。A
map *pMap;
// メモリ獲得処理
if ((pBmp = (BITMAPINFOHEADER*)VirtualAlloc(NULL, MAP_MAXSIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE)) == NULL) {
return (-1);
} else {/* ----- @ここで割り当てられたバイト数を知りたい ----- */
sprintf(logMsg, "メモリリソース獲得後: pointer = BITMAPINFOHEADER %x / size = %d", pBmp, (int)sizeof(*pBmp));
pMap = (map *)pBmp;
}
/* 構造体定義 */
typedef struct tagBITMAPINFOHEADER{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;
typedef struct tag_map {
BITMAPINFOHEADER biInfo;// Bitmap Info Header
BYTE bData[1];// 実際には約10MB分
} map;
441デフォルトの名無しさん:2005/09/08(木) 18:40:06
スレ違い。
442デフォルトの名無しさん:2005/09/08(木) 18:44:02
>>437
こんなんどうよ

template <int N>
std::bitset<32*N> make_bitset(unsigned long const(&ar)[N])
{
    std::bitset<32*N> result;
    for (int i = 0; i < N; i++)
        (result <<= 32) |= ar[i];
    return result;
}

int main()
{
    unsigned long field[4] = { 1, 3, 7, 15 };

    std::bitset<128> y( make_bitset(field) );
}
443デフォルトの名無しさん:2005/09/08(木) 19:17:17
437,438,442の中だと442が速いね
444デフォルトの名無しさん:2005/09/08(木) 19:26:56
>>438
>>442
ありがとうございます。
とりあえず、以下のようにしました。

// VC++7.1 のエラー回避用
template< typename T > struct bsizeof
{
 static size_t const value = sizeof(T) * CHAR_BIT;
};

// inline bitset< sizeof(T) * CHAR_BIT * N > bitset_from_vector( ... )
// と記述するとエラーする。どうして?
template< typename T, size_t N >
inline bitset< bsizeof<T>::value * N > bitset_from_vector( T (&x)[N] )
{
 typedef bitset< bsizeof<T>::value * N > bset_t;

 bset_t b;
 size_t i = N;
 while( i != 0 )
  ( b << bsizeof<T>::value ) |= bset_t( x[--i] );
 return b;
}

いつもオーダーで混乱するので間違ってたら指摘してください。
445デフォルトの名無しさん:2005/09/08(木) 19:55:50
>>444
まあ typo だとは思うが
× ( b << bsizeof<T>::value )
○ ( b <<= bsizeof<T>::value )
446デフォルトの名無しさん:2005/09/08(木) 20:09:06
>>439
VirtualQueryでは駄目だった。
VirtualFreeでもサイズは自分で入れなきゃいけないし
システムではサイズの把握までやってないんじゃないの?
だから自分で算出でいいと思うけど。
ページサイズで切り上げ( ページサイズで切り捨て( 開始アドレス ) + サイズ )
447デフォルトの名無しさん:2005/09/08(木) 22:49:11
質問なのですが、クラス1で、map<string, string> sample を宣言して、 クラス2で、map<string, string>* sampleと
宣言した時、クラス1のsampleのアドレスを、クラス2のsampleに代入して、クラス2で string a = *sample[abc] とするのは
可能でしょうか?  
448デフォルトの名無しさん:2005/09/08(木) 22:51:36
>>447
可能です
449デフォルトの名無しさん:2005/09/08(木) 23:04:50
>>447
(*sample)[abc]だな。
450デフォルトの名無しさん:2005/09/08(木) 23:07:31
>>448
ありがとうございます。
しかし、何度やっても”型変換が間違っています”というメッセージがでてうまくいきません。
mapをポインタとして持つこと自体が間違っているのでしょうか?
それとも、クラス2で、string a = *sample[abc] という書き方が間違っているのでしょうか?

451デフォルトの名無しさん:2005/09/08(木) 23:11:58
452デフォルトの名無しさん:2005/09/08(木) 23:24:48
>>448 >>449 >>451
みなさんありがとうございました。
ご指摘どおり型変換に問題があったのですね。
早速明日再度試してみたいと思います。
本当にありがとうございます。
453デフォルトの名無しさん:2005/09/08(木) 23:31:36
型変換じゃなくて演算子の優先順位の問題だろ。
454デフォルトの名無しさん:2005/09/09(金) 00:19:45
>>440
それってべたcデハ?
455デフォルトの名無しさん:2005/09/09(金) 01:27:29
累乗を一行で演算子で表せれますか?
10^xを計算したいんだけど
456デフォルトの名無しさん:2005/09/09(金) 01:28:19
>>455
累乗演算子はC++にはないよ。
代わりにpow関数を使う
457435:2005/09/09(金) 01:35:48
>>436
うおーサンクス!
458デフォルトの名無しさん:2005/09/10(土) 09:03:58
クラスの継承時における、アクセス演算子についてなんですが
例えばある基底クラス内でprotectedなメンバ変数を宣言して、そのクラスを継承した場合
このprotectedなメンバ変数は、派生クラスのメンバ変数としてpublic指定をしたとほぼ同意になりますか?
それとも、privateで宣言したようなものですか?
手持ちの入門書だと継承先で使用できるとしか書いてなくて迷っています。
459デフォルトの名無しさん:2005/09/10(土) 09:19:57
>>458
試せよ。人に聞くよりそのほうが覚える。
460デフォルトの名無しさん:2005/09/10(土) 09:23:16
>>458
そのとおり継承先のクラスからでしか使えないから。前者の意味はpublicで十分だろ。
class B
{
public:
  B(int n) : hoge(n) {} //OK
  int get() const {return hoge;}
protected:
  int hoge;
};

class D : public B
{
public:
  void set(int n) {hoge = n;} //OK
};

int main()
{
  D obj(5);
  std::cout << obj.hoge << std::endl; //エラー 
  std::cout << obj.get() << std::endl; //OK 
}
461デフォルトの名無しさん:2005/09/10(土) 09:25:24
>>458
元々protectedだったメンバは絶対にpublic扱いにならないし、元々privateだったメンバは絶対にprotected扱いやpublic扱いにならない。
「: protected」をしたら継承されたメンバは絶対にpublic扱いにならないし、「: private」をしたら継承されたメンバは絶対にprotectedやpublicにならない。
462デフォルトの名無しさん:2005/09/10(土) 09:56:44
あっという間に試せることなのに、なんでいちいち質問するんだろうね。
手を動かさないからいつまで経っても成長できないんだよ。
463デフォルトの名無しさん:2005/09/10(土) 10:06:00
お前らが>>458のしもべなだけ
464デフォルトの名無しさん:2005/09/10(土) 10:07:53
試してもコンパイラが間違ってるかも知れないって事だろ?
465デフォルトの名無しさん:2005/09/10(土) 10:24:18
>>461
using
466461:2005/09/10(土) 11:18:05
>>465
あぁ、そうか。461の言い方はマズかったな。
467デフォルトの名無しさん:2005/09/10(土) 15:12:39
char型のポインタをcout文で使うと
文字配列のアドレスじゃなくて文字列を表示するのはなぜなんですか?
468デフォルトの名無しさん:2005/09/10(土) 15:15:09
>>467
そういうオーバーロードが用意されているから、としか答えようがない。

アドレス値を表示させたければキャストすればいい。
char *p = 〜;
std::cout << static_cast<void *>(p) << std::endl;
469デフォルトの名無しさん:2005/09/10(土) 15:15:18
そういう仕様だからです
470デフォルトの名無しさん:2005/09/10(土) 15:20:47
仕様ですかぁー
なるほど
471デフォルトの名無しさん:2005/09/10(土) 15:28:41
そうしないと文字列を文字列として<<で出力できなくなる。
472デフォルトの名無しさん:2005/09/10(土) 16:54:58
>>471
馬鹿を晒さなくていいから。
473名無しさん@そうだ選挙に行こう:2005/09/10(土) 17:18:20
472の馬鹿が逆に晒されてしまいました。
474名無しさん@そうだ選挙に行こう:2005/09/10(土) 18:31:25
>>466
どうマズいのか教えてくださいー
475名無しさん@そうだ選挙に行こう:2005/09/10(土) 18:44:24
>>474
アクセス権限なんてusingで自由自在
476名無しさん@そうだ選挙に行こう:2005/09/10(土) 18:48:38
>>475
いや、usingでは隠すほうに持っていけない。
477名無しさん@そうだ選挙に行こう:2005/09/10(土) 18:59:37
>>475
あ、どうも。usingってnamespaceの省略以外にも使い道があるんですねぇ。
478名無しさん@そうだ選挙に行こう:2005/09/11(日) 07:39:56
そこで無名名前空間ですよ
479デフォルトの名無しさん:2005/09/11(日) 09:08:09
>>478
いや、namespaceの話じゃないから
480デフォルトの名無しさん:2005/09/12(月) 14:53:28
boostをインテルコンパイラで使用するためにインストールしました。
疑問があるのですが、ここで質問してもいいですか?
481デフォルトの名無しさん:2005/09/12(月) 14:57:40
>>480
質問していいか質問するなんて行為は辞めれ
いきなり本題でok
482デフォルトの名無しさん:2005/09/12(月) 14:58:16
483デフォルトの名無しさん:2005/09/12(月) 15:45:53
ファイルにクラスの状態を保存する為、そのクラス用にoperator<< 関数を作りたいと思います。
しかし同時に、デバック表示用に人が読める形で出力するoperator<<関数も欲しいんですが
どう作り分ければ良いですか?

std::ostream& operator<< ( std::ostream& stream, const ClassA& a ) const;
これでは被ってしまいます。
484デフォルトの名無しさん:2005/09/12(月) 15:48:54
>>483
マクロで置き換え
485デフォルトの名無しさん:2005/09/12(月) 15:59:55
インストールに関する質問で恐縮ですが、こちらで質問します。
Visual Studio .NET 2005 + intel C++ compiler ver.9 の環境に下記の様にビルドしました。
bjam -sTOOLS=intel-win32 "--prefix=C:\Program Files\Intel\Compiler\C++\9.0\IA32" "-sINTEL_PATH=C:\Program Files\Intel\Compiler\C++\9.0\IA32" "-sINTEL_BASE_MSVC_TOOLSET=vc-7_1" install
インテルコンパイラ用にビルドしたつもりですが、
vc-C++ bin\boost\libs\wave\build\libboost_wave.lib\intel-win32\release\threading-multi\cpp_re.obj cpp_re.cpp
とvc-C++でコンパイルしていきました。これでよいのでしょうか?
ここでビルドしたライブラリをiclで使用する予定です。
486デフォルトの名無しさん:2005/09/12(月) 16:10:01
>>483
マニピュレータ
487デフォルトの名無しさん:2005/09/12(月) 17:00:13
一時オブジェクトの const 参照による束縛の話なんですが、
ちと理解できたか自信ないので質問です。
こんなクラスと関数があったとして…

 struct A {};
 struct X {
  const A* p;
  X(const A& a) : p(&a) {}
 };
 X xget(const A& a) { return X(a); }
 void xtest(const X& x) {
  // ここで *(x.p) を使うとします
 }

以下のようになるという理解であってますか?

これはok
 xtest(xget(A()));
これもok
 const A& a = A(); xtest(xget(a));
これもok
 const A& a = A(); const X& x = xget(a); xtest(x);
これはダメ!
 const X& x = xget(A()); xtest(x);
488デフォルトの名無しさん:2005/09/13(火) 01:27:54
>>487
挙げている例はあってるけど、「ダメ」の理由を自分で説明できないと、
ちゃんと理解したかどうかは判別できないだろう。
489デフォルトの名無しさん:2005/09/13(火) 02:10:57
>>487
ややこしいかもしれないが、一番下のはダメともいいきれない。
490489:2005/09/13(火) 02:12:32
すまん、よく読んでなかった。忘れてくれ。
491デフォルトの名無しさん:2005/09/13(火) 02:32:15
>>487をみて思ったんだけど

A* p = &A();

これって、pの参照先はこのスコープが閉じるまで保持されるの?
492デフォルトの名無しさん:2005/09/13(火) 04:38:33
const A& a = A();

これはダメじゃね?
すぐにデストラクトされるような気が
493デフォルトの名無しさん:2005/09/13(火) 05:43:23
>>492
それがconst参照の束縛かと
494デフォルトの名無しさん:2005/09/13(火) 12:51:27
>>491 されない。
>>492 されない。
495デフォルトの名無しさん:2005/09/13(火) 13:39:25
constわけわかめ
496デフォルトの名無しさん:2005/09/13(火) 17:05:34
そもそもconst T&をT同然に使える(右辺値で初期化できる)ようにというところからこうなったわけで。
497デフォルトの名無しさん:2005/09/13(火) 17:35:34
RVOって関係ある?

498デフォルトの名無しさん:2005/09/13(火) 18:05:19
結果には関係無いんじゃない?
499デフォルトの名無しさん:2005/09/13(火) 19:21:00
お忙しいところすみませんが教えてください

char s1[80], s2[80];
cout << "Enter two strings : ";
gets( s1 );
gets( s2 );
strcat( s1, s2 );
cout << s1 << "\n";

で、一回目の gets( s1 );
でなぜか入力の状態にならず
勝手に NULL が入ってしまいます。
cin だと問題ないのですが
違いは何なのでしょうか?
500デフォルトの名無しさん:2005/09/13(火) 20:55:27
>>499
・gets()は過去との互換性が必要な場合を除いて使うべきではない。
・NULLは入るはずがない。NULキャラなら勿論入るが。
>>499に書かれたロジック以前に入力は行なっていないか? その場合空読みするべき。
501487:2005/09/13(火) 21:23:20
>>488
一時変数の束縛は、それが参照されとぃるかどうかではなく、
あくまでその一時変数を含む式の最後まで保持されるに過ぎない、
ということを確認したかったのですが、規格書の 12.2-3 に
書いてありました。
規格書には「full-expression を評価した最後まで」みたいな表記
だったので、full-expression ってどこまでじゃーと思ってさらに
検索したら 1.9-12 に「別の expression の subexpression でない
ものが full-expression」とかあって何だか騙されたような気分に。

とりあえず関数呼び出しは expression なんで、一時オブジェクト
を使って関数呼び出しを何度行おうが、それが一つの式である限り
一時オブジェクトは有効、ということですね。一番最後の例は最初
の文の後で A() は破棄されてしまうのでダメ、と。
502デフォルトの名無しさん:2005/09/13(火) 21:27:42
>>499
ios::sync_with_stdio() は呼んでますよね
503デフォルトの名無しさん:2005/09/13(火) 21:33:44
>>500
> ・gets()は過去との互換性が必要な場合を除いて使うべきではない。
調べていたらバッファオーバーフローの原因になるので使わないようにと
いろんなサイトに書いてました・・・・。
fgets() というのを使うようにします。

> ・NULLは入るはずがない。NULキャラなら勿論入るが。
すみません。まだまだよくわかってないんですが、
自分でも何が言いたかったのかよくわかんないんですが
文字が入ってない状態ってことを言いたかったんです。
ヌル文字は入りますね。

> ・>>499に書かれたロジック以前に入力は行なっていないか? その場合空読みするべき。
>>499 のコード以前に cin で入力させていました。
これを消してやってみたら、問題なく動きました。
どういう動きをしてこういうことになるのかとか
細かいことはまだまだよくわからないんですが
これから勉強続けていけばわかってくるかなということで
今回はこれでよしとします。

ありがとうございました。
504デフォルトの名無しさん:2005/09/13(火) 21:47:22
>>502
すみません、呼んでません。
っていうか全然わかりません。

翔泳社の標準講座C++で勉強してるんですが
640ページ近くあるうちのまだ145ページぐらいしか読めてないので
難しいことはまだ全然わかりません。

でもちょっと調べてみます。
ありがとうございました。
505デフォルトの名無しさん:2005/09/13(火) 22:38:12
>>504
ストリームバッファとstdioが別々の実装になっていても、常に中身を同じく
するのがstd::ios::sync_with_stdio(bool b = true)。

但し、デフォルトで最初からtrueなので、今回の件とは関係ないと思う。
506デフォルトの名無しさん:2005/09/13(火) 23:05:45
>>503
一般的に、 std::cout が問題なく使える環境なら
iostream と cstdio は混ぜる必要が無い。(混ぜないほうがいい)
さらに言えば、文字列操作も std::string を使ってしまえばいい。
今回の例で行くと、 s1 に40文字、 s2 に40文字入力された場合、
strcat() で配列サイズ超えた書き込みが起こってしまう。

string s1, s2;
cout << "Enter two strings : ";
cin >> s1;
cin >> s2;
s1 += s2; // or s1.append(s2);
cout << s1 << "\n";

これでバッファオーバーフローも配列オーバーも起こり得ない。

ただし cin >> s1 はDOS攻撃を許してしまう
セキュリティホールだと捉える場合もある。
istream::getline() などを使うといい。
507デフォルトの名無しさん:2005/09/13(火) 23:08:36
>>501
はい。その理解で問題ないですよ。

あとはこんな話とか。
http://jbbs.livedoor.jp/bbs/read.cgi/computer/5651/1075539833/35
508デフォルトの名無しさん:2005/09/14(水) 01:35:28
ポインタについて質問させて下さい。

以下の2つの宣言は、同じ意味を持ちますか?

CPen* Pen1;
CPen *Pen2;

基本的なことの質問ですが、回答お願いいたします。
509デフォルトの名無しさん:2005/09/14(水) 01:39:39
前者はCPen*型の変数Pen1を宣言している
前者はCPen*型の変数Pen2を宣言している

質問の意図を察するに同じ意味でオッケー。
510デフォルトの名無しさん:2005/09/14(水) 01:41:24
>>508
上の宣言はC++コンパイラを使うように指示する
下の宣言はCコンパイラを使うように指示する
511デフォルトの名無しさん:2005/09/14(水) 01:56:52
>>510 おもしろくない
512デフォルトの名無しさん:2005/09/14(水) 01:57:37
えーっ!そうなのか!!知らなかったよ。
んじゃ CPen * Pen3; はどうなるの?教えてちょぶだい。
513デフォルトの名無しさん:2005/09/14(水) 02:04:30
C#コンパイラかな、やっぱり。
514デフォルトの名無しさん:2005/09/14(水) 02:27:39
CPen * * Pen4, *pen5; は?
515デフォルトの名無しさん:2005/09/14(水) 02:44:35
>>514
Cωコンパイラ
516508:2005/09/14(水) 04:13:38
>>509
早速のレスありがとうございます。

>>510
本当のことですか?ネタですか?
マジレス、キボン
517デフォルトの名無しさん:2005/09/14(水) 04:14:57
さすがにこのレベルなら自分で調べられるだろ
518デフォルトの名無しさん:2005/09/14(水) 06:58:56
>>516

>>511以降の展開見れば察しはつくだろ。
察しがつかないなら2chを利用するのは止めとけ。
519デフォルトの名無しさん:2005/09/14(水) 07:19:56
2ch信者というやつですか。あらまあ必死 ;-)
520デフォルトの名無しさん:2005/09/14(水) 08:35:40
なぜにウィンク
521デフォルトの名無しさん:2005/09/14(水) 09:43:54
質問です。

try {
 throw (int);
} catch (int a) {
 printf("%d\n", a);
}

とした場合、
aには何が入るかは決まってますか?
522デフォルトの名無しさん:2005/09/14(水) 09:47:13
>>516
マジレスしとくよ。一応。お前思いっきり釣られてる。
523デフォルトの名無しさん:2005/09/14(水) 09:48:02
>>521
0だろ。
524デフォルトの名無しさん:2005/09/14(水) 09:50:04
>>521
お前、それコンパイル通ったか?
525デフォルトの名無しさん:2005/09/14(水) 09:51:08
>>521
コンパイルできませんよ。
526デフォルトの名無しさん:2005/09/14(水) 09:58:10
あれれ、コンパイルできませんでした。
もしかして、型だけthrowするのってできないんですか?
527デフォルトの名無しさん:2005/09/14(水) 10:01:04
>>526 やってみてから言ってるんだろうな?
528デフォルトの名無しさん:2005/09/14(水) 10:23:09
つか仮にコンパイルできて0とかが返されたところで何に使うんだか。
529デフォルトの名無しさん:2005/09/14(水) 10:27:34
throw int();

とやったら通りました。
型を返す時は暗黙的に一時オブジェクトを返すということですか?
530デフォルトの名無しさん:2005/09/14(水) 10:33:24
>>529
int()はどんな文脈でも0と同じだが。
531デフォルトの名無しさん:2005/09/14(水) 10:34:07
ちなみにaは0でした。

intの暗黙のコンストラクタは0をセットするんでしょうか。
(というかこの理解であってますか?)
532デフォルトの名無しさん:2005/09/14(水) 10:34:25
>>529
言っている意味がよく分からんが、それは throw int(0); や throw 0; と書いているのと同じ。
型を返しているのではなく、int型の値(オブジェクト。内容は0)を投げている。
533デフォルトの名無しさん:2005/09/14(水) 10:37:24
>>532
意味違ってましたか。
型だけをthrowしたいんですが、どうすればよいですか?
(どっかの解説サイトに型またはオブジェクトをthrowできるとあったので)
534デフォルトの名無しさん:2005/09/14(水) 10:42:14
>>533
それは嘘だ。 throw できるのはオブジェクトだけ。
サイト晒せ。
535デフォルトの名無しさん:2005/09/14(水) 10:45:38
>>534
そうでしたか。
すいません。
Javaのサイトだったかもしれません。
たしかgoogleで throw 例外 式 とかで検索して出てきたサイトです。
536デフォルトの名無しさん:2005/09/14(水) 10:51:49
>>535
それも嘘だ。おまえの勘違いだろ。
537デフォルトの名無しさん:2005/09/14(水) 10:53:40
見つけました。
ここです。
ttp://www.mars.dti.ne.jp/~torao/program/cpp/exception.html

>何をなげるか
>例外処理の throw では、int, char*, double, 構造体など、どんなデータ型でも投げられます。

(中略)

>また、例外はクラス定義されたオブジェクトもなげることができます。
538デフォルトの名無しさん:2005/09/14(水) 10:58:01
>>536
読み返したら、自分の勘違いだったみたいです。
型を投げるではなく、〜型のデータを投げるという文脈みたいですね。
でも、まぎらわしいですよね。
539デフォルトの名無しさん:2005/09/14(水) 11:09:42
本買えバカ
540デフォルトの名無しさん:2005/09/14(水) 11:12:47
>>537
そのサイト、筆者の知識が曖昧だな。鵜呑みにしないほうがいい。
541デフォルトの名無しさん:2005/09/14(水) 12:33:32
おいおい型を投げるって・・・・・
C++にはまだリフレクションが装備されてないぞ。これから先もずっとからかも。
542デフォルトの名無しさん:2005/09/14(水) 13:30:45
obj->Func(); は、Func が非仮想関数なら静的結合されて、通常の関数呼び出しと同じ速度で実行できる
……の認識で合ってますか?
543デフォルトの名無しさん:2005/09/14(水) 13:59:49
合ってる。
class A
{
public: void f(int n);
};
のf()呼び出しは
sturct A
{
};
void A_f(int n, A*)
;のA_f()呼び出し
と本質的に変わらん。
544デフォルトの名無しさん:2005/09/14(水) 14:05:46
thisがレジスタ渡しされるぶん前者が速いよ(VC)
545デフォルトの名無しさん:2005/09/14(水) 14:08:35
const std::string & s = "hoge";

としたとき、

(1) "hoge"で初期化された一時オブジェクトが生成される
(2) sに一時オブジェクトの参照が代入される

という認識であっていますか?
またこの場合、sの有効期間はどうなりますか?
546545:2005/09/14(水) 14:12:41
すみません。少し前に出てた話題(>487)でした。
解決しました。
547デフォルトの名無しさん:2005/09/14(水) 14:20:01
>>543 >>544
便乗だけど、非仮想だったら
a->b->c->d->func()
でも同じことが言える?
548デフォルトの名無しさん:2005/09/14(水) 14:34:56
質問です。
newでclassの配列を生成する際、それぞれのclass生成時のコンストラクタ引数は指定できないんでしょうか?

例えば。
String *str;
str = new String [5] ("デフォ文字列");

という感じにできるのが理想です。
(Stringというのは説明のためにデッチあげたクラスです)
もちろんこれはコンパイルとおらないのですが…。
549デフォルトの名無しさん:2005/09/14(水) 14:36:52
C++の設計ミスでできない
550デフォルトの名無しさん:2005/09/14(水) 14:37:04
>>548
無理です。
551デフォルトの名無しさん:2005/09/14(水) 14:40:45
ありがとうございます。

おやまぁ…。
これは結構困り者ですね。
552デフォルトの名無しさん:2005/09/14(水) 15:03:36
>>549
設計ミスじゃないぞゴラ。
553デフォルトの名無しさん:2005/09/14(水) 15:20:09
あーん?
こんな重要な事項、設計ミス以外の何があるってんだ。言って見ろ。
554デフォルトの名無しさん:2005/09/14(水) 15:51:42
互換性
555デフォルトの名無しさん:2005/09/14(水) 16:52:12
コンストラクタ記述にCとの互換性もクソもないと思うが
556デフォルトの名無しさん:2005/09/14(水) 17:08:30
C++0xには配列のコンストラクタ記述を認める予定があるんだろ。
557デフォルトの名無しさん:2005/09/14(水) 17:51:54
実際どうなんかねえ。「C++の設計と進化」を読むと、配列型のnew/delete
演算子は後から追加されたものらしいから(§10.3、P270)、その時、初期化の
書式との整合性を取るのを”うっかり”忘れたのかねえ。

俺には何か理由があってわざと取り入れなかったような気がしてならないんだが。
558デフォルトの名無しさん:2005/09/14(水) 19:30:19
>>548
代わりにその型へのポインタをnew []して、その中に個々の要素をnewで入れたり、
あるいはstd::vectorを使って、個々の要素をpush_back()で入れていったりする。
559デフォルトの名無しさん:2005/09/14(水) 19:38:15
>>558
それやと、boost::shared_ptrか、boost::ptr_vector使わないと、deleteが
面倒やねえ。
560558:2005/09/14(水) 19:43:18
>>559
言い方が悪かった。
std::vectorにはポインタではなく、オブジェクトそのものを入れるつもりで書いた。
561デフォルトの名無しさん:2005/09/14(水) 20:11:01
まあ配列にはstd::vectorやね。C++なら。OOする時はboost::ptr_vector当たりが便利。
562デフォルトの名無しさん:2005/09/14(水) 20:13:24
javaでもできないし良いやん
563デフォルトの名無しさん:2005/09/14(水) 20:27:48
C#が出来るのでくやしい。
564デフォルトの名無しさん:2005/09/14(水) 20:31:51
C# だと出来るんか。知らんかった
565デフォルトの名無しさん:2005/09/14(水) 20:44:48
>>564
558の前者のようなやり方になる。つまり参照をnew []して、個々の要素をnewする。
ただ初期化できるんだけどね。
566デフォルトの名無しさん:2005/09/14(水) 20:53:50
>>548
cygwin g++ なら、-ansi -Wall オプションつけても、それ通るよ。
動作も期待通り。

他の処理系のg++ は試してないからわからんけど。
567デフォルトの名無しさん:2005/09/14(水) 20:54:55
C++でワイドバイトファイルとマルチバイトファイルを両方扱わなきゃ
いけない場合、どのように実装する?
今は、BOMを見てマルチバイトだった場合は1行読み込む毎にwchar_tに変換〜てな感じでやっている。
しかし、なんか効率悪くて思えて仕方が無いんだけど・・・。
568デフォルトの名無しさん:2005/09/14(水) 20:58:04
>>566
それGCCの独自拡張だったような
569デフォルトの名無しさん:2005/09/14(水) 21:00:57
gccとbccは独自拡張多いな‥‥まあbccはObjectPascalとの互換性維持があるからしょうがないが
570デフォルトの名無しさん:2005/09/14(水) 21:43:16
gccのはもろイカ臭いよね
571デフォルトの名無しさん:2005/09/14(水) 21:45:31
gccはC99とかc++0xの規格を少し取り入れているからな。C99に関してはかなり。
572デフォルトの名無しさん:2005/09/14(水) 21:49:42
>>571
逆にgcc独自拡張がC99に取り入れられたものもある。
573508:2005/09/14(水) 22:45:45
>>522thx (・∀・)
574デフォルトの名無しさん:2005/09/14(水) 22:46:19
>>567
読み込むファイルを全部ワイドバイトにしてしまえばいい。
で、別途コンバータを提供する。

って、そういう問題じゃないか・・・。
575デフォルトの名無しさん:2005/09/14(水) 23:35:36
ワイドバイト? 新語?
576デフォルトの名無しさん:2005/09/14(水) 23:48:02
ワイドバイト の検索結果のうち 日本語のページ 約 134 件中 1 - 50 件目 (1.04 秒)
wide-byte の検索結果 約 630 件中 1 - 50 件目 (0.40 秒)
577デフォルトの名無しさん:2005/09/15(木) 00:31:49
>>545
× sに一時オブジェクトの参照が代入される
○ sが一時オブジェクトへの参照として初期化される
578デフォルトの名無しさん:2005/09/15(木) 12:52:49
>>576
超少数派だね
579デフォルトの名無しさん:2005/09/15(木) 16:24:46
stlのmapみたいな感じで、valueからkeyの検索もできるような物ってありませんでしょうか。
580デフォルトの名無しさん:2005/09/15(木) 16:28:14
>>579
std::hash_map 但しSGI STL
581デフォルトの名無しさん:2005/09/15(木) 17:39:07
コンパイルタイムプログラミングで
template <int X>
struct INT { enum { type = X }; };

としたとき、INT<100>::typeは定数値(100)になるのだろうか?
というのはどうやって確かめればいいですか?
582デフォルトの名無しさん:2005/09/15(木) 17:43:49
出力すればいいだろう
583デフォルトの名無しさん:2005/09/15(木) 19:44:41
>>581
定数式かどうか確認したいなら typede char array[定数式]; とか。
任意の bool 式のコンパイルチェックは
template <bool> struct static_assert;
template <> struct static_assert<true> { enum { value }; };
static_assert<(100 == 100)>::value; とか。
584デフォルトの名無しさん:2005/09/15(木) 19:46:27
すまん、typedef char array[定数値];
585デフォルトの名無しさん:2005/09/15(木) 19:56:26
>>582-584 thx
「#defineマクロとstatic const intではなり、const intやstatic const doubleではならない」
ものって即値と呼ぶのだっけ。定数だとconstでしたごめんなさい。
コンパイル時に固定の数値として評価される値、例えばnumeric_limits<int>::min()など。
このように、コンパイル時に評価されていることを確認するのは、どうすればいいのだろう?
586デフォルトの名無しさん:2005/09/15(木) 19:59:21
>>585
パフォーマンスにそれほど深刻な影響がなければ、別にコンパイル時評価にこだわる理由はない
というのはよくわかっております。
コンパイルタイムプログラミングしているつもりで、実は実行時に展開されてたら寂しいというだけの理由です。
587デフォルトの名無しさん:2005/09/15(木) 22:35:25
そんなに不安なら逆アセンブルなりなんなりすればいいじゃん。
VCならデバッグモードで確認できるし、gccなら-Sオプションつけてコンパイルしてもいいけど。
588デフォルトの名無しさん:2005/09/15(木) 22:47:34
>VCならデバッグモード
………
589デフォルトの名無しさん:2005/09/15(木) 23:08:41
>>588
何が不満なんだ?
590デフォルトの名無しさん:2005/09/15(木) 23:12:50
正しくはデュバックムォード
591デフォルトの名無しさん:2005/09/15(木) 23:13:23
vctoolkitを使ってるけどIDEは無いとか?
592デフォルトの名無しさん:2005/09/15(木) 23:32:58
cl -FA
593デフォルトの名無しさん:2005/09/16(金) 00:38:19
C++のstreamライブラリを覚えようと
勉強してるんだけど、全然要領得ないんです。
原因は複雑な設計だったり、極端に略されたメンバ名だったりするんで
なんだかやる気が起きません。
やっぱりC++使ってたらこれらが使えないと一人前とは言えないですかね?
594デフォルトの名無しさん:2005/09/16(金) 00:51:14
まぁ人の好き好きだが、別なのを勉強した方がいい希ガス。
少なくとも自分はstream系が役に立ったことは無い。
595デフォルトの名無しさん:2005/09/16(金) 00:56:16
他スレでVC6の bitmap<n> ってバグってるってマルチがあるけど
試したら、ホントにバグってたな
やっぱりあの次期のコンパイラのSTLって過信しないほうがいいのか
596デフォルトの名無しさん:2005/09/16(金) 01:01:06
iostreamは俺もcin, cout, cerrに出す時以外使ったこと無い
使いにくいから
I/Oクラスが必要なときは自分で作ってる
597デフォルトの名無しさん:2005/09/16(金) 01:02:43
ちょっと読めないので失礼 >>1-10
598デフォルトの名無しさん:2005/09/16(金) 01:03:44
>>596
>I/Oクラスが必要なときは自分で作ってる

馬鹿ハケーン。ま、個人レベルで何をやろうが個人の買ってだが、俺の会社に
こういう香具師が面接にきたら、一番最初に落とす。
599デフォルトの名無しさん:2005/09/16(金) 01:04:25
×買って
○勝手
600デフォルトの名無しさん:2005/09/16(金) 01:12:45
まぁ自分の書いた文章も確認できない香具師を落とす方が先だなw
601デフォルトの名無しさん:2005/09/16(金) 01:13:37
>>598
cin cout cerr に出力するサンプルの動作だけを妄信する奴って多いからな
(サンプルがそういうの多いからか)
ここ1年、fstream sstream の実用的な使い方を知って、結構目から鱗状態だったよオレ
602デフォルトの名無しさん:2005/09/16(金) 01:34:52
職業プログラマは社内のコード共有が優先で標準ライブラリの
ダメな部分も使わなくちゃいけなくて大変だねえ
603デフォルトの名無しさん:2005/09/16(金) 01:48:40
>>602
うちのプロジェクトなんてコンテナにSTL使わないで
MFCのコンテナ満載だよ
どうやって、こいつらにSTLを啓蒙させようかと悩み中
604デフォルトの名無しさん:2005/09/16(金) 01:50:11
イテレーターとか、アルゴリズムとの絡みを上手く啓蒙できればアレ
605デフォルトの名無しさん:2005/09/16(金) 01:57:49
std::stringとCStringの変換がダサい。
606凶笑面:2005/09/16(金) 02:16:17
今日の夜9時からフジTVで民俗学ミステリ凶笑面だ。
みんな、見ようぜ。 原作は新潮文庫から出てるよ。
俺はドラゴン桜を見るからビデオに撮るけどな。
607デフォルトの名無しさん:2005/09/16(金) 04:16:04
>>605
このライブラリ乱立状態をなんとかしろ
608デフォルトの名無しさん:2005/09/16(金) 04:19:34
Microsoftに言ってくれ
609デフォルトの名無しさん:2005/09/16(金) 07:25:43
API公開したのはMSだが
それに皮かぶせてMFCを売りつけた他社が
余計で中途半端なコンテナクラス(CStringを含む)
をオマケで付けた弊害が蔓延してるって構図かな
610デフォルトの名無しさん:2005/09/16(金) 08:39:39
>>605
std::string、std::wstring、AnsiString、WideString、CString、char*、wchar_t*が入り交じってて収拾つきません⊂(。Д。⊂⌒`つ
611デフォルトの名無しさん:2005/09/16(金) 09:45:55 BE:89861292-##
>>601
実用的な使いかたって?
612デフォルトの名無しさん:2005/09/16(金) 12:08:34
template<class Ctype>
class A
{
protected:
Ctype foo;
};

template<class Ctype>
class B : public A<Ctype>
{
void bar()
{
foo = 0;
}
};

こんな感じな事をやろうとすると、
error: ‘foo’ was not declared in this scope
と怒られてしまいます。
Aの継承をintなどで限定するとこのエラーは出ませんでした。
Ctypeのまま継承するにはどうしたらいいでしょうか。
613デフォルトの名無しさん:2005/09/16(金) 12:31:06
>>612 this->foo
614デフォルトの名無しさん:2005/09/16(金) 12:32:21
>>612

template<class Ctype>
class A
{
protected:
Ctype foo;
};

template<class Ctype>
class B : public A<Ctype>
{
void bar() {
Ctype::foo = 0;
}
};
615デフォルトの名無しさん:2005/09/16(金) 12:38:12
いけましたー。ありがとうございます。
しかし、なんかしっくりこないなー。C++の謎は深い。。
616デフォルトの名無しさん:2005/09/16(金) 13:15:27
>>615
キーワードは
"dependant name"
"unqualified lookup"
"point of definition"
"point of instantiation"
617もこな:2005/09/16(金) 14:19:14
はじめまして、私はeVc4.0++を使っている者です。
それで まずIEのように とりあえずプログラムを起動したら
MSNやYahooのようなサイトのトップが表示され普通に使える物を作りたいです。
それで作ろうとしたのですが、eVcにはCHtmlViewがサポートされていないようなのでどうしたらよいのか迷ってます。

メニュー → 表示 −> ClassWizard → 関数追加 → OnInitialUpdate関数の追加 → Navigate2(_T("適当にURL"),NULL,NULL);  
上記をしたら error C2065: 'Navigate2' : undeclared identifier
とエラーが出てしまいました。
何故でしょうか。。。??
といいますか、IEを作るにはどうしたら良いでsしょうか。
お願いします
618デフォルトの名無しさん:2005/09/16(金) 14:26:36
まずは英語の勉強からかな。
619デフォルトの名無しさん:2005/09/16(金) 15:03:08
>>610
グローバルロケールの影響受けない文字列型ない?
620デフォルトの名無しさん:2005/09/16(金) 15:38:41
>>617
Windows関連スレか初心者スレ、或いはeVcとやらのスレへどうぞ。
621デフォルトの名無しさん:2005/09/16(金) 22:41:21
>>593ほか
i/o/iostreamクラスに限って言えばは単にCのFILE *のラッパのような感じだよ。(<<と>>以外は)
622デフォルトの名無しさん:2005/09/17(土) 18:06:48
std::stringに対し"頭のスペースを削る"とか
"doubleに変換"みたいな事が出来る関数ってありませんでしょうか?
自分で書くしか無いんでしょうか。。
623デフォルトの名無しさん:2005/09/17(土) 18:08:26
>>622
doubleに変換→boost::lexical_cast
頭のスペース削る→boost::regex
624デフォルトの名無しさん:2005/09/17(土) 18:09:59
>>622
少なくとも後者はstringstream使うと楽にできる。
前者はそのままでも可能。
625デフォルトの名無しさん:2005/09/17(土) 18:11:06
>>622
頭のスペースはfind_if+erase
626デフォルトの名無しさん:2005/09/17(土) 18:12:34
後者だけ。

#include<sstream>
double toDouble(const std::string&s){
    double ret;
    return std::stringstream(s)>>ret,ret;
}

boost::lexical_castを使う方がより良いけど
627デフォルトの名無しさん:2005/09/17(土) 21:28:39
//doubleに変換
double conv2double(const std::string foo) {return std::atof(foo.c_str());}
// 頭のスペースを削る
std::string cutSpaces(const std::string foo) {return /* すまん、後を頼む */}
628デフォルトの名無しさん:2005/09/17(土) 21:34:36
じゃあこんな感じで
std::string cutSpace(const std::string & foo){
    return std::string(find_if(foo.begin(),foo.end(),std::bind2nd(std::not_equal_to<char>(),' ')),foo.end());
}
629デフォルトの名無しさん:2005/09/17(土) 21:36:58
おっとstdの付け忘れがあった。
×find_if
○std::find_if

630デフォルトの名無しさん:2005/09/17(土) 21:39:48
A trim implementation for std::string
ttp://www.codeproject.com/vcpp/stl/stdstringtrim.asp
631デフォルトの名無しさん:2005/09/17(土) 22:33:30
すみません、「禿本」とは何を指しているのでしょうか?

VisualC++のスレッドで間違えて聞いてしまいましたが
皆様にC++スレで聞けと仰られたので、、、
632デフォルトの名無しさん:2005/09/17(土) 22:35:41
633デフォルトの名無しさん:2005/09/17(土) 22:41:35
>>632
ありがとう、早速注文したよ、AMAZONで
634デフォルトの名無しさん:2005/09/18(日) 00:01:27
boost::trim_left
635デフォルトの名無しさん:2005/09/18(日) 00:09:26
gcc で日本語の正規表現が使いたいのですが、適当なライブラリはあるのでしょうか?
boost::regex を試してみましたが、うまく動いてくれませんでした。
636デフォルトの名無しさん:2005/09/18(日) 00:10:21
637デフォルトの名無しさん:2005/09/18(日) 01:03:56
>>630
たかがこれだけの事で写真まで載せるあたりがアメリカンだね
638デフォルトの名無しさん:2005/09/18(日) 01:04:04
>>635
鬼車、これ最強。
639デフォルトの名無しさん:2005/09/18(日) 01:22:23
>>637
CodeProjectのAuthorはアメリカ人じゃない人の方が多いけどな
640デフォルトの名無しさん:2005/09/18(日) 01:29:59
日本にはCodeProjectみたいなのはないの?
641デフォルトの名無しさん:2005/09/18(日) 02:39:37
1 AAA
3 xxxx
10 aaaaa
3 qqqqq
3 aaaaaaa

こんな感じのデータを保存していきたいんですが、
データを取り出すときに、同じ数字のデータごと集めて出したいんです。
(1のデータはaaa,bbb,ccc。3はddd...といった感じで)

vectorやmapで保持すると、取り出すときに数字を一々確認するような形になってしまうのですが、
より良いデータの保持、取り出し方法はありませんでしょうか。
642デフォルトの名無しさん:2005/09/18(日) 03:08:28
std::multi_map
643デフォルトの名無しさん:2005/09/18(日) 06:14:37
std::ifstream f;の中身を
全部文字列にしたいときってみんなどうしてる?

std::stringstream s;
s << fi.rdbuf();
std::string result(s.str());
644デフォルトの名無しさん:2005/09/18(日) 06:30:49
>>643
std::istreambuf_iterator<char> begin(fi),end;
std::string result(begin, end);
645643:2005/09/18(日) 07:13:34
>>644
なるほどそうやるのか〜
でも、VC6タソだとだめぽ...
646デフォルトの名無しさん:2005/09/18(日) 11:37:53
>>640
欲しいねぇ。flipcodeも閉鎖(Readonly化)しちゃったし・・・
647デフォルトの名無しさん:2005/09/18(日) 14:31:15
猫でもわかるのページの C++のページの26章のファイルの入出力のところで
実行するとファイル名は入力してファイルができるのですが文字が書きこめません。
解かる方教えていただけないでしょうか?
648デフォルトの名無しさん:2005/09/18(日) 14:32:47
初心者スレへでもどうぞ。つーか、URIくらい提示しろって。
649デフォルトの名無しさん:2005/09/18(日) 14:39:53
文字列定数を宣言したいときってどっちが速度とかメモリの効率がいいですか?

const char* const str = "test";
const char[] str = "test";
650デフォルトの名無しさん:2005/09/18(日) 14:43:41
>>648
すいませんでした。
651649:2005/09/18(日) 14:55:42
あと、関数内で
文字列定数定義する場合
const char* const str = "test";
const char[] str = "test";

より
static const char* const str = "test";
static const char[] str = "test";

の方が効率いいというのは本当ですか?
652デフォルトの名無しさん:2005/09/18(日) 15:21:33
const char[] str = "test";
こんな書き方C++で出来たっけ?
653649:2005/09/18(日) 15:24:15
>>652
とりあえず手元のVC++7.1ではコンパイル通るのですが、
これってVC++独自拡張でしょうか?
654デフォルトの名無しさん:2005/09/18(日) 15:27:22
const char str[] = "test";
これじゃなんでだめなの?
655649:2005/09/18(日) 15:32:56
bcc5.6.4とg++3.4.3で試したら通りませんでした。
独自拡張だったようです。const char* constの方を使う事にします。
staticの方は関数内では付けた方がいいんでしょうか?
656デフォルトの名無しさん:2005/09/18(日) 15:33:47
>>654
俺んとこで試したら main 関数がないってエラーがでたよ。
657649:2005/09/18(日) 15:36:08
すいませんやっぱりg++でもbccでも通りました。

const char str[] = "test";
ですよ?

const char[] str = "test";
ではなく。
658デフォルトの名無しさん:2005/09/18(日) 15:36:31
コンパイル通らないけど?これ。
 const char[] str = "test";

>>649
いくらか効率に違いが出るかも知れんが、そんな些細な効率化を意識するよりstaticやchar*、char[]の使い分け方を理解しろって。
状況によって使い分けるものを一緒くたに語ってもしょうがないだろ。
659649:2005/09/18(日) 15:38:29
#include <iostream>

const char str[] = "test";
int main()
{
using namespace std;
cout << str << endl;
return 0;
};


これそのままコピペしたら通ると思います。
結局どっちがいいんでしょうか?
660デフォルトの名無しさん:2005/09/18(日) 15:39:12
アセンブラのソース見れば一発じゃん
661デフォルトの名無しさん:2005/09/18(日) 15:39:21
すいまらん最初の方に
const char[] strとか自分で書いてました。
const char str[]が正解です。
662649:2005/09/18(日) 15:42:08
>>660
それが一番手っ取り早そうですね。
ありがとうございました。
663デフォルトの名無しさん:2005/09/18(日) 15:42:23
const char* const str = "test";
const char str[] = "test";

最適化すれば、この二つって意味的に同じ物になる?
664デフォルトの名無しさん:2005/09/18(日) 15:43:51
全く違います
665デフォルトの名無しさん:2005/09/18(日) 15:45:13
>>664
どういうときに?ポインタのアドレスを取るようなコードがないとしたらどう?
666649:2005/09/18(日) 15:50:50
>>663
違いました。
コンパイラが吐いたアセンブラのリスト見れば分かります。
コンパイラの最適化ってまだそんなもんなんですね。
667649:2005/09/18(日) 15:51:50
ちなみにアセンブラリストは
cl -G7 -O2 -GF -FAs test.cpp
で吐かせました
668デフォルトの名無しさん:2005/09/18(日) 15:57:36
>>649
で、メモリ効率の良し悪しは?
669デフォルトの名無しさん:2005/09/18(日) 15:59:17
ポインタ1個分
670デフォルトの名無しさん:2005/09/18(日) 16:00:51
考えるまでもなく前者
後者は存在意義自体疑問
671デフォルトの名無しさん:2005/09/18(日) 16:02:58
>>670
なんで?
672デフォルトの名無しさん:2005/09/18(日) 16:04:37
>>664
解説キボンヌ
673デフォルトの名無しさん:2005/09/18(日) 16:07:43
674デフォルトの名無しさん:2005/09/18(日) 16:09:08
#define str "test"

が最強
最適化されるコンパイラ多数
Cでも使える
675デフォルトの名無しさん:2005/09/18(日) 16:43:57
int _tmain(int argc, _TCHAR* argv[])
{
    const char* const           str0    = "test"; 
    const char                  str1[]  = "test";
    static const char* const    str2    = "test"; 
    static const char           str3[]  = "test";
    #define str4 "test"

    std::cout << str0;
    std::cout << str1;
    std::cout << str2;
    std::cout << str3;
    std::cout << str4;

    return 0;
}

これだと、
str4 = str3 > str2 > str0 > str1
676デフォルトの名無しさん:2005/09/18(日) 17:11:17
void sub();

int _tmain(int argc, _TCHAR* argv[])
{
    const char* const           str0    = "test"; 
    const char                  str1[]  = "test";
    static const char* const    str2    = "test"; 
    static const char           str3[]  = "test";
    #define str4 "test"

    std::cout << str0;
    std::cout << str1;
    std::cout << str2;
    std::cout << str3;
    std::cout << str4;

    return 0;
}

void sub()
{
 puts(str4);
}

#defineキモッ
677デフォルトの名無しさん:2005/09/18(日) 17:51:16
>>651
本当だよ。

関数ローカルでの
 const char str[] = "test";
は、
・ローカルなメモリ領域(一般的には関数のスタックフレーム内)
・初期化するためのデータ(この場合では"test")
・初期化するためのコード(この場合ではmemcpyとか)
を必要とする。

それに対して
 static const char str[] = "test";
なら "test" の実体を静的に用意すればいい。
678デフォルトの名無しさん:2005/09/18(日) 18:02:00
"test"とstrがどのセクションに割り当てられてどういう風に初期化されるっかてことだろ。
679デフォルトの名無しさん:2005/09/18(日) 21:42:22
struct hoge {
size_t size;
void *data;
};

のdataが指し示すsizeバイトのヒープメモリを解放するには、
どうすりゃいいんですか?
適当に、delete[size] (char*)data;とやってみたら、コンパイルは通ったけど、
違う?
680デフォルトの名無しさん:2005/09/18(日) 21:44:40
void*ってことは何がくるか分からないってことなのか?
素直に考えればインターフェースに分離するかテンプレートだと思うが。
681デフォルトの名無しさん:2005/09/18(日) 21:45:26
>>679
new char [...]で確保したことが確実なのならまあそれでいいんだが
それ以外の確保の可能性があるのなら(mallocやnew 他の型)駄目
682デフォルトの名無しさん:2005/09/18(日) 21:47:01
確保方法によって方法変わるからどうやってメモリ確保したか教えて。
683デフォルトの名無しさん:2005/09/18(日) 21:48:34
dataは様々な構造体で確保したデータを指します。
684679:2005/09/18(日) 21:53:30
struct Apple;
hoge h;
h->data = new Apple;
h->size = sizeof(Apple);
みたいな感じです。
685デフォルトの名無しさん:2005/09/18(日) 21:55:53
ついでにtypeidも取得しといたらどうだw
686デフォルトの名無しさん:2005/09/18(日) 21:58:35
struct Object{
 virtual ~Object(){}
};
struct hoge{
  size_t size;
  Object*data;
};
とかにして使う型をObjectから派生させちゃ駄目ですか?
687デフォルトの名無しさん:2005/09/18(日) 21:59:04
素直にテンプレートでも使おうよ。
688デフォルトの名無しさん:2005/09/18(日) 22:06:30
void (*ReleaseData)(); みたいなメンバを用意して、data を設定すると同時に解放用の関数を設定してもらうとか
689デフォルトの名無しさん:2005/09/18(日) 22:07:44
どうでもいいけど、様々な構造体で確保した data を、種類も知らずにどうやって使うのだろうか
それとも単なるコレクション?
690デフォルトの名無しさん:2005/09/18(日) 22:11:07
暇だったから
今は反省している
691デフォルトの名無しさん:2005/09/18(日) 22:43:44
VisualC++なんだけど
new・mallocとdelete・delete[]・freeの
どの組み合わせでもリークしないんだが
そういうもん?
692デフォルトの名無しさん:2005/09/18(日) 22:48:05
んな訳ねーだろwwwwwwwwwwwwwww
693デフォルトの名無しさん:2005/09/18(日) 22:50:52
まぁコンストラクタもデストラクタもないPODなデータ形式でかつ、
たまたまnewとmallocのメモリの確保方法が同じであればリークはしないな。

そんなコード書くやつは死んでくれた方がありがたいがな
694679:2005/09/18(日) 23:27:35
どうも。
結局、派生させました。
695デフォルトの名無しさん:2005/09/18(日) 23:48:47
>>691
これリークしない?
#include <stdlib.h>
struct hoge {
    int* p_;
    hoge() : p_(new int[16777216]) {}
    ~hoge() {delete[] p_;}
};
int main() {
    hoge* p = new hoge();
    free(p);
}
696デフォルトの名無しさん:2005/09/19(月) 00:01:56
リークもくそも無茶苦茶でんがな
697デフォルトの名無しさん:2005/09/19(月) 00:15:43
ワロスw
698デフォルトの名無しさん:2005/09/19(月) 00:31:46
>>691
ほい
std::vector<std::string> * p = (std::vector<std::string> *) malloc( sizeof (std::vector<std::string>) );

699デフォルトの名無しさん:2005/09/19(月) 00:36:14
>>691
たしかにVCのoperator new/new[]/delete/delete[]()はmalloc/freeを呼ぶ実装になっている。
だからと言って混同して良いものではないし、コンストラクタ・デストラクタが絡むとやばい。
700デフォルトの名無しさん:2005/09/19(月) 00:45:52
派生クラスやコンテナをfreeで開放するのはまずいっしょ。
deleteなら基底クラス/各オブジェクトのデストラクタを呼んでくれる。
701デフォルトの名無しさん:2005/09/19(月) 01:11:04
じゃあこれならOK?
class A;
A* a = new A;
a->~A();
free(a);
702デフォルトの名無しさん:2005/09/19(月) 01:34:21
>>701
だからfree()はやめろとあれほど
703デフォルトの名無しさん:2005/09/19(月) 01:42:10
ん?ちょっと話が戻るけど>>679の開放はnewした時にどんな構造体かに関わらず
delete [] data;
とやるだけでnewしたときの分がちょうど開放されるわけではないの?
malloc/freeの組み合わせも同様で。

どのコンパイラだか忘れたけど、動的確保したバイト数を、newで返るアドレスの手前に保存するのがあったはず。
まあコンパイラの実装方法は多々あるのかもしれないが、newした分のバイト数は内部でしっかりとっておかないと、普通に素直なnew/deleteしたときも困らないか?

標準を知る者求む。
704デフォルトの名無しさん:2005/09/19(月) 01:44:31
>>703
hoge h;
h.data=new hoge;
705703:2005/09/19(月) 02:19:11
>>704
あぁ、そういうことか。でも
h.data = new hoge; なら delete h.data;
h.data = new hoge[size]; なら delete [] h.data;
のどちらかしか使わないことように徹底した場合はどう?
まあそんな保守性低いもの書くくらいなら>>679みたいなの書かない方がいいわけだけど。
とりあえず、動的確保した大きさが内部で保存されてるってのは標準で保証されてるのかどうかが疑問点。
706デフォルトの名無しさん:2005/09/19(月) 03:00:01
>>705 保証されてないよ。
707デフォルトの名無しさん:2005/09/19(月) 03:37:07
>>704の意味がわからないんだけど
これのこと?
これならVCでは駄目だったなぁ。

struct A
{
    char* a;
    A(){ a = new char[100];}
    ~A(){ delete [] a;}
};

struct B
{
    void* a;
};

{
    B b;
    b.a = (void*)new A;
    delete b.a;
}
708デフォルトの名無しさん:2005/09/19(月) 03:51:24
そんな糞なVCは窓から投げ捨てろ!
709デフォルトの名無しさん:2005/09/19(月) 04:03:43
>>708 別にVCだからダメなわけじゃない。コードがダメ。
710デフォルトの名無しさん:2005/09/19(月) 09:47:42
そもそもわざわざそんなコード書いて何が楽しいのかさっぱりわからん
711デフォルトの名無しさん:2005/09/19(月) 12:21:16
ロマン
712デフォルトの名無しさん:2005/09/19(月) 16:35:07
class B;
class A {
    public: B method() { return B(); }
};
class B: public A {}
みたいな循環した宣言って無理?
713デフォルトの名無しさん:2005/09/19(月) 16:41:18
>>712
無理だろうな。
基底クラスが派生クラスを知っているという状況は、一般的におかしい。
714デフォルトの名無しさん:2005/09/19(月) 16:43:24
不完全型
715デフォルトの名無しさん:2005/09/19(月) 16:45:19
というかBがAを継承しているなら、必要なメンバ関数をvirtualにしてA*を返せばいい話じゃ
716712:2005/09/19(月) 17:04:42
うーん、やっぱり無理か…。
Object a, b, c;
a[0] = b;
c = a[0]
こんな感じの振る舞いをするクラスが必要になったので、最初は以下のようなコード
class Assigner {
nbsp;nbsp;nbsp;nbsp;...
nbsp;nbsp;nbsp;nbsp;operator=(Object obj) { /* setter */ }
nbsp;nbsp;nbsp;nbsp;operator Object() { /* getter */ }
};
class Object {
nbsp;nbsp;nbsp;nbsp;...
nbsp;nbsp;nbsp;nbsp;Assigner operator[](int i) { return Assigner(this, i); }
};
を書いたんだけど、これだと
a[0].method();
などが動かないので、AssignerをObjectの派生クラスにしてしまおうと
考えたんだけど…。

識者の方、何か良い方法があったら教えてください。
717712:2005/09/19(月) 17:07:12
うげ。置換ミスった。
class Assigner {
    ...
    operator=(Object obj) { /* setter */ }
    operator Object() { /* getter */ }
};
class Object {
    ...
    Assigner operator[](int i) { return Assigner(this, i); }
};
718デフォルトの名無しさん:2005/09/19(月) 17:13:21
>>716-717
Assigner の意味がわからない。
719デフォルトの名無しさん:2005/09/19(月) 17:23:31
確かにそのコードからだけじゃAssignerの存在価値がわからん
720デフォルトの名無しさん:2005/09/19(月) 17:30:44
>>712
>>176-717を見ていなかったときの俺ならこう答えた。
template <typename T>
class A {
public:
    T func() {return T();}
};
class B : public A<B> {};
721デフォルトの名無しさん:2005/09/19(月) 17:38:46
普通にvectorとかに入れときゃいいやん
AとBの継承関係が無理やりすぎ
722デフォルトの名無しさん:2005/09/19(月) 17:45:10
このスレはレスの多さでどれくらいレベルが低い質問なのかよくわかりますね。
723デフォルトの名無しさん:2005/09/19(月) 18:21:22
>>718, >>719
略しすぎて訳わかんないな。ごめんなさい。
急にコードが具体的になって申し訳ないんだけど、
PythonのC拡張を書く関係で、Pythonのオブジェクトを表すPyObjectのwrapperを書いてる。
で、Pythonオブジェクトの属性の取得/代入を[]演算子で行いたい。
value = obj["attr_name"];
obj["attr_name"] = value;
こんな感じで。なお、属性はPyObject_{Get|Set}AttrString()で可能。

class PyObjectWrapper
{
 public:
  PyObject* mObj;

  PyObjectWrapper() {}
  PyObjectWrapper(PyObject* obj): mObj(obj) {}

  class Assigner
  {
   public:
    PyObject* mObj;
    string mKey;

    Assigner(PyObject* obj, const string& key): mObj(obj), mKey(key) {}

    operator PyObjectWrapper()
    {
     PyObject* pobj = PyObject_GetAttrString(mObj, (char*)mKey.c_str());
     return PyObjectWrapper(pobj);
    }
724デフォルトの名無しさん:2005/09/19(月) 18:22:46

    void operator=(const PyObjectWrapper& pobj)
    {
     PyObject_SetAttrString(mObj, (char*)mKey.c_str(), pobj.mObj);
    }
  };

  PyObjectWrapper operator[](const string& key) const
  {
   return Assigner(mObj, key);
  }
};

このコードで値の取得/代入はできるが、
obj["name"].PythonObjectのメンバ();
はできないので、AssignerをPythonObjectの派生クラスに…と考えたのです。
725デフォルトの名無しさん:2005/09/19(月) 18:34:12
こう?
class PyObjectWrapper {
PyObject& operator[](const string& key);
};
726デフォルトの名無しさん:2005/09/19(月) 18:39:14
>>723-724
質問をぶった切ることになるけど、 boost::python でも見るといいんじゃないかな?
勉強じゃないなら、そのまま使うとか。
727デフォルトの名無しさん:2005/09/19(月) 18:41:56
>>723, 724
アドホックな解決策として、Assignerで
PyObject *operator->() const {
  return mObj;
}
としておけば、
obj["name"]->メンバ();
は使えるようになるんじゃまいか。
boost::python使うのが一番手っ取り早いだろうけど。
728デフォルトの名無しさん:2005/09/19(月) 20:33:00
COMのスレってどこいっちゃったの?
729デフォルトの名無しさん:2005/09/19(月) 20:47:02
730デフォルトの名無しさん:2005/09/19(月) 21:14:15
int *i;
i = new int[x];
動的に確保した配列の数(x)をどうやって算出するのか
おしえてください。
731デフォルトの名無しさん:2005/09/19(月) 21:16:43
基本的にはできない。
別変数に個数を保存しておくか、vectorのように配列のサイズを知ることができるコンテナを使う。
732デフォルトの名無しさん:2005/09/19(月) 23:48:23
ttp://ccfa.info/cgi-bin/up/src/up16469.gz
gcc4.0で上のファイルがコンパイルできなくて困っています。
gcc3.2や3.3(とそのlibstdc++)ではコンパイル出来るみたいなんですが、
どこが悪いのでしょうか。
733デフォルトの名無しさん:2005/09/19(月) 23:56:45
>>732
エラーが出るならエラーメッセージぐらい貼れ。
あと、内容によっては↓こっちかもしれない。
http://pc8.2ch.net/test/read.cgi/tech/1121146723/
734デフォルトの名無しさん:2005/09/20(火) 01:01:39
>>733
すいません。
g++ .... -c mqodrawer.cc -o mqodrawer.o
material.hh:22: error: ‘Vector4’ has not been declared
material.hh:22: error: expected ‘,’ or ‘...’ before ‘<’ token
material.hh:23: error: ‘Vector4’ has not been declared
material.hh:23: error: expected ‘,’ or ‘...’ before ‘<’ token
material.hh:24: error: ‘Vector4’ has not been declared
material.hh:24: error: expected ‘,’ or ‘...’ before ‘<’ token
...
こんな感じのエラーです。
735デフォルトの名無しさん:2005/09/20(火) 01:29:43
>>734
そのまんまじゃねーか。
↓これだろ。
//#include "vector.hh"
#include "texture.hh"

namespace bkl {
#include "vector.hh"

Vector4 が ::bkl::bkl::Vector4 になってる。
::bkl 内で Vector4 では見つからない。

こんなことになるから、 namespace の中で #include するな。
736デフォルトの名無しさん:2005/09/20(火) 01:40:59
>>735
すいません。それはnamespaceの外でincludeしても同様のエラーが出ます。
元々外のコメントアウトされたものだけだったんですが、見つからんと言われたので
色々書き換えてたのが残ってしまっていました。

#include "vector.hh"
#include "texture.hh"

namespace bkl {
//#include "vector.hh"
このようにしても、エラーコードはかわりませんです。。
737デフォルトの名無しさん:2005/09/20(火) 02:21:57
>>736
手元の 3.4@cygwin では、その修正で問題なくなる。
エラーメッセージが変わらないわけ無いとおもうんだが。

もう一度試しても、本当に >734 のエラーになるか?
エラーメッセージはそのままコピペしてるか?
738デフォルトの名無しさん:2005/09/20(火) 02:33:25
>>737
はい、全く同じエラーになります。自分の環境(FedoraCore4)のgcc3.2でも通ります。
が、gcc4では通りません。。
739デフォルトの名無しさん:2005/09/20(火) 03:28:29
まさか…gcc4環境からそのヘッダにパスが通ってないとか言わないよな…
だとしたら死んでも償いきれないぞっ!!
740デフォルトの名無しさん:2005/09/20(火) 08:27:07
usingディレクティブである名前空間を丸ごと可視化しようとして、シンボル名が衝突してしまいます。
名前空間を直接指定してスコープ解決すればいいのはわかっていますが、
小手先の方法として、あるひとつのシンボルを優先して解決するような方法はいまりすでしょうか。

本当はそうならないように設計すべきだということはわかっているのですが……
お願いします。
741デフォルトの名無しさん:2005/09/20(火) 08:41:17
>解決するような方法はいまりすでしょうか。

いまりません。
742デフォルトの名無しさん:2005/09/20(火) 09:45:02
いまハムスターです
743デフォルトの名無しさん:2005/09/20(火) 12:05:00
>>738
同じディレクトリにあるヘッダですし、
他のファイルからもincludeされているヘッダなのでそれはないです。
何故出来ないんだろう。。
744デフォルトの名無しさん:2005/09/20(火) 12:34:50
freopenを使わないでstd::coutをファイルにする方法ってないの?
745デフォルトの名無しさん:2005/09/20(火) 12:43:55
リダイレクト
746デフォルトの名無しさん:2005/09/20(火) 12:48:21
>>744
逆に、どうやってstd::freopen()を使ってstd::coutをファイルにするのか聞きたい。
747744:2005/09/20(火) 12:50:57
>745
リダイレクトってOSの?それでは駄目だ。
>746
ごめん。std::freopenではなくて、Cのだ。
748デフォルトの名無しさん:2005/09/20(火) 12:58:33
普通そういう場合は設計段階から考慮して、ストリームをostream&なりで保持して
後から切り替えができるようにするもんじゃないか
749デフォルトの名無しさん:2005/09/20(火) 13:03:12
クラスをポインタ型で宣言して
メンバ関数のアドレスを取得しようとすると
「仮想関数のアドレスを取ろうとしました」って言われる

CGame *game;
game = new CGame;
&(game->Main);  // エラー

こんな感じ
なんで仮想関数?
750デフォルトの名無しさん:2005/09/20(火) 13:07:12
>>749
CGame::Mainが仮想関数なんじゃないの?
751デフォルトの名無しさん:2005/09/20(火) 13:09:35
ただのvoid型
ソース全部検索したけどvirtualって文字列は
CWinAppの派生クラスに1コだけだった
752デフォルトの名無しさん:2005/09/20(火) 13:14:39
>>749
それはVC++の意味不明なエラーメッセージで混乱してるだけ。g++でコンパイルしてみ。
「ISO C++ではそのようなアドレス取得は認められていません」って出るから。
753デフォルトの名無しさん:2005/09/20(火) 13:18:00
>>749
game->Main(); ではないかと釣られてみる。
754デフォルトの名無しさん:2005/09/20(火) 13:18:37
そりゃ残念だ
どうしても手動でメモリ確保しつつ関数のアドレスが欲しかったんだけど
教えてくれてサンクス
755デフォルトの名無しさん:2005/09/20(火) 13:19:59
>>749
&(CGame::Main);じゃなんでダメなの?
756デフォルトの名無しさん:2005/09/20(火) 13:20:48
関数のアドレスを取るだけなら&CGame::Mainでいいけどね。
ただしstaticにしないとコールはできないよ。

コールしたい場合はstd::mem_funか、boost::functionを使うと吉。
757デフォルトの名無しさん:2005/09/20(火) 13:22:07
>>753
「'&' に左辺値がありません」って言われる
その&じゃないってのに

>>755-756
ちょっと考え直してみる
758デフォルトの名無しさん:2005/09/20(火) 13:25:27
>>757
ていうか何でエラーが出るか理解してるか?

C++のクラスでは、オブジェクトがいくつあったところで関数の実体は1つしかなくて
その関数に暗黙にオブジェクトのポインタ(thisポインタ)が渡されるのは知ってるよね?

ということは、オブジェクトAの関数F をポインタで表現しようとなると、
オブジェクトAのアドレスと関数Fのアドレスを両方管理しなきゃいけなくなって
1つのポインタじゃ表現できないからエラーになる。

だから結局、関数だけのアドレスを取得するか(&CGame::Main)、
両方を管理できるmem_funのようなクラスを使う必要があるってだけ。
用途に応じて使い分ければいい。
759デフォルトの名無しさん:2005/09/20(火) 13:27:36
インスタンスをいっぱい生成して
それらのメイン関数をまとめて実行したい
だからメイン関数のアドレスを集めようとしてた

>C++のクラスでは、オブジェクトがいくつあったところで関数の実体は1つしかなくて
>その関数に暗黙にオブジェクトのポインタ(thisポインタ)が渡されるのは知ってるよね?
すいません実は・・・
760デフォルトの名無しさん:2005/09/20(火) 13:28:32
>>756
this->*pFunc
761デフォルトの名無しさん:2005/09/20(火) 13:28:52
>>747
こんな感じで。

#include <iostream>
#include <fstream>

int main()
{
 std::ostream* fsp;
 int i;

 std::cout << "1: std::coutに出力 2: 'test.txt'に出力? ";
 std::cin >> i;

 if (i == 1)
  fsp = &std::cout;
 else if (i == 2)
  fsp = new std::ofstream("test.txt");
 else
  return 0;

 (*fsp) << "出力\n";

 if (fsp != &std::cout)
  dynamic_cast<std::ofstream*>(fsp)->close();
}
762デフォルトの名無しさん:2005/09/20(火) 13:33:00
>>759
boost::signalを調べてみれば?
そこまで複雑なものじゃなくてもいいなら、ちょっと工夫すれば自作できるだろうし
763デフォルトの名無しさん:2005/09/20(火) 16:47:03
下の様に、あらかじめ数が分からないintデータを、ファイルが終わるまでreadしたいのですが、
下のやり方だとreadが一回多くなってしまいます。
上手いやり方があったら教えて頂けないでしょうか。

#include <fstream>

int main(){
int writed_count=0, read_count=0;

std::ofstream ofile( "hoge", std::ios::binary );
for( int i=0; i<5; ++i ){
ofile.write( (const char*)&i, sizeof(int) );
++writed_count;
}
ofile.close();

int array[10] = {0};
int pos = 0;
std::ifstream ifile( "hoge" );
while( ! ifile.eof() ){
ifile.read( (char*)&array[pos], sizeof(int) );
++read_count;
++pos;
}
printf( "write count = %d\nread count = %d\n", writed_count, read_count );
return 0;
}
764デフォルトの名無しさん:2005/09/20(火) 16:52:48
>>763
while (!ifile.eof()) がおかしい。
C/C++はBASICとは違い、一度読んでみて初めてEOFかどうかわかる。
765デフォルトの名無しさん:2005/09/20(火) 16:57:49
従って、「読み込んでからeof()で調べてみて、okだったらやりたいことをやる」
という順序が正解ですな。

たとえば、条件文のところをwhile (1)にした上で、ifile.read()の直後にeof()をチェックして
真だったらbreakするとか、
条件文の中に読み込む式とeof()をカンマで並べるとか。
766デフォルトの名無しさん:2005/09/20(火) 16:58:40
>>764
ありがとうございます、おかげで良く分かりました
この場合はreadの後にeofで終了判定すべきなんですね
767763=766:2005/09/20(火) 17:00:09
>>765
リロードが間に合いませんで
なるほどwhileの所に書く手もあるんですね
重ね重ね感謝ッス
768デフォルトの名無しさん:2005/09/20(火) 18:05:52
listの最後の要素のイテレータが欲しいのですが、
どうすれば効率よく取れますか?
it = list.end();
--it;
はマズイですよね?
769デフォルトの名無しさん:2005/09/20(火) 18:09:53
>>768
std::listのイテレータはBidirectionalIteratorだからまずくない。
770デフォルトの名無しさん:2005/09/20(火) 18:22:25
今ExceptionalC++を読み直してみたらまずいのは
--list.end()でしたね。
ありがとうございました。
771デフォルトの名無しさん:2005/09/20(火) 19:33:12
list.rbegin();
772デフォルトの名無しさん:2005/09/20(火) 19:50:54
>>771
そいつが返すのはreverse_iteratorじゃないのか?
773デフォルトの名無しさん:2005/09/20(火) 22:15:12
>>770
list::iterator が builtin type であることはないから
問題ないのでは?
774デフォルトの名無しさん:2005/09/20(火) 23:27:12
どんなクラスへのポインタも代入できて、そのメンバ関数も実行できる型って無い?
boost::anyでいけるかと思ったけど
メンバ関数を実行しようとすると「boost::anyのメンバではありません」とか言われる
775デフォルトの名無しさん:2005/09/20(火) 23:30:07
どんな型のポインタも代入できる、とは型がないということだ。
メンバ関数が実行できる、とは、型がある、ということだ。

型に共通のメンバ関数を括りだしてインターフェースにするか、
Object型にしてInvoke(COMMAND,...)とか、RTTIで型の列挙、
みたいな話になってくるが。
776デフォルトの名無しさん:2005/09/20(火) 23:36:15
IOの
[io]?strstream
だけがtemplate化されてないのって何か理由あるのかな?
777デフォルトの名無しさん:2005/09/20(火) 23:40:13
標準C++にstrstreamなんてないが。
basic_[io]stringstream<>ならあるけどな。
778デフォルトの名無しさん:2005/09/20(火) 23:41:09
>>775
諦める。・゚・(ノД`)・゚・。
779デフォルトの名無しさん:2005/09/20(火) 23:42:49
>>776
strstream類は過去との互換性のためだけに存在するから。
逆にstringstream類はテンプレートになっている。
780デフォルトの名無しさん:2005/09/20(火) 23:45:02
>>777
少なくともX3014:2003には附属D.7にstrstream類が載っている。
781デフォルトの名無しさん:2005/09/21(水) 00:57:20
>>774
boost::anyにoperator->を付け加えてやればできるのではないかと。
試してないけど。
782デフォルトの名無しさん:2005/09/21(水) 00:59:56
どのみち型が確定しないと意味がない。
783776:2005/09/21(水) 01:11:35
どうも。
>>777
basic_iostream<...>->strstream
>>779
そのような歴史的経緯?もあり、
配列ベースの入出力のようなので今後はあまり使わない方がよさそうですね。
784デフォルトの名無しさん:2005/09/21(水) 01:51:11
そこでObjective C++ですよ
785デフォルトの名無しさん:2005/09/21(水) 03:01:44
どこで?
786デフォルトの名無しさん:2005/09/21(水) 03:40:53
>>784
微妙に使いどころに苦しむ。

オブジェクトに互換性がないんじゃ、混ぜて書けるメリットが無いと思うんだが。
つか、むしろC++ベースでCocoaをサポートしてくれ
787635:2005/09/21(水) 16:47:08
>> 638
情報ありがとうございました。鬼車の c++ ラッパーを作って、ruby-like な gsub とか
scan ができるようになりました。日本語の正規表現も問題なしです。
788デフォルトの名無しさん:2005/09/21(水) 16:57:05
鬼車で解決したみたいだからどうでもいいけど、
日本語で問題があったならwregexだとどうだったんだろうか。
789デフォルトの名無しさん:2005/09/21(水) 18:18:15
PC一般板の、エスパースレから誘導されてきました。
よろしくお願いします。

c++で作られたソフトをダウンロードしたのですが
文字が一部「・」とか「・・」と表示されていて
読めません。
どうすれば日本語に戻りますか?
790デフォルトの名無しさん:2005/09/21(水) 18:25:20
参照仮引数と、ポインタを使った仮引数の違いは
コードの書き方に違いが出るだけで
やってることはおなじと考えていいんですか?
791デフォルトの名無しさん:2005/09/21(水) 18:28:46
>>790
そそ。
792デフォルトの名無しさん:2005/09/21(水) 18:54:15
参照だとNULLを渡せないていう制約はあるけどね
793デフォルトの名無しさん:2005/09/21(水) 18:57:16
こういう変態的な事したら渡せる。
*static_cast<hoge*>(NULL)

まぁ自分もNULLが来ないことを前提にコード書いてるけどね
794デフォルトの名無しさん:2005/09/21(水) 19:43:11
>>789
自分がそのプログラムのソースコードを修正する気でもない限り、ここは板違い。
恨むならエスパースレでお前にここに行けと答えた奴を恨め。
795790:2005/09/21(水) 20:15:18
前勉強したときはなんか頭混乱して
よくわからなかったままだったんですが、
今回勉強し直してたらおんなじなんじゃないかとおもいまして
お聞きしました。
すっきりしました。

さんくすです。
796デフォルトの名無しさん:2005/09/21(水) 20:19:58
クラス内で定義されたタイプはなんて呼んだらいいんでしょう?
メンバータイプでぐぐると異様に件数が少ないんですが・・・
797デフォルトの名無しさん:2005/09/21(水) 20:21:42
>>789
EUCかUTF-8かSJISかいろいろ試せ。
798635:2005/09/21(水) 23:02:51
>>788
gcc with boost::regex (wregex) だと、正規表現自体に日本語を含むケースでまともに
動きませんでした。原因は良く分かりませんが・・・。
799デフォルトの名無しさん:2005/09/22(木) 03:57:41
>>796
クラス内で定義されたクラス型なら
"nested class" 「ネストされたクラス」っていう呼び方があるけど、
typedef だと特に用語も無く「クラス内の typedef 」とか言えばいいと思う。
800デフォルトの名無しさん:2005/09/22(木) 05:50:42
自分のクラスをintの参照にキャストしたい場合、
class AAA
{
public:
operator int&()
{
return & m_i;
}
int m_i;
};
という具合に自分のメンバのm_iのポインタを返せばいいのですか?
正しい方法を教えてくださいませ。
801デフォルトの名無しさん:2005/09/22(木) 07:30:05
>>800
参照とポインタは違う。やればすぐ判ることを一々聞くな。
そもそも、メンバを返すのが適当な設計かどうかは一概には言えんぞ。
それと、constメンバ関数にしておいた方がいいかも知らん。
802初心者:2005/09/22(木) 13:20:24
質問があります。
現在、ボーランドでプログラムを作っているのですが、
TransparentBlt()関数が読み込めないらしく、
 Error: 外部シンボル 'TransparentBlt' が未解決
と出てしまいます。

何かをインクルードし忘れているからでしょうか?
windows.hだけをインクルードしているのですが。
803デフォルトの名無しさん:2005/09/22(木) 13:40:02
804デフォルトの名無しさん:2005/09/22(木) 13:42:18
以下のようなMakefileでコンパイルしているのですが、$(EXE)を生成する時は、$(CC)により指定しているコンパイラを
使ってくれるのですが、$(OBJS)を生成するときは、g++が使われてしまいます。拡張子ルールか何かがまちがっているのでしょうか?
どなたかご教授をよろしくお願いします。
環境は、Red Hat(R) Enterprise Linux AS 2.1

/************* Makefile ****************/
CC = /opt/intel_cc_80/bin/icc
DEBUG = -g
CFLAG = -c $(DEBUG)
OFLAG = -o
IPOFLAG = -ipo
IPFLAG = -ip
LFLAG = -lm

# ソースファイルの宣言
SRCS = Main.cpp HelloWorld.cpp

OBJS = ${SRCS:.cpp=.o}

# 実行ファイルの宣言
EXE = Ocean

$(EXE) : $(OBJS)
$(CC) $(OFLAG) $(EXE) $(IPOFLAG) $(OBJS) $(LFLAG)

.c.o :
$(CC) $(CFLAG) $(IPOFLAG) $<

Main.o : HelloWorld.h
HelloWorld.o : HelloWorld.h
805デフォルトの名無しさん:2005/09/22(木) 13:51:09
>>804
.cpp.oはデフォルトでどう定義されているのか見てみるがよろし。
806初心者:2005/09/22(木) 13:55:17
>>803
どうもです。
行ってきます。
807804:2005/09/22(木) 13:56:20
>>805
c++のプログラムでしたので、
.c.o => .cpp.o
と、変更したら解決できました。ありがとうございます。

ほんとしょうがないミスで申し訳ありません。
808デフォルトの名無しさん:2005/09/22(木) 13:56:29
.c から .o を生成する規則を自分で記述しときながら、実際の SRC は .cpp の群
.cpp から .o を生成する規則を追加汁
809デフォルトの名無しさん:2005/09/22(木) 21:50:36
今晩は、教えてください。
ウィドウに、文字を書き込んでいるのですが、
一定の処で、改行したいのですが、
どうも、区切り場所の文字が、変になります。
バイト数を求めるには、どうすればよいのでしょうか
string hh;
hh = strtok(NULL,"\t");
while(1){
if(strlen(hh.c_str())>=25){
TextOut(ps.hdc,105,takasa,hh.substr(0,24).c_str(),
strlen(hh.substr(0,24).c_str()));
hh = hh.substr(24,hh.length());
takasa +=20;
}else{
TextOut(ps.hdc,105,takasa,
hh.substr(0,hh.length()).c_str(),
strlen(hh.c_str()));
break;
}
}
810デフォルトの名無しさん:2005/09/22(木) 21:58:25
なぜだめなのかを考えなさい
意外と簡単だから
811デフォルトの名無しさん:2005/09/22(木) 22:05:34
strlen(hh.c_str())
ってずいぶん斬新なコードだなぁ、
812デフォルトの名無しさん:2005/09/22(木) 22:21:43
string使う意味が全くないな
813デフォルトの名無しさん:2005/09/22(木) 22:26:49
>>810さんありがとうございます。
何度かんがえてもわかりません。
上のコードでは、最後の文字が半角なら
失敗しす。
だから、最後の文字が半角かどうか判断して、
コードを変えようかと思ったのですが、
もっと簡単な方法があると考えてよいのでしょうか。
そうならば、もっと考えて見ます。

>>811さん、全く読みにくいコードをあげてしまいすみません。
c も c++もまったくしらず、vc++からはじめたので、
charのポインターつかうか、stringクラスつかうか、
あるいは、この関数がどっちの関数なのか、
整理が全くできてない状態です。
814デフォルトの名無しさん:2005/09/22(木) 22:28:59
>>812さんへ
string 使うと、メモリの心配しなくてすむのかなと思ったのですが、
malloc とか、使わなくてすむと・・・
815デフォルトの名無しさん:2005/09/22(木) 22:34:08
>c も c++もまったくしらず、vc++からはじめたので、

こいつは大物になるぜ。
816デフォルトの名無しさん:2005/09/22(木) 22:35:50
>>814
std::string.length()のこともたまには思い出してあげてください。
817デフォルトの名無しさん:2005/09/22(木) 22:36:48
とりあえずstrlen(〜.c_str())は〜.length()に直せ。
818デフォルトの名無しさん:2005/09/22(木) 23:40:07
> hh.substr(0,hh.length()).c_str(),
目から鱗が落ちた。
819デフォルトの名無しさん:2005/09/22(木) 23:45:59
昔見たstr[strlen(str)] = '\0';並にヒットだ俺的に。
820デフォルトの名無しさん:2005/09/22(木) 23:49:01
VB厨臭い使い方だよなあ。MID$のような。
821デフォルトの名無しさん:2005/09/22(木) 23:58:28
>>819
激しく和露他
822デフォルトの名無しさん:2005/09/22(木) 23:58:29
未来の大物が降臨しているなw
ところで皆に聞きたいんだが、クラスのメンバである配列の初期化ってどうやってる?
自分のやり方むちゃくちゃな予感なんで定石を聞きたいんだが。
823デフォルトの名無しさん:2005/09/23(金) 00:00:30
>>822
むちゃくちゃなやり方知りたいので書いて
824デフォルトの名無しさん:2005/09/23(金) 00:00:40
>>822
普通のCスタイル配列じゃコンストラクタ関数の先頭で、とか無理だから
別にないと思うよ。
825デフォルトの名無しさん:2005/09/23(金) 00:07:54
参照をメンバに持つクラスを複数持ちたいときハマるよね。
826822:2005/09/23(金) 00:08:53
class Color {
  union {
    float color[4];
    struct {
      float c1;
      float c2;
      float c3;
      float c4;
    };
  };

  Color(void) : c1(0.0),c2(0.0),c3(0.0),c4(0.0) {};
  Color(float* c) : c1(*c),c2(*(c+1)),c3(*(c+2)),c4(*(c+3)) {};
};

こんな感じでやってる。
827デフォルトの名無しさん:2005/09/23(金) 00:13:23
>>826
float4つだからAltiVecかSSEのコードかと思った。
828デフォルトの名無しさん:2005/09/23(金) 00:19:00
>>826
組込型なら、そういう場合は割り切ってコンストラクタの中で記述するのがいいかと。
829822:2005/09/23(金) 00:25:38
そんなもんか。dd
830デフォルトの名無しさん:2005/09/23(金) 20:13:01
>>819
strを単なる文字型の配列として使っていたら最後が'\0'で終わってるとは限らないから有効なんじゃ、と
一瞬思ってしまったorz
'\0'で終わってなかったらstrlen使えないよな。sizeofならともかく。
831デフォルトの名無しさん:2005/09/24(土) 01:20:45
BCCでコンパイルしたときSleepが未定義の関数ってなるのは俺だけ?
832デフォルトの名無しさん:2005/09/24(土) 01:41:16
>>831
必要なライブラリにリンクしてても出るんなら
あんただけ。
833デフォルトの名無しさん:2005/09/24(土) 12:42:26
イテレータってポインタの代わりとして長期間保持していてるのって普通?
それともイテレータは基本的に複数要素に順番にアクセスするために
あるのであって、単にコンテナ内の一つの要素のアドレスを
長期間保持して好きなときに要素にアクセスしたいだけ(ptr++等のポインタ演算も行わない)
の場合、生ポインタを保持しておいたほうがいいの?
834デフォルトの名無しさん:2005/09/24(土) 12:42:56
質問です。
演算子のオーバーロードは継承した場合引き継がれないのでしょうか。

クラスで演算子のオーバーロードをしました。
class CBase{
(略)
void operator =(CBase*);
};
で、その後CBaseを継承したクラスを作成
class CMain : public CBase{
(略)
}

void main(){
CMain a;
a = new CBase();
}
としたところコンパイルエラーなのです。
ためしに
class CMain : public CBase{
(略)
void operator =(CBase*);
}
としてみたところ、コンパイルがとおりました。
つまり演算子のオーバーロードは継承されないのかなと感じたわけです。
これはそうなのでしょうか。
835デフォルトの名無しさん:2005/09/24(土) 12:46:26
>としたところコンパイルエラーなのです。
内容書けや
836デフォルトの名無しさん:2005/09/24(土) 12:52:35
>>833
イテレータは、ポインタの概念を大きく拡張したもの。
君の言っているポインタは、random access iteratorの事だと思うが、
C++ STLのコンテナや、ストリームは、自由にあちこちをアクセスできない
物がある。

イテレータをそれぞれの属性を持った物として定義する事により、その
コンテナやストリームの意味を逸脱しない範囲でアクセス出来るように
なっている。

それから、長時間保持するとあるが、コンテナのメンバ関数にはイテレータ
を無効にする物があるので、保持しても無意味。
837デフォルトの名無しさん:2005/09/24(土) 13:03:19
>>833
イテレータが無効になるタイミングを把握しているのなら、
長期間保持してもいい。
イテレータとしての操作が不要であれば、
生ポインタのほうがサイズや処理効率の面で
パフォーマンスがいいこともある。

>>836
map や list などのイテレータは、
指してる要素の削除以外では無効にならないんで、
長期間保持するのはよくあることだよ。
838デフォルトの名無しさん:2005/09/24(土) 13:09:19
>>834
演算子のオーバーロードも継承される。
ただし代入演算子の場合はうまくいかない。

同じクラスの代入用 T& operator = (T const&) はクラスを定義ごとに必ず宣言される。
ユーザーが宣言しなくても、コンパイラが自動的に宣言する。

前者のケースではコンパイラが自動的に追加した宣言によって
CBase の operator = が隠れてしまっている。
839デフォルトの名無しさん:2005/09/24(土) 13:25:25
>>838
あらー、代入演算子だけはダメなんですか。
ありがとうございます。

いちいち代入演算子のオーバーライドに長々プログラム書くのはアレなので、
CBaseにInsert()という関数を作ってそれを呼ぶようにします。

void operator =(CBase* p){
insert(p);
}

>>835
失礼しました。
error C2679: 二項演算子 '=' : 型 'class Image *' の右オペランドを扱う演算子は定義されていません。(または変換できません)
でした。
840デフォルトの名無しさん:2005/09/24(土) 13:47:41
>>839
そんなことするぐらいなら、全部 Insert() 使ったほうがいいぞ。
ただ便利だからと言うだけの理由で
組み込み型と意味の違う代入演算子を作るのはよくない。

さらに、 >834 の例だと a = 0 なんてコードもコンパイルが通る。
new の戻り値を生ポインタで受け取るのも危ない。
841デフォルトの名無しさん:2005/09/24(土) 14:18:16
>>837
例えばstd::mapが赤黒木で構成されているとして、挿入後回転や二重回転
が起きてもイテレータは全部有効なのか?

insert()が挿入後の新しいイテレータを返すようになっている仕様は、そういう
意味だと思っていたが。
842デフォルトの名無しさん:2005/09/24(土) 14:18:19
>>840
>ただ便利だからと言うだけの理由で
>組み込み型と意味の違う代入演算子を作るのはよくない。
なるほど、確かにその通りですね。
じっくり考えてみます。ありがとうございます。
843デフォルトの名無しさん:2005/09/24(土) 14:54:15
>>837
なるほど。そういう感じで使い分ければいいのですか。
ありがとうございます。

>>841
ISO/IEC 14882:1998
23.1.2 Associative containers
-8-
The insert members shall not affect the validity of iterators and references to the container,
and the erase members shall invalidate only iterators and references to the erased elements.
なので>>837さんが正しいです
844デフォルトの名無しさん:2005/09/25(日) 07:39:18
LinuxでMPIを使ったC++コードのデバッグをVC++みたいに
やるにはTotalViewとかを導入するしかないですか?

フリーのデバッガでMPIプログラムのデバッグをやるのに
便利なツールがあれば教えて下さい。
845デフォルトの名無しさん:2005/09/25(日) 09:42:09
>>844
スレ違い。>1くらい読んでくれ。
846デフォルトの名無しさん:2005/09/25(日) 14:31:15
>>832
ありがと。
ライブラリにリンクするの忘れてた。
オレが糞なだけだったよー。
847デフォルトの名無しさん:2005/09/25(日) 18:12:55
派生クラスのインスタンスを基底クラスのポインタに入れると
仮想関数も基底クラスで定義したものに変わるの?
848デフォルトの名無しさん:2005/09/25(日) 18:16:50
変わったら仮想関数の意味がないじゃない。
849デフォルトの名無しさん:2005/09/25(日) 18:18:05
まさにそれを変わらないために作られたカラクリが仮想関数なんだしな
850デフォルトの名無しさん:2005/09/25(日) 18:18:56
そうだよね。何がおかしかったんだろ
851デフォルトの名無しさん:2005/09/25(日) 18:30:32
852デフォルトの名無しさん:2005/09/25(日) 19:12:06
。・゚・(ノД`)・゚・。
853デフォルトの名無しさん:2005/09/25(日) 23:11:50
わかりにくかったらすみません。
Visual C++6.0なんですけど

struct 1_t {int s ;
int t ;
int u ;
} ;

struct 2_t {int A[N][N] ;
int B[N] ;
int C[Y] ;
int D[Y] ; 
} ;

struct 3_s {struct 1_t 1_s ;
struct 2_t 2_s ;
int E[2] ;
} 3_t[V][W] ;

って感じで構造体配列をヘッダで生成して、Mainで

struct 3_s *p = 3_t ;

ってやってポインタ代入するんですが、新しい動作:
C2440エラーってのが出ます。
色々試してみると、1次元配列にするとエラーが
出ないようなのですが。
854デフォルトの名無しさん:2005/09/25(日) 23:15:30
pは3_sへの単純なポインタだから1次元配列相当
struct 3_s *p = 3_t[0];なら代入はできるだろう
855デフォルトの名無しさん:2005/09/25(日) 23:21:46
>>854
早速の回答ありがとうございます。
試してみたところエラーは無くなりました。

以前そういう記述を読んだ記憶がわずかにあるの
ですが今手元に参考書が無いので確認できません。
とにかくありがとうございました。
856デフォルトの名無しさん:2005/09/25(日) 23:54:22
>>853
標準では、名前は非数字から始まらなくてはならないと規定されているから、そんな名前は避けること。
857デフォルトの名無しさん:2005/09/26(月) 01:31:10
>>855
struct 3_s (*p)[W] = 3_t; でもいけるだろ。こちらは二次元配列風にアクセス
できる、配列へのポインタとなる。
858デフォルトの名無しさん:2005/09/26(月) 22:59:42
>>809です
皆様、いろいろご指導ありがとうございました。
mblenを使って解決いたしました。
859デフォルトの名無しさん:2005/09/27(火) 03:22:25
質問です。

暗黙のキャストが行われている箇所を明示的なキャストに変更する事によって、
処理速度が遅くなるといったことはあるのでしょうか?
860デフォルトの名無しさん:2005/09/27(火) 03:23:53
ありません
861デフォルトの名無しさん:2005/09/27(火) 03:42:03
>>859
暗黙のキャストを明示しただけなら、遅くなることは無い。
だが明らかに、そんなことはしないほうがいい。
862デフォルトの名無しさん:2005/09/27(火) 03:46:14
dinamic_castに変更したら遅くなるかもねー
863デフォルトの名無しさん:2005/09/27(火) 03:46:59
○dynamic_cast


釣ってくる
864デフォルトの名無しさん:2005/09/27(火) 03:48:50
>>861
式の可読性のために明示することはあるけどね。
865859:2005/09/27(火) 03:51:09
回答ありがとうございます。

>>861
明らかにそんなことしないほうがいいというのは、
そもそもキャストする必要がないようにコードを書き直すべき、
という意味でしょうか?
866デフォルトの名無しさん:2005/09/27(火) 04:09:22
C++ で以下のようなコードを書くと

typedef struct {
int i;
} foo;

typedef struct {
foo foo;
} bar;

gcc 3.3.5 でコンパイルしたときに下記のようなエラーが出てしまいます。

error: declaration of `foo <無名 struct>::foo'
error: changes meaning of `foo' from `typedef struct foo foo'

定義を変えずにこれを回避するにはどうすればよいのでしょうか?
(上記の定義は C のコードとして書かれたもので、私が書き換えることはできません)

書き換えることができるなら bar の定義を次のようにすれば良いのですが...

typedef struct {
foo foo_;
} bar;
867デフォルトの名無しさん:2005/09/27(火) 08:08:26
ハードゲイ?
868デフォルトの名無しさん:2005/09/27(火) 08:42:04
>>866
typedefを取れ。
869デフォルトの名無しさん:2005/09/27(火) 08:43:21
あ、それだけではだめだ。

struct foo {
int i;
};

struct bar {
foo foo;
};
870デフォルトの名無しさん:2005/09/27(火) 08:54:44
>>869
書き換えない前提だとさ。
871デフォルトの名無しさん:2005/09/27(火) 10:18:07
>>865
そうだよ。

>>864
そんなのあるっけ?どんなとき?
872デフォルトの名無しさん:2005/09/27(火) 10:30:16
>>871
>>864じゃないけど、オーバーロードの絡む場合。たとえば、
unsigned char *addr;
std::cout << "addr = " << (void *)addr << "\n";
とか。
873デフォルトの名無しさん:2005/09/27(火) 10:42:39
>>872
それは可読性のためじゃなくて、望みの動作をさせるために必要なんだろ。
874デフォルトの名無しさん:2005/09/27(火) 10:46:19
全ての暗黙の変換を起こらないように書くことなど、実際的不可能だし意味がない
875デフォルトの名無しさん:2005/09/27(火) 10:51:25
>>874 だれもそんな話はしてないわけだが。
876デフォルトの名無しさん:2005/09/27(火) 11:19:43
畜生。規格書にはanonymous union についてしか書いてないな。
877デフォルトの名無しさん:2005/09/27(火) 11:31:40
>>866
ttp://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#407

こんな話で規格がごたごたしている現状では無理だな。
878デフォルトの名無しさん:2005/09/27(火) 11:35:16
↓これなら通るみたい。

typedef struct foo {
int i;
} foo;

typedef struct {
struct foo foo;
} bar;

こういう混乱を避けるため、Cのコード書くときは
・無名の struct/unon/enum は使わない。
・struct/union/enum を省略するためだけの typedef は避ける
というガイドラインを実施したほうがよさそう。
879デフォルトの名無しさん:2005/09/27(火) 11:37:01
MSVCだとそのまま通るな。gccの問題か?
880デフォルトの名無しさん:2005/09/27(火) 13:24:54
gcc では問題なくて、g++ で error だな。
コンパイラ換えるか、そこだけでも C(not C++)にするか…
>>866
いずれにせよ、書き換えることができない、という前提自体が間違いなので、
お好きにすれば、としかならないなあ。
881872:2005/09/27(火) 16:27:23
>>873
勘違いしてた。
でも、unsigned char *の代わりにint *ならどうよ。
882デフォルトの名無しさん:2005/09/27(火) 18:06:13
>>866
元のヘッダをlegacy.hとして
$ cat legacy.h
#ifndef Legacy_H
#define Legacy_H
typedef struct {int i;} foo;
typedef struct {foo foo;} bar;
#endif
$ cat bar.h
#ifndef Bar_H
#define Bar_H
#ifdef __cplusplus
extern "C" {
struct bar;
struct foo;
#else
# include "legacy.h"
#endif
struct Bar {bar *bar_;};
struct Bar *init_bar (struct Bar *p);
int *access_foo_i (struct Bar *p);
#ifdef __cplusplus
}
#endif
#endif
(続く)
883デフォルトの名無しさん:2005/09/27(火) 18:06:44
$ cat bar.c
#include "bar.h"
#include <malloc.h>
struct Bar *init_bar (struct Bar *p)
{
p->bar_ = (bar *)malloc (sizeof (bar));
return p;
}
int *access_foo_i (struct Bar *p)
{
return &p->bar_->foo.i;
}
$ cat test.cpp
#include <iostream>
#include "bar.h"
using namespace std;
int main ()
{
Bar b0;
init_bar (&b0);
*access_foo_i (&b0) = 10;
cout << *access_foo_i (&b0) << endl;
return 0;
}
$ gcc -c bar.c
$ g++ -o test test.cpp bar.o
$ ./test
10
でどう?
884デフォルトの名無しさん:2005/09/27(火) 19:09:41
>>882

> (上記の定義は C のコードとして書かれたもので、私が書き換えることはできません)

て書いてあるからifdef __cplusplusマクロなんぞも追加できないだろう
885882:2005/09/27(火) 19:48:04
>>884
オリジナルと別に用意したラッパに加えるのはいいのでは?
886デフォルトの名無しさん:2005/09/27(火) 21:42:54 ID:0
>>885
……まさかと思ったが本気のつもりでこんなコードを……
まあくそみたいな前提にはそれにふさわしい例がつくという見本として……
887デフォルトの名無しさん:2005/09/27(火) 22:26:45 ID:0
そのlegacy.hを使いたい関数だけCでオブジェクトファイルを作ってリンクしたらいいんでない?
888デフォルトの名無しさん:2005/09/27(火) 23:03:33
>>886
ライブラリかなんかなんでしょ?
くそみたいなってのには違いないけど
889デフォルトの名無しさん:2005/09/27(火) 23:15:48
>>887
>>880
>>888
「ライブラリかなんか」でも無条件に書き換えられないわけではあるまいに。
どっちにしてもくそみたいなもんだが。
つか、とことん無意味に前提や条件をとり違えて問題点を見失っとるわけだが。
890866:2005/09/28(水) 00:05:44
皆さんいろいろとありがとうございます。
有効打はなさそうですね...

ありがとうございました。
891デフォルトの名無しさん:2005/09/28(水) 19:07:21
質問です。
operatorのオーバーライドで、
int n;
CHoge c;
n = c;

という式を処理させたいのです。
どうにかintへの=をオーバーライドする術はないものでしょうか。
892デフォルトの名無しさん:2005/09/28(水) 19:13:19
=じゃなくてoperator int()作れば?
893デフォルトの名無しさん:2005/09/28(水) 19:36:59
>892
お返事ありがとうございます。
ただすいません、operator int() というのがどういうものなのか分かりません。

オーバーライド系の解説サイトはロベールさんのところをはじめ、あっちこっち見たのですが。
もしよければそれについて詳しいサイトを教えていただけませんでしょうか。
894デフォルトの名無しさん:2005/09/28(水) 19:55:03
だめだこりゃ
895デフォルトの名無しさん:2005/09/28(水) 20:05:31
896デフォルトの名無しさん:2005/09/28(水) 20:08:07
それC#じゃね?w
897デフォルトの名無しさん:2005/09/28(水) 20:09:20
>>893
続けるなら初心者スレへどうぞ。
898デフォルトの名無しさん:2005/09/28(水) 20:13:14
了解しました。初心者スレに移動します。
899デフォルトの名無しさん:2005/09/29(木) 06:00:30
ロベールさんって誰やねんw
900デフォルトの名無しさん:2005/09/29(木) 15:00:22
901デバッグ生活6週間目:2005/09/30(金) 14:19:11
初学者はつい目先のコンパイルエラーの解消に夢中になるあまり
考察の足りない小手先の修正をして事態を悪化させることがある。
最近デバッグ中に、某ソフトウェア・ハウスへ数年前に外注したコード中で
この例の反面教師となるようなダメかつ姑息なコードを見つけて
唖然としたので晒しておく。

まずは背景解説。

class A {
  public:
  A(void) {;}
  //...(omit)
  virtual void v(void)=0;
   //pure virtual function
};

class D : public A {
  D(void) : A() {v();}
   // pure virtual function is called!
  //...(omit)
  void v(void) {/* anything */;}
};

こういうコードはC++では実行結果が不定になる。
(分かりやすく言うと書いちゃだめ。)
仮想関数のセットアップはコンストラクタの実行の
どの段階で行われるか規格は敢えて厳密には決めていないからだ。
仮想関数をコンストラクタ中で呼び出すことはそもそも微妙だが、
特に純粋仮想関数の場合は深刻で、結果は不定だと明示されている。
気の利いたコンパイラなら上掲のコードについてエラーを報告するだろう。
(余談だがJavaのコンストラクタは根本的にC++と動作が違うのでOK。)
902& ◆uJ1hK4x8zw :2005/09/30(金) 14:20:21
>>901から続く)
で、エラーを出されたからといってその意味を深く考えないで:

class A {
  public:
  A(void) {;}
  //...(omit)
  virtual void v(void)={throw new NotCallException();}
    //Non pure virtual function in the appearance only.
};

とかやって見かけ上だけ小手先で回避しようとするのはよくない。
本当に仮想関数をコンストラクタ内で呼び出す必要があるのかどうか、
もしあるならどういうタイミングでどの関数が呼び出されるか
じっくり考えてみるべきだ。
903デバッグ生活6週間目:2005/09/30(金) 14:22:14
>>902から続く)
まして:

class A {
  public:
  A(void) {;}
  //...(omit)
  virtual void v(void)=0;
    //pure virtual function
  protected:
  void bypass(A* a) {a->v();}
};

class D : public A {
  D(void) : A() {bypass(this);}
    // Ooops!! pure virtual function is called!
  //...(omit)
  void v(void) {/* anything */;}
};

などとやってコンパイラを出し抜こうと考えるのは
以ての外である。
これはコンパイラが検出可能だったシンプルな問題を
ロジックをスパゲティ化することで
コンパイラにも人間にも
見つけにくい実行時エラーに変えて
隠蔽したに過ぎない最低のコードになる。
904& ◆uJ1hK4x8zw :2005/09/30(金) 14:26:38
>>901-903
以上、こういうコードは真似しないようにしようというお話。
以下これを見つけた私がどう思ったかは愚痴スレでw

ぐち0x12 〜底なし沼はなお深く〜
http://pc8.2ch.net/test/read.cgi/prog/1116475364/
905デフォルトの名無しさん:2005/09/30(金) 17:38:48
宣伝死ねって事でいいんだろうか
906デフォルトの名無しさん:2005/09/30(金) 18:13:12
最初は愚痴の部分まで一気に書きかけたが、
誘導される前に自己誘導&自粛したってことで。
907デフォルトの名無しさん:2005/09/30(金) 20:44:40
愚痴の部分抜いたら初心者でもマトモな脳みそがあれば
自分で分かるような事を偉そうに書いただけになるんだが。
908デフォルトの名無しさん:2005/09/30(金) 23:10:12
長すぎ。3行で飽きて読むのやめた。
909デフォルトの名無しさん:2005/10/01(土) 00:48:25
>>901-908
全部自作自演って落ちなんだろ?
910デフォルトの名無しさん:2005/10/01(土) 05:52:26
>>901
コンストラクタ内で仮想関数を呼び出したときの動作については
規格中に記述があるよ。 12.7.3 がそう。
 D(void) : A() {v();}
ここでは D::v() が呼び出される。
そして D::v() は純粋仮想関数では無いので、
呼び出し自体に問題は無い。

偉そうな長文が間抜けだな。
911デフォルトの名無しさん:2005/10/01(土) 17:16:30
偉そうな奴は大抵間抜けだからな。
912デフォルトの名無しさん:2005/10/02(日) 02:05:03
メンバ関数ポインタのポインタをtypedefを使わずにどのように定義したらいいんでしょうか?

typedef void(*ClassName::Func)();
Func* f;
のFunc*をtypedefを使わずに定義したいんです。

単なるメンバ関数のポインタなら
void(ClassName::*f)();
でいいんですが....
913デフォルトの名無しさん:2005/10/02(日) 02:09:44
>>912
みずらくなるからやめれ
914デフォルトの名無しさん:2005/10/02(日) 05:03:17
std::string型の変数に"2.5"や"4.7"などの小数点を含む数字の文字列が格納されているのですが、
これを数字として扱って加減乗除するにはどうすればいいですか?
915デフォルトの名無しさん:2005/10/02(日) 07:33:08
こんな感じかな
std::string s = "2.5";
double x;
std::sscanf(s.c_str(), "%lf", & x);
916デフォルトの名無しさん:2005/10/02(日) 07:44:26
>>915
いい加減Cの呪縛から逃れろ。
>>914
boost::lexical_cast<double>(str)を使うか、std::stringstream s(str); s >> d;
などどやる。
917デフォルトの名無しさん:2005/10/02(日) 08:42:15
>>915
C流でやるならせめてstd::atof(s.c_str())にしてくれ。
918デフォルトの名無しさん:2005/10/02(日) 09:31:40
>>912
俺もそのままtypedef使えとは思うが、こういう手段を知っていても損はないと思う。
#include <iostream>
#include <typeinfo>

class ClassName {};
typedef void (*ClassName::Func)();

int main()
{
    std::cout << typeid (Func *).name() << std::endl;
}
919デフォルトの名無しさん:2005/10/02(日) 09:54:02
>>916
C++は両方とも糞重いのが難点
まあlexical_castも中でstringstream使ってるから当たり前だけど。
920914:2005/10/02(日) 10:49:27
>>915-916
ありがとうございました。お蔭様でうまくいきました。
921デフォルトの名無しさん:2005/10/02(日) 10:50:13
貧弱シンプルC路線で行くか重厚楽々C++路線で行くか
922デフォルトの名無しさん:2005/10/02(日) 10:51:29
それを好きに選べることがC++のいいところでもある。
923デフォルトの名無しさん:2005/10/02(日) 11:24:32
でも単なる変換ならatofのが早くて楽な罠。
sscanfは使わないけど。。
924デフォルトの名無しさん:2005/10/02(日) 18:06:18
大量にメモリを確保する予定がある場合、
配列で一気に確保するのと、ちまちま一つずつnewしていくのでは、どちらが確実なのでしょうか。
速さは問いません。

配列の方が無駄が無さそうですが、
素人目にはしかし、連続したメモリ空間が無いと失敗しちゃいそうなイメージがあります。
925デフォルトの名無しさん:2005/10/02(日) 18:13:54
>>924
どっちかと言うと、ちまちま一つずつのほうが成功しやすいだろうな。

ページングの効く環境であれば、物理メモリの
フラグメンテーションによる危険性はほとんど無視できるんで、
あんまり差は無いと思うよ。
926デフォルトの名無しさん:2005/10/02(日) 18:29:15
関係ないけどC++にとってatoiは標準ライブラリなの?
単に好みとしてC++の標準ライブラリだけを使いたくなるものジャン。
でもC++でatoiみたいなことするにはstrstreamに対して<<とか使うんでそ?めんどい
927デフォルトの名無しさん:2005/10/02(日) 18:31:22
>>926
じゃあなんでstdネームスペースがあるんだよって言いたくなる
928デフォルトの名無しさん:2005/10/02(日) 18:38:07
atoi
The return value is 0 if the input cannot be converted to a value of that type.
だれじゃこんな糞仕様にしたのは
929デフォルトの名無しさん:2005/10/02(日) 18:41:21
ごめん
930デフォルトの名無しさん:2005/10/02(日) 18:42:06
そんな時はstrtolですよ。
931924:2005/10/02(日) 18:58:41
>>925
用語を調べていたら遅くなってしまいすいません。
おかげでとても勉強になりました。ありがとうございました。
932デフォルトの名無しさん:2005/10/02(日) 19:25:07
Cに由来する標準ライブラリ関数を残らず再設計してリプレースしてほしい
933デフォルトの名無しさん:2005/10/02(日) 19:39:43
>>926
少なくともJIS X3014:2003では<c〜>もその他のヘッダも全く同列に扱われている。
もっとも<c〜>のほとんどはCの<〜.h>と同じと書かれているが。
934デフォルトの名無しさん:2005/10/02(日) 19:43:09
>>926
そんでもってstrstreamはほかとは別扱いで附属書D 互換性に載せられている。
935デフォルトの名無しさん:2005/10/02(日) 20:19:02
そりゃあstrstreamはdeprecatedだからな
936デフォルトの名無しさん:2005/10/02(日) 20:31:15
>>928
文句があるなら>930。
私ゃ妥当な仕様だと思うがね。
937デフォルトの名無しさん:2005/10/02(日) 23:44:16
そういや、strstreamは使った事ないな。俺がC++始めた時には既に
標準規格が決まっていて、strstreamは使わないでください、みたいな
事が書いてあったな。でもこれを使ってるプログラムはたくさんあるわけで、
過去との互換性に残すんでしょ?
938デフォルトの名無しさん:2005/10/02(日) 23:47:09
strstreamは規格化(?)されたときにすごく非難された、とは聞いたことがある。
んだからstrstreamを使ってるプログラムはほとんどないんじゃない?
939デフォルトの名無しさん:2005/10/02(日) 23:52:02
>>926はstringstreamを知った上でわざとstrstreamを出したのかな
940デフォルトの名無しさん:2005/10/03(月) 00:01:27
>>938
ISO/IEC 1482:1998の通り、標準規格が決まったのは1998年の事で、C++自体は
1985年頃からあるわけで、その13年間でdeprecatedなプログラムが書かれた可能性
はどうかな?

あ、そうか、STLそのものは1993年にC++への組み込みが提案され、1994年に正式
に取り入れられる事が決まったので、たった4年ほどしかstd::strstreamを安心して
使える時期はなかったんだね。
941デフォルトの名無しさん:2005/10/03(月) 11:34:47
>>910
その動作は10年前から知ってる。
…だからわざわざ絶対にまずい純粋仮想関数の場合と分けて
「微妙だ」と書いたんだが。

仮想関数がコンストラクタ内でだけは通常のようなオブジェクトの動的な型ではなく、
静的な型に従って呼び出されるというのは決して直感的に分かりやすい動作とは思えない。
(その呼び出しそのものは確かに動作として安全ではあっても、
その仮想関数からさらに仮想関数が呼ばれたりRTTIが利用されたりした場合の
動的な型と静的な型がどうなっているか考えると頭が痛くならないか?
多分このようにコンストラクタ内でだけ仮想関数の動作が「特別扱い」される仕様は
古いC++コードとの互換性のために残ってしまった仕様ではないかと思う。
そしてこの微妙な仕様のせいで純粋仮想関数をコンストラクタ内で呼ぶのは
呼ぶ相手がなくなるために具合が悪いわけだ。
純粋仮想関数のほうが歴史的には後でできた仕様だったからこうなったのだろうが。)

・・・なので絶対に必要なとき以外はやはり書かないに越したことはにと思うのだ。
(もっともその「絶対に必要な例」は中々思いつけないが。)
というわけで例に挙げたコードのように論理的には純粋仮想関数であるべきものを
コンパイルエラー回避目的でエラー例外を投げる仮想関数に書き換えるのは
決して必要に迫られて熟慮した結果というよりはやっぱり性質の悪い小手先の誤魔化しだと思う。
942謹んで訂正:2005/10/03(月) 11:40:10
>>941
・書かないに越したことはにと思うのだ→書かないに越したことはないと思うのだ
・決して必要に迫られて→ 必要に迫られて
943デフォルトの名無しさん:2005/10/03(月) 12:47:27
>>901
>こういうコードはC++では実行結果が不定になる。
>(分かりやすく言うと書いちゃだめ。)
>仮想関数のセットアップはコンストラクタの実行の
>どの段階で行われるか規格は敢えて厳密には決めていないからだ。
>仮想関数をコンストラクタ中で呼び出すことはそもそも微妙だが、
>特に純粋仮想関数の場合は深刻で、結果は不定だと明示されている。
>気の利いたコンパイラなら上掲のコードについてエラーを報告するだろう。

・初心者も読むスレッドでこういう嘘を平気で書き、なおかつ指摘されても訂正もしない
・他人のミスとも言えないようなミスはことさらに(誤りを含んだ)長文で指摘する
・しかも多分スレ違い。
944デフォルトの名無しさん:2005/10/03(月) 12:57:50
>>943
たぶん、得意げになりたかっただけだろ。
スルーで勘弁してやってくれ。
945デフォルトの名無しさん:2005/10/03(月) 13:43:37
>>941
恥をかきたくなかったら、最低でも、規格書のどこを読めば
そんな動作をするか、リファレンス先を書いておけ。

ま、この場合完全な嘘だから、リファレンス先などありはしないがな。
946デフォルトの名無しさん:2005/10/03(月) 14:39:13
>>941
D&E読め。
コンストラクタで仮想関数呼び出しでは派生クラスでオーバーライドしたほうの関数が呼ばれない理由がちゃんと書いてある。

ようするに派生クラスでオーバーライドした仮想関数の実装が
その派生クラスのコンストラクタが行われていることに依存していたら、
派生クラスのコンストラクタが呼ばれる前(== 基底クラスのコンストラクタの中)で、
派生クラスでオーバーライドされた仮想関数が呼ばれたらまずいことになる、
だからはコンストラクタでの仮想関数呼び出しでは派生クラスでオーバーライドした関数は呼ばれない仕様にしたと書いてある。
947デフォルトの名無しさん:2005/10/04(火) 00:53:48
>>941
この動作がいかに(マシンにとって)自然であるか理解していないのなら、
10年もの間、誤解していたことになるな。
948デフォルトの名無しさん:2005/10/04(火) 00:57:10
>>941は自我崩壊寸前です。
949デフォルトの名無しさん:2005/10/04(火) 01:27:04
>>941はJavaから入ったに違い無い
950デフォルトの名無しさん:2005/10/04(火) 01:44:15
>>941 ワロスwwwwnwっうぇwuwwwrwuwっうぇwwpwwwwwow
951デフォルトの名無しさん:2005/10/04(火) 03:12:06
さあ、そろそろ>>941の長文が飛び出すぞw
952デフォルトの名無しさん:2005/10/04(火) 03:31:20
晒し上げしていいの?
953デフォルトの名無しさん:2005/10/04(火) 08:32:32
ドゾー
954デフォルトの名無しさん
ここまで説得力の無い長文の言い逃れは久々に見たw