■過去ログ置き場に戻る■ 1- 前250 次250 最新50


[memo] "9999999999_00.html#R20" という感じで、URLの最後に "#RレスNo" を追加すると幸せになれます。

C++相談室 Part3
251 名前:248 :01/11/07 00:30
>>250
本屋で探してきます。ありがと。ちゅ。

252 名前:デフォルトの名無しさん :01/11/07 01:04
「例外安全」「中立」ってなに?
用語がわからん

253 名前:245 :01/11/07 01:12
例外安全
例外発生時にもリソースが適切に解放され、かつ一貫性が保たれること

例外中立
例えが委を処理しない場合、呼び出し側で処理できるようにその例外を伝えること。

C++を使う上で設計にも関わるくらい大切なことみたい。
>>250の本を読んでみてね。

254 名前:デフォルトの名無しさん :01/11/07 01:19
>>253
> 例外安全
> 例外発生時にもリソースが適切に解放され、かつ一貫性が保たれること

「リソースが適切に解放され、かつ」は冗長。

255 名前:252 :01/11/07 01:27
>>253
・・・それって、当たり前にそうあるべきことじゃないの?

256 名前:245 :01/11/07 01:29
>>254
もっと精を出して読みます。

>>255
当たり前にやるべきだとおもいます。

257 名前:デフォルトの名無しさん :01/11/07 01:32
コンストラクタ、デストラクタ。
演算子オーバーロード。
テンプレート。

これらのキーワードと例外処理くんの民族紛争の話です。

258 名前:デフォルトの名無しさん :01/11/07 02:03
クラスの関係にis_a(継承)と
has_a(インスタンス保持)ってあるじゃん。
あれの使い分けがようわからん。
なんかhas_aばっかしになる私はDQN?

259 名前:デフォルトの名無しさん :01/11/07 02:23
つーか、基礎英語ヤレ。

260 名前:デフォルトの名無しさん :01/11/07 02:31
スレッドセーフなので
エクセプションセーフの方が良かったかも
いや例外セーフか。
やっぱ例外安全か。

261 名前:デフォルトの名無しさん :01/11/07 02:36
is-a has-aって久々に聞いたなぁ

262 名前:デフォルトの名無しさん :01/11/07 02:37
>>258
委譲やコンポジションを使いこなしているならOK

263 名前:ななし :01/11/07 08:37
VCで,
CMap <int,int,CArray,CArray&> Fx;
って宣言すると,CArrayが引っかかる.なぜ?
使い方が根本的にまちがってるのかつら?

264 名前:デフォルトの名無しさん :01/11/07 09:08
>>263
CMap<int,int,CArray<int,int>,CArray<int,int>&> Fx;

265 名前:デフォルトの名無しさん :01/11/07 11:31
>>255
いいえ。

例外安全にしようと思うと、メソッドのインターフェースから制限されてしまう場合もあるし、特に
テンプレートが絡む場合には設計の難易度が上がります。例外が発生したら「例外が発生し
ました」という情報だけ伝えることにして、例外を発生させたインスタンスは以後は使えないこと
(デストラクトだけは可能)にするという選択もアリです。

266 名前:デフォルトの名無しさん :01/11/07 11:46
igoire , tolower, boolalpha...
これってみなさん何て呼んでます?

267 名前:デフォルトの名無しさん :01/11/07 14:21
>>245
http://www.shindich.com/sources/c++_topics/exceptions.html
の定義だと、
例外安全 - 例外時のオブジェクトの状態を保持する
例外中立 - 知らない例外は全て遺伝させることを保証する
とある。 例外安全はDBのロールバックみたいな物だね。

>>265
コンテナが例外発生後は使えないようになるなんていう設計だとかなり
苦しいと思うけど。使えないようになるってことは、以降にアクセスした
スレッドに対してまた「使えません」と例外投げるってことだろう
からかなりやばい例外でない限りコスト的に見合わないような気がする。
例外中立って例外安全に対する机上の比較ネタじゃないの?

268 名前:デフォルトの名無しさん :01/11/07 14:23
>>265
適切にデストラクトできるという保証をするには、
それなりのコストがいるので、どうせやるならはじめから
強い保証を行うべきだと思ってる。

たとえばスレッドのハンドルを管理するmapのようなコンテナクラスが
あったとして、新しいスレッドの追加時に例外が発生したら、
それ以降はデストラクトしかできませんよ、というわけにはいかないよね。

mymap<threadhandle> threadmap;

threadmap.insert(CreateThread()); // ここで死んだらどうする?

単純なクラスであればそれもいけるかもしれないけど、
すべてがすべて、失敗したらプログラムも終わり(後始末も無し)
ってわけにはいかないよ。

269 名前:デフォルトの名無しさん :01/11/07 14:24
質問です。
ストリームとは何なんでしょうか?cout等はストリームを操作しているらしいのですが・・・・・
いまいちピンときません。
tcpのストリームとは全く違った概念なんでしょうか?

270 名前:デフォルトの名無しさん :01/11/07 14:34
どっちも広い意味でのストリームだが、扱うものも意味も違う。

271 名前:デフォルトの名無しさん :01/11/07 14:38
>>268
> 単純なクラスであればそれもいけるかもしれないけど、
> すべてがすべて、失敗したらプログラムも終わり(後始末も無し)
そもそも 265 は

 「すべてのクラスが堤外安全」でなくてもいい

であって、

 すべてのクラスが「例外安全でなくても」いい

ではないと思われ。

リソースとしてメモリしか使わないコレクションクラスの類はともかく、ハードウェアと密接に絡むような
操作だと、一度発行したら容易には元に戻せないこともあるし。

272 名前:デフォルトの名無しさん :01/11/07 14:41
>>269
http://yougo.ascii24.com/gh/38/003826.html

先頭から順番に、シーケンシャルに、データを読むことを
ストリームと言うね。
UNIXの標準入出力と言うと、コンソールやらファイルやら
プロセス間のやりとりやらをすべてストリームとして
扱うとこのできる仕組み。
coutは標準出力を扱うインスタンス。

273 名前:デフォルトの名無しさん :01/11/07 14:56
>>270-272
レスありがとうございました。勉強になります。

274 名前:デフォルトの名無しさん :01/11/07 15:17
初歩的な事だと思うんですけど整数を表示させる時10桁以上の整数は
どのようにすればいいんでしょうか?
教えて下さい

275 名前:デフォルトの名無しさん :01/11/07 15:50
>>274
64ビットの整数演算は「long long」や「__int64」などで使える場合が多いです。
(処理系によって違うので、ドキュメントなどで調べてください)
64bit以上の数十、数百桁の演算を行う場合は、それ用のライブラリを用意する必要があります。
ネットで公開されていると思いますので「多倍長」などの言葉で検索をかけてください。

276 名前:デフォルトの名無しさん :01/11/07 16:16
>>275
ありがとうございました。自分はUNIXでやってるんですけど
long long int a=10000000000
みたいな感じでいいんでしょうか?

277 名前:デフォルトの名無しさん :01/11/07 16:22
>>276
gccだったら、それでOKです。
printf()なんかで表示するときは、%dじゃダメっぽいので、
気をつけてください。

278 名前:デフォルトの名無しさん :01/11/07 16:26
long long int で定義したらこのようなエラーが出ました、なぜなんでしょうか?
syukudai.cpp:17: integer constant out of range
syukudai.cpp:17: warning: decimal integer constant is so large that it is unsigned

279 名前:デフォルトの名無しさん :01/11/07 16:28
>>276
ビット長は処理系依存なので、環境も明記したほうが良いと思われ。64bit 版 Solaris だと long で
64bit, int 32 bit だったりするし。

280 名前:デフォルトの名無しさん :01/11/07 16:32
家のパソコンで宿題してるのでlinuxです

281 名前:デフォルトの名無しさん :01/11/07 16:32
>>278
1000000000 とか書いても、それは「int 型の定数」だから。整数の型を明示したければ、適切な
サフィックスを付けないとダメ。

>>280
で、CPU は Alpha なんですか?

282 名前:デフォルトの名無しさん :01/11/07 16:38
すいませんペンティアム3です

283 名前:デフォルトの名無しさん :01/11/07 16:42
>>282
x86 アーキテクチャの Linux だと、int 32bit, long 32bit, long long 64bit ですね。gcc では long long 型の
整数定数は、サフィックス LL をつけることになっています。

long long int a=10000000000LL;

これで試してみてください。

284 名前:デフォルトの名無しさん :01/11/07 22:20
>>266
igoire : アイゴイレ tolower : トゥロワー boolalpha : ブーラルファ
全部てきとー・・・

285 名前:デフォルトの名無しさん :01/11/09 21:45
string型とwstring型の相互変換のやり方を教えてください〜。

286 名前:デフォルトの名無しさん :01/11/09 21:49
>>285
どういう相互変換よ? 文字コード含めた変換はプラットフォーム
依存のAPIかライブラリつかえや

287 名前:デフォルトの名無しさん :01/11/09 23:07
>>285
mbstowcs, wcstombs

288 名前:デフォルトの名無しさん :01/11/10 10:41
「C++実践プログラミング」って本持ってる人います?
面白いかどうか聞きたいのですが。

289 名前:名無しさん@Emacs :01/11/10 11:01
>>288
オライリーのやつ?あれは「面白い」かどーかだったら「面白くない」と思うよ,漏れは.
Effective C++ とかの方が面白いと思うけど.
まぁ悪くは無いけどね.

290 名前:デフォルトの名無しさん :01/11/10 11:38
Exceptional C++はおもしろいよ

291 名前:デフォルトの名無しさん :01/11/10 11:59
>>289
そっか。ありがと。
Effective C++はとっくに読んでるので、
とりあえず、Exceptional C++読むことにするよ。

292 名前:デフォルトの名無しさん :01/11/10 18:40
>>287
seylocaleを忘れるとハマるよね‥‥

293 名前:デフォルトの名無しさん :01/11/10 23:05
継承を制限するJavaでいうclass修飾子finalと同じ働きをするものはありますか?

294 名前:290 :01/11/10 23:09
>>291
読んだら感想書いてね

295 名前:デフォルトの名無しさん :01/11/10 23:32
>>293
無い.
C++ Gems あたりで
/* final */ とコメント入れてるのを見たことがある.
ドキュメネトでやるしか無いってことね.

296 名前:293 :01/11/10 23:36
>>295
了解、さんくすです。

297 名前:デフォルトの名無しさん :01/11/10 23:48
privateで継承して、元publicメソッドをpublicで全部くくり直す……駄目か

298 名前:デフォルトの名無しさん :01/11/11 08:32

周波数を指定してスピーカーから音を出そうとして、
Web上でサンプルを検索したところ、
http://www.thevine.net/~hopkins/seth_cpp.html
のようなページを見つけ、早速コンパイルしてみました。
ですが、「未定義の関数soud」というコンパイルエラーがでてしまいます。
dos.hのファイルをみたところ、soundなどの関数はありませんでした。
サンプルではBorland C++ 4.xを使っているようですが、
これより上のバージョンでサポートしなくなるということはあるのでしょうか。

また、周波数を指定して、音を出すために、他に簡単な方法はありますでしょうか。

以下、HP上のサンプルコードです。
#include <stdio.h>
#include <dos.h>

void main() {

int x;

printf("\n\n Are we having fun yet? \n\n");
for (x=50; x<2000; x++) {

sound(x);
delay(3);

}
nosound();

}

299 名前:デフォルトの名無しさん :01/11/11 12:42
関数の定義でconstを使いたいのですが、
何かいい本ないでしょうか?

300 名前:デフォルトの名無しさん :01/11/11 14:04
>>299 const使って何をするのかわからないと答えようがない。
とりあえずプログラミング言語C++読んでから聞け

301 名前:名無しさん :01/11/11 14:17
入力で
N01 68 56
N02 74 79
N03 39 56
出力で
N01 68 56 144
N02 74 79 153
N03 39 56 95
としたいんです。
で、宣言を int n [3];
として   while (k<=3)
z=x+y
k=k+1
としてみたんっすけどうまくいきません。
助言ください。
当方殆ど初心者です。 

302 名前:デフォルトの名無しさん :01/11/11 14:31
何がどううまくいかないのか書きなさい。

わかりやすくいうとだな、
どういうメッセージが表示されたか書きなさい。
どういうプログラムを書いたのか書きなさい。

だ。

303 名前:デフォルトの名無しさん :01/11/11 14:32
>>301
何がどううまくいかないの

304 名前:デフォルトの名無しさん :01/11/11 14:33
Winプログラマです。誰か教えてください
VC++で以下のようなインターフェースのDLLを作りました

#include <vector>
using namespace std;

__declspec(dllexport) void WINAPI Foo(vector<string>& arg)
{
arg.pushback("AAA");
}

これを他のC++コンパイラ(C++Buiilderとか)でビルドしたEXEから
上記DLLのエクスポート関数を正常に処理することは可能でしょうか?
試してみたところ、上記関数を実行した時点でGPFが起こります。
コンパイラによって当然vectorの実装方式が違うため、
無理な気がするのですが気のせいでしょうか...
板違いかもしれませんが、宜しくお願いします

305 名前:デフォルトの名無しさん :01/11/11 14:37
おまえは医者に、


調子が悪いんです。
いつもは朝起きてご飯食べて学校に行ってるんですが、
調子が悪いんです。

なんて説明するのか?

306 名前:デフォルトの名無しさん :01/11/11 14:40
他のコンパイラとC++そのもので協調するのは名前の問題や
ヒープ管理の問題もあるから、あなたの言うとおり、絶望的。
というかC++のクラスをdllexportするのは、たとえ同じコンパイラ
であてもちと気持ち悪い。

安直にはCのみになるのかな。当然vectorとか使えない。
がんばりたければCOMだろうけど・・・疲れるよ

307 名前:デフォルトの名無しさん :01/11/11 14:49
COMはべつに疲れるもんでもないがなー

308 名前:デフォルトの名無しさん :01/11/11 14:51
>>306
レス有難うございました。
やっぱり、そうですね。本当にバイナリレベルの互換
を望むならCOMでしょうが・・・確かに疲れますしねぇ

309 名前:デフォルトの名無しさん :01/11/15 04:24
mage

310 名前:デフォルトの名無しさん :01/11/15 10:06
例外安全、例外中立とはなんですか?

311 名前:デフォルトの名無しさん :01/11/15 21:43
コピペコンストラクタ

312 名前:デフォルトの名無しさん :01/11/15 21:47
>>252-257

313 名前:310 :01/11/16 09:25
>>312
ありがと

314 名前:デフォルトの名無しさん :01/11/16 16:26
クラス階層を表示したりメンバをスーパークラスまでたどって
表示できるツールってVC以外で無い?

コマンドラインアプリでも良いんだけど・・・

315 名前:名無しさん :01/11/16 19:01
>>314
td32ってできるんじゃない [View|Hierarchy]

316 名前:デフォルトの名無しさん :01/11/16 21:50
>>315
ありがとう
Turbo Debuggerはできるんだね
でもあれってユーザ登録が必要でしょ?それってちとイヤンな感じ

317 名前:デフォルトの名無しさん :01/11/16 22:28
>>316
たまにメールが来るだけだから気にするこたぁない
それも嫌ならすぐ登録解除でもすれば?

318 名前:デフォルトの名無しさん :01/11/16 23:07
>>317
そうだね試してみようかな

でもよさそうなの見つけたよ
フリーだしオープンソースらしい
SourceNavigator
http://sources.redhat.com/sourcenav/

まだちょっとしか使ってないけどGUIがTkなんで遅いし
不安定っぽいが機能はかなりいけてる

319 名前:ルビ厨な入 :01/11/18 10:10
C++なんか相手にしてませんが。

320 名前:デフォルトの名無しさん :01/11/18 19:07
doxygenってどうですか?

321 名前:デフォルトの名無しさん :01/11/18 22:18
'/0'ってのはNULLって意味でしょうか?
char a='/0';
とするのと
char a;
*a=0;
とするのは同じ事となる?

322 名前:デフォルトの名無しさん :01/11/18 22:23
unko

323 名前:デフォルトの名無しさん :01/11/18 22:28
>>321
まず /0 (スラッシュゼロ)ではなく \0 (バックスラッシュゼロ)。
NULL ではなくヌル文字といい、文字配列の終端を表す。
規格上 char ポインタの文脈で使われる 0 はヌル文字に変換されることになっている。

324 名前:デフォルトの名無しさん :01/11/18 22:33
>>321
それじゃ意味が全然違うというかコンパイルとおらないんじゃ?
char a='\0';

char a;
char *p = &a;
*p = '\0';
なら同じことです。

'\0'とNULLは違うものです。
'\0'はキャラクタコードでNULLはポインタ。

325 名前:デフォルトの名無しさん :01/11/18 22:38
>>323
> 規格上 char ポインタの文脈で使われる 0 はヌル文字に変換されることになっている。
「char ポインタ」じゃなくて「char」の間違いだよね。

326 名前:デフォルトの名無しさん :01/11/18 22:44
>>325
フォローサンクス。書いてから気付いた。
char ポインタの文脈だとメモリ壊れるね(笑

327 名前:日本@名無史さん :01/11/18 22:51
>>323
> NULL ではなくヌル文字といい、文字配列の終端を表す。
「文字配列」じゃなくて「文字列」の間違いだよね。

328 名前:デフォルトの名無しさん :01/11/18 22:55
>>321
実際問題として
'\0'とNULLはどっちも 0 だから混同してもコンパイルできたり
正常に動いたりはする。
でも処理系によってはトラブルの元になるからちゃんと区別して
使わないとダメ。

329 名前:デフォルトの名無しさん :01/11/18 23:02
>>328
処理系依存だからというのも理由の一つだが、ソースコードを読んで

 ポインタなのか
 文字型なのか
 それとも整数の 0 なのか

が一発で分かるので、読みやすくなるというのも少なからぬメリット。もっとも C++ だと

#define NULL 0

って処理系がほとんどだが、その場合 foo(NULL) で foo(int) が呼ばれる点だけは注意が必要。

330 名前:321 :01/11/18 23:22
char a='\0';
とするのと
char a;
&a=0;
ですね、すいません

で結論としては
char a='\0';

char a=0;
が同じなんですね

331 名前:デフォルトの名無しさん :01/11/18 23:30
>>330
前者はやってることが違う。
a = '\0'はaに値を代入している。
&a = 0; はaのアドレスを0で上書きしている。こんなことはしてはいけない。

後者はまぁオッケー。

332 名前:デフォルトの名無しさん :01/11/18 23:42
NULLはC++じゃないだろ。Cスレへ逝け

333 名前:デフォルトの名無しさん :01/11/18 23:45
>>332
size_t は?

334 名前:デフォルトの名無しさん :01/11/18 23:52
>>332
そういうときには、論拠も示してくれると助かるんだが。

335 名前:デフォルトの名無しさん :01/11/19 00:09
>>334
人に聞く前に
http://www.kuzbass.ru/docs/isocpp/
の全ページを見てNULLについての記述があるかないか目を皿のようにしてしらべましょう

336 名前:デフォルトの名無しさん :01/11/19 00:13
>>335
手元には ISO C++ の規格書がありますが、これには 18.1 で NULL は C++ null pointer constant だと
明記してありますな。

337 名前:デフォルトの名無しさん :01/11/19 00:19
世渡り上手になりましょう>>335
オタッキーなデブになってはいけません

338 名前:オタッキーなデブ :01/11/19 01:34
while (NULL == (void*)0);

339 名前:デフォルトの名無しさん :01/11/19 02:09
>>338
ネタは sage てな。

それとも NULL の定義や、整数型とポインタ型の比較についてディープに語りたい?

340 名前:デフォルトの名無しさん :01/11/19 02:31
CとC++におけるvoid *の違いについてディープな議論キボンヌ。

341 名前:デフォルトの名無しさん :01/11/19 02:32
>>339
ディープに語れるのですかッ?

342 名前:デフォルトの名無しさん :01/11/19 04:30
独習C++読んだけどムズイ・・・

343 名前:デフォルトの名無しさん :01/11/19 09:49
NULL が __null とか定義されてて 0 と違った特別扱いになってるコンパイラはないのかしらん。
__null は何型のヌルポインタにもなるけど整数には変換できないみたいな。
規格違反?

344 名前:デフォルトの名無しさん :01/11/19 09:49
NULL が __null とか定義されてて 0 と違った特別扱いになってるコンパイラはないのかしらん。
__null は何型のヌルポインタにもなるけど整数には変換できないみたいな。

345 名前:デフォルトの名無しさん :01/11/19 10:23
gccは__nullなんてのを導入してるよ。

346 名前:デフォルトの名無しさん :01/11/19 22:22
18.1 - Types [lib.support.types]

-4- The macro NULL is an implementation-defined C++ null pointer constant in this International Standard (conv.ptr).*

[Footnote: Possible definitions include 0 and 0L, but not (void*)0. --- end foonote]

NULLはnull pointer定数なんだねえ。

347 名前:デフォルトの名無しさん :01/11/19 22:42
>>346
念のため、キーワードではなく単なるマクロなのでよろしく。

348 名前:デフォルトの名無しさん :01/11/19 23:23
>>346
ISOで定義されているというのはデカいな。

349 名前:デフォルトの名無しさん :01/11/19 23:42
イソイソイソ

350 名前:デフォルトの名無しさん :01/11/21 01:53
VC++6.0 sp5でstlport4.5使用してるんですが、
int WINAPI WinMain(...)
{
 std::string str("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
}
コレだけのプログラムで、BoundsCheckerが4800バイトのメモリリークを検出します。
他の方はどうですか?
ビルドに失敗したんじゃないかと心配です

351 名前:デフォルトの名無しさん :01/11/21 02:05
>>350
漏れのところもそうなるよ。
stringの数だけリークしてるわけじゃないから、メモリプールじゃないか?
無視して問題ないと思うが、他人の回答も欲しいからage

352 名前:デフォルトの名無しさん :01/11/21 02:51
>>350
かなりがいしゅつ。リークではない。
ロケールだかなんだかのために、STLportが
最初の一回だけ確保するメモリだ。

厳密に言えばboundscheckerの言うとおりリークだが、
深刻なリークではない。

プロセスが終了すれば解放されるので気にしないでよい。

353 名前:デフォルトの名無しさん :01/11/21 03:24
>>352
確かに既出だが、細かい話はこのスレじゃなくて STL スレでやってた気がする。

354 名前:デフォルトの名無しさん :01/11/21 05:06
タイマーを作りたい!たとえば5秒の待ち時間をつくるとか。
簡単にできますかね?

355 名前:デフォルトの名無しさん :01/11/21 05:10
>>354
精度にもよるがおおむね処理系依存。

356 名前:デフォルトの名無しさん :01/11/21 05:29
仮想関数ってJavaのインターフェースと一緒だと思って良いのかな?

357 名前:デフォルトの名無しさん :01/11/21 09:10
>>356
仮想関数=Javaのすべてのメソッド
C++の非仮想関数に相当する物はJavaに無いよ

358 名前:デフォルトの名無しさん :01/11/21 13:23
>>356-357
あえて挙げれば final か?
微妙に違うけど。

359 名前:デフォルトの名無しさん :01/11/21 14:12
Exceptional C++ とか、C++ FAQ とかをみると、operator= で
明示的にデストラクタを呼ぶときに、そのクラスが X だとすると、

this->~X();

って書いてある。this-> っているだろうか?

360 名前:デフォルトの名無しさん :01/11/21 15:01
要らないと思う。

361 名前:デフォルトの名無しさん :01/11/21 18:30
Exceptional C++ とかのコードは C++ のエキスパートの
目にふれているはずなのだけど、やはり this-> はただの
飾りなのかな?

非 virtual なメソッドから virtual なメソッドを呼び
出していることを明示してるだけの気はするが、何か深遠
な理由があるのではないかと勘ぐってみたり。

362 名前:デフォルトの名無しさん :01/11/21 20:04
@
 throw new classA
 で
 catch(classA* a)
 ってうけとるのと
A
 throw classA
 で
 catch(classA &a)
 ってうけとるのと

なにがどうちがうの
@はdelet aするけど
Aはしなくていいの?

363 名前:デフォルトの名無しさん :01/11/21 20:16
そぉいうことです。

364 名前:デフォルトの名無しさん :01/11/21 20:26
>>363
そしたらAのほうがぜったいつかいやすいとおもうんだけど
どーして@のようなそーすがおおいの?

365 名前:デフォルトの名無しさん :01/11/21 20:29
>>364
多いか? MFC は過去のしがらみがあるので catch (CException*) だが、それ以外で例外を
new で投げてるのは、私の周囲では見ないよ。

366 名前:デフォルトの名無しさん :01/11/21 21:36
小心者なのでnewい失敗するのが怖い :−<

367 名前:デフォルトの名無しさん :01/11/21 21:51
>>365
そーなんだ ありがとー
それで、もひとつしつもんだんだけど
AでthrowしたclassAはどのじてんできえてなくなるの?
catchしたばしょでまたthrowしたかったとき?

368 名前:デフォルトの名無しさん :01/11/21 21:53
>>367
まちがえた!
catchしたばしょでまたthrowしたかったとき?
   ↓
catchしたばしょでまたthrowしなかったとき?

369 名前:デフォルトの名無しさん :01/11/21 22:21
>>368
オブジェクトはスコープの終わりで解体される

370 名前:デフォルトの名無しさん :01/11/21 22:56
推薦図書スレに逝ったのですが荒れまくっていて話しにならなかったのでここで質問させてください。
STLを勉強したいのですが、お勧めの本はありますでしょうか?

371 名前:デフォルトの名無しさん :01/11/21 23:14
throw classA;
の時点で生成されたインスタンスを仮に a とする。
a はコピーコンストラクタで一時的にコピーされる(bとする)。
throw 文が実行終了したので a は破棄される。

catch に突入。
ここで受け取る方法が参照の場合は、b を参照する。
参照でなければ、もっかいコピーコンストラクトされる。
catch 終了時点で b は破棄される。

って感じだと、勝手に思ってます。規格を調べたわけではない。

372 名前:デフォルトの名無しさん :01/11/21 23:20
>>370
C++標準ライブラリについて知りたいならプログラミング言語C++を。
STLに限るなら「標準テンプレートライブラリによるC++プログラミング」あたり?

373 名前:デフォルトの名無しさん :01/11/21 23:23
>>370
すでに移転済み。

推薦図書/必読書のためのスレッド in プログラム板
http://pc.2ch.net/test/read.cgi/tech/1005897052/

374 名前:デフォルトの名無しさん :01/11/21 23:56
>>371
くわしいせつめいありがとー
じゃあまたまたしつもんだけど
classA;
がもし
int i[10000];
ってゆーくらすへんすう?をもってたら
やっぱり@のほうがいいのかなー??

375 名前:デフォルトの名無しさん :01/11/22 00:04
>>374
int i[10000];
ってゆーくらすへんすう?をもってたら
 ↓
すごーくいっぱいめもりつかってるからもったいないとか、
こぴーにじかんかかるとか
そーゆーいみです
わかりずらい?

376 名前:デフォルトの名無しさん :01/11/22 00:09
>>374
読みにくすぎ。漢字を少しは使おう。

漢字を使いたくなければ単語の間を適当にスペースで区切るか、英語で書いてくれ。

377 名前:デフォルトの名無しさん :01/11/22 00:19
>>376
御免なさい

378 名前:デフォルトの名無しさん :01/11/22 00:43
>>371
例外発生時にコピーコンストラクタが呼ばれるなんて聞いたこと無いが?

379 名前:デフォルトの名無しさん :01/11/22 01:08
漢字使って書き直してみました。
>throw classA;
>の時点で生成されたインスタンスを仮に a とする。
>a はコピーコンストラクタで一時的にコピーされる(bとする)。
>throw 文が実行終了したので a は破棄される。

classA がもし
int i[10000] あるいはもっと大きいクラス変数?を持っていた場合
一時的にコピーされる際の、時間・メモリ大きさのことを考えると
やはり@のようにポインタを投げる方が良いのでしょうか??

話しはそれますが(コピーコンストラクタもよく知りません)
コピーコンストラクタでコピーされる内容は
仮に classA が持っているクラス変数?がポインタの場合、
コピーされるのはそのポインタのみでしょうか?
下記の *a の値は、どうなるのでしょうか?

class classA{
  intr* p;
  classA(){
    p = new int;
    *p = 10;
  }
  ~classA{
    delete p;
  }
}
これを throw classA した場合
catch(classA &a) で受け取った
a の持つ *p の値は保証される(この場合値は10になるのか)のでしょうか?

380 名前:デフォルトの名無しさん :01/11/22 01:09
まちがえた!!
下記の *a の値は、どうなるのでしょうか?
  ↓
下記の *p の値は、どうなるのでしょうか?

381 名前:デフォルトの名無しさん :01/11/22 01:10
実験してみたよ。
VC++ だと、catchが参照なら、コピーコンストラクタ呼ばれない。
catchが実体なら、コピーコンストラクタ呼ばれる。

C++Builder だと、catchが参照なら、コピーコンストラクタが1回呼ばれる。
catchが実体なら、コピーコンストラクタが2回呼ばれる。

gccは試してない。

テストコードはこんな感じ↓
#include <stdio.h>
class A{
public:
 A(){ printf("constructor %p\n", this); }
 A(A&){ printf("copy constructor %p\n", this); }
 ~A(){ printf("destructor %p\n", this); }
};
void f()
{
 throw A();
}
int main()
{
 try{
  f();
 }catch(A a){
 }
 return 0;
}

382 名前:デフォルトの名無しさん :01/11/22 01:16
>>379-380
というわけで、保証されません。
上手く動くこともあるけど、上手く動かないこともある。
潜在的なバグですな。

コピーコンストラクタを書くべき。
ついでに代入演算子も書くべき。

このように↓
class classA{
  intr* p;
  classA(){
    p = new int;
    *p = 10;
  }
  classA(const classA& a){
    p = new int;
    *p = *a.p;
  }
  ~classA{
    delete p;
  }
  classA& operator=(const classA& a){
    *p = *a.p;
    return *this;
  }
}

383 名前:デフォルトの名無しさん :01/11/22 01:32
>C++Builder だと、catchが参照なら、コピーコンストラクタが1回呼ばれる

だとしたら型が変わる可能性があるぞ?

class a {};
class b : public a {}
void f(){
try {
throw b();
}
catch( a aa ){
aa は b ニアラスズ
}
}

384 名前:デフォルトの名無しさん :01/11/22 01:41
>>383
それ terminate() されないか?

385 名前:デフォルトの名無しさん :01/11/22 01:49
実験した。
一度 b のコピーコンストラクタでコピーされたあと、
a に変換されて catch が実行される。

たぶん throw b(); の b() で生成した一時オブジェクトは、
throw 文の終了時点で消滅する理屈なのかなぁと。
コピーして取っておかないと、元のオブジェクトは消滅して
catch ブロックで使えない。

386 名前:デフォルトの名無しさん :01/11/22 01:56
>>382
なるほどー

とっても勉強になりました。
ありがとうございました。

387 名前:デフォルトの名無しさん :01/11/22 02:09
>>383 さんのをみてると、またわかんなくなってきました。

>>382 の classA を 継承する classB を throw し、
catch(classA &a) や catch(classB &b) できるようにする場合の
classB はどう書けばいいんだろう???
classA と同じようにコピーコンストラクタと代入演算子も書くべきなのかなー??

寝ながら考えてみます。

388 名前:383 :01/11/22 02:18
382については「コピーコンストラクタと代入演算子」の問題
383については「スライス」の問題で
別件です。

389 名前:デフォルトの名無しさん :01/11/22 07:57
コピーコンストラクタや代入演算子は、
基本的に多くの場合、書くべきだと思うけど?

書かなくても自動生成されるけど、これはC++の罠だし。

390 名前:デフォルトの名無しさん :01/11/22 12:42
>>341
NULL の話は、結局、こっちで盛り上がりました(数日前から狙ってたんだが、人が集まったのが
向こうだったので)

http://pc.2ch.net/test/read.cgi/tech/982758107/774-875

しかし

- C++ の標準規格で NULL が null pointer constant と規定されている
- その値は整数型で 0 と等しい (0, 0L など)
 したがって #define NULL ((void*)0) は規格違反

ということを知らない人が、わりと多かった気がする。

391 名前:デフォルトの名無しさん :01/11/22 12:47
throwはreturnと同じような意味を持っていると理解しているが
どうでしょう。
例外の説明でスタックの巻き戻しとか出てくるけど
return文だって同じことするのになぜだろう。

392 名前:デフォルトの名無しさん :01/11/22 12:50
>>391
return は呼び出しもとの関数に戻るけど、throw は catch されるまで一気に戻るのが違い。
throw は C なら return よりも setjmp, longjmp に近いと思われ。

393 名前:デフォルトの名無しさん :01/11/22 12:56
>>391
たとえばこんな感じかな。
void f1()
{
 try{
  f2();
 }catch(...){
 }
}
void f2()
{
 f3();
}
void f3()
{
 f4();
}
void f4()
{
 throw 0;
}
どこまで戻るかが違う。

394 名前:デフォルトの名無しさん :01/11/22 18:31
>>372
プログラミング言語C++買ってきました
7000円は痛い・・・

395 名前:デフォルトの名無しさん :01/11/22 19:07
>>394
今後3年は使えると考えて、1年に2000円なら安いもんだ

396 名前:デフォルトの名無しさん :01/11/22 23:55
>>393
おおなるほど。
ってreturnでも一緒じゃん!

397 名前:デフォルトの名無しさん :01/11/23 00:21
393じゃないけど。

>>396
>ってreturnでも一緒じゃん!

違うよ。もっと考えてみて。実行してみるのが一番だよ。
もし良かったら、今後の参考のために「一緒」と思った理由を教えて。

398 名前:デフォルトの名無しさん :01/11/23 00:36
どうでもいいけど>>393のソースなら一緒だっていみだろ。

399 名前:デフォルトの名無しさん :01/11/23 00:46
内部定義したいょ

400 名前:デフォルトの名無しさん :01/11/23 04:51
仮想関数を何度か呼び出すのですが、インスタンスは変化しないので、
2回目以降はvftableのようなものを経由しないで呼び出したいのですが、
どうすればよいでしょうか?

401 名前:デフォルトの名無しさん :01/11/23 05:56
何のためにそういった手の込んだことをするのですか? >>400

402 名前:デフォルトの名無しさん :01/11/23 06:08
多分vtblのオーバーヘッドが〜とかいいたいのでしょう

403 名前:400 :01/11/23 06:25
>>401
>>402さんがいうとおりです。

404 名前:401 :01/11/23 06:28
では。仮想関数を呼び出すニーモニックは
ほぼ call [vtable+n] です。

さて、インスタンスが変化しないのでそれを経由せずに
自分でポインタで関数を管理したとします。でも
インスタンスは当然一つではないので、それぞれの
インスタンスにポインタが必要です。
コレを呼び出す手間は最小で call [footable+pointeraddress] です。
言語側の仮想関数と自前のポインタ処理は同じような機械語になります。

よって呼び出しを自前で処理してもあまり意味がないと思うのですが。
そうでもないのかな?

405 名前:デフォルトの名無しさん :01/11/23 09:43
>>400
1 仮想関数にするのをやめる。仮想関数でなければ、オブジェクトのクラス名とメソッド名から、
 呼び出すコードが一意に決まりますから vtbl 引きませんし、うまくいけばインライン化できま
 す。コンパイル時に型が確定するのであれば、template を使う手もあります。
2 メンバ関数へのポインタを使う。

ただ、ほんとうにボトルネックはそこですか? 細工を始める前に本当に仮想関数呼び出しが
オーバーヘッドになっているのか、プロファイラを使って計測した方が良いです。細かい工夫で
数サイクル稼ぐより、アルゴリズムを工夫してメソッド呼び出し回数のオーダーを下げた方が
遥かに効果的です。

406 名前:デフォルトの名無しさん :01/11/23 13:35
>>405
メンバ関数へのポインタではオーバーヘッドなくならないんじゃない?
あと、正直プロファイラがどんなものなのか分からない。

407 名前:デフォルトの名無しさん :01/11/23 13:40
おいおい

パフォーマンスを気にするなら、プロファイラがどんなものか
理解しておくべきだ。

プログラムを実際に動かしてみて、
どの関数が何回呼ばれたとか、
どの関数で何ミリ秒時間がかかったとか、
そういう様々な実行時の情報を計測してくれるツール
のことだよ。

小手先最適化の前に
まず、こっちを先に調べなさい。

408 名前:400 :01/11/23 13:49
どうもありがとうです。

>>404
VC++のはいたコードを見てみたのですが、
たしかにそういう呼び出し方をしていますね。

>>405
>2 メンバ関数へのポインタを使う。

>>404さんの
>言語側の仮想関数と自前のポインタ処理は同じような機械語になります。
と同じですよね?

>数サイクル稼ぐより、アルゴリズムを工夫してメソッド呼び出し回数のオーダーを下げた方が
>遥かに効果的です
にしたいのですが、もともと仮想関数を使う理由は
あるコンテナ群に対する処理をひとつのソースで済ませたいからなのですが、
コンテナのインタフェースに対して処理しているので、
どうしてもvirtual invokeが発生するのです。
やはり、この場合はコンテナにアルゴリズムを持たせるのが一番でしょうかね・・・。

409 名前:デフォルトの名無しさん :01/11/23 14:29
>382
classBが下記のような場合はコピーコンストラクタいるの?
classA を継承しているし、いらないかなー
なんて思ってしまうのですが・・・
(わけわかんない事いってたらごめんなさい)

classB
throw classB;
して
carch(classB &b){
}
で受け取ると


class classB : public classA {
  int q;
  classB(){
   q = 20;
  }
  ~classB{} 
}

class classA{
public:
  int* p;
  classA(){
    p = new int;
    *p = 10;
  }
  classA(const classA& a){
    p = new int;
    *p = *a.p;
  }
  ~classA{
    delete p;
  } 
  classA& operator=(const classA& a){
    *p = *a.p;
    return *this;
  }
}

410 名前:デフォルトの名無しさん :01/11/23 16:50
class container_base
{
public:
virtual void each() = 0;
};

class container1 : public container_base
{
public:
virtual void each() { }
};

class container2 : public container_base
{
public:
virtual void each() { }
};

//ひとつのソース
template <typename Container>
void general_test(container_base* pBase)
{
Container* pCont = dynamic_cast<Container*>(pBase);

for (int i = 0; i < 10000; i++)
pCont->Container::each();// no virutal call
}

container_base* pCont = new container1;
general_test<container1>(pCont);

仮想関数を非仮想呼び出しするには、明示的限定以外ないので(関数ポインタによる呼び出しも仮想呼び出し)、
こんな感じですがあまり役に立ちそうにない。

411 名前:デフォルトの名無しさん :01/11/23 18:43
A:すべてのクラスの基底クラス
A1,A2:Aから派生したクラス
X:A1,A2を多重継承したクラス
としてAのポインタをXのポインタにキャストしたいのですが
どうすればよいでしょうか

#BCCでエラー('A *' から 'X *' へのキャストはできない)
class A {};
class A1 : virtual A {};
class A2 : virtual A {};
class X : A1, A2 {};
main() { A *pa; X *px = (X *)pa; }

412 名前:デフォルトの名無しさん :01/11/23 19:06
>>411
何のためにそんなコトしたいのか知らんが、できないものはできない。

413 名前:デフォルトの名無しさん :01/11/23 19:09
>>411
X* から A* ではなく、逆なのか? やってやれないことはないが、設計が腐ってるとしか思えん。

414 名前:デフォルトの名無しさん :01/11/23 19:09
>>411
Aが仮想関数もってないからじゃないの?
class A {virtual void virtual_method(){}};
class A1 : A {};
class A2 : A {};
class X : A1, A2 {};
main() { A *pa; X *px = dynamic_cast<X *>(pa);}

ところで、class A1 : virtual A {}; での
「virtual」の意味を教えてちょ。どんなときに使うの?

415 名前:デフォルトの名無しさん :01/11/23 19:13
>>414
仮想継承は菱形継承するときに使う。この場合だと、仮想継承しないと X オブジェクトの内部には
A オブジェクトが二つ含まれることになるが、仮想継承すると A オブジェクトが一つしか含まれな
くなる。

プログラミング言語 C++ に図入りで解説があるから、読んでみ。

416 名前:414 :01/11/23 19:21
>>415
おお、さんくす。
プログラミング言語 C++買ってこよ。

417 名前:デフォルトの名無しさん :01/11/23 19:51
7000円の壁にくじけ、本屋で膝を崩す414の画像をキボンヌ、と

418 名前:デフォルトの名無しさん :01/11/23 19:54
万引きしようとして不自然に服がふくらんで店員に捕まっている414の画像をキボンヌ

419 名前:デフォルトの名無しさん :01/11/23 19:59
gotoのかわりにtry catch使う人多い?

420 名前:デフォルトの名無しさん :01/11/23 20:00
break一発じゃぬけだせない深いループから抜け出すときに

421 名前:デフォルトの名無しさん :01/11/23 20:01
414キボンヌ

422 名前:417 :01/11/23 20:02
膝を崩すって変だな、本屋でくつろいでどうするよ。逝ってこよう…
ただtry catchはやはり例外発生時にのみ使うべきだと思うのであります。

423 名前:仕様書無しさん :01/11/23 20:24
7000円の壁にくじけ、座り読みを始めて、隣で立ち読みしているょぅι゛ょの
スカートの中を覗き見しようとしている414の画像をキボンヌ

424 名前:デフォルトの名無しさん :01/11/23 20:49
>>419
俺は goto 使う場面では goto 使う。

425 名前:411 :01/11/23 21:19
>>411-413
Aを基底クラスとした様々な派生クラスをリスト化
その要素にアクセスするためのイテレーターをA*

X以降の派生クラスであることがわかっている要素(一応typeidで確認して)で
Xのメソッドを使用したいときにA*→X*のキャストが必要となりました。

多重継承させずに設計すべきだったんでしょうかね。
できないなら仕方ありませんが、
やれないことはないとは、どのようなことか教えてくださいませんか?

426 名前:デフォルトの名無しさん :01/11/23 21:31
>>425
> X以降の派生クラスであることがわかっている要素(一応typeidで確認して)で
> Xのメソッドを使用したいときにA*→X*のキャストが必要となりました。
X の派生クラスであることが分かっているのなら X* のまま渡すべきであって、途中で A* に落としてしまう
設計がイマイチでしょう。

基底クラスを扱う側で本当に「その X 固有のメソッド」を参照する必要があるのなら、そのメソッドを A に移
して仮想メソッドにするべき。A では純粋仮想メソッドにして派生クラスで実装させるか、もしくは適当なデフォ
ルト値を返すようなメソッドを定義しておく。

> やれないことはないとは、どのようなことか教えてくださいませんか?
dynamic_cast です。

427 名前:425 :01/11/23 22:21
>>426
なるほど。色々と説明ありがとうございます。
dynamic_cast を使う場合は >>414 のようにするのですね。
レスくださった方に感謝します。
設計から再考してみようと思います。

428 名前:デフォルトの名無しさん :01/11/24 13:29
C++自体の話とはずれるかも知れませんが、ちょっとしたプログラムを書いて

1. VC++(ver6)
2. g++(2.96, Kondara MNU/Linux 2.0)
3. g++(cygwin2.95.3-5, WIN2K)

でコンパイルしたのですが、1,2ではコンパイルが通って(警告もなし)
3ではどばっとエラーが出ます。エラーの内容は最初に

class my_itr : public iterator<bidirectional_iterator_tag, my_type>{

と書いた行で parse error before `<' と出た以後、
何かがずれたようにsyntax errorやundeclaredといったエラーが延々と出ます。
こんな経験のある方いませんか?
cygwinメインで書いてるのでホトホト困ってます。

429 名前:デフォルトの名無しさん :01/11/24 13:31
>>428

絶対ソースのせた方が早く解決すると思う。

430 名前:デフォルトの名無しさん :01/11/24 13:36
ほんとだ、とーらないね。

431 名前:428 :01/11/24 13:47
ソース200行ほどになるのですが、ここに張っつけて可能でしょうか。

432 名前:428 :01/11/24 14:05
とりあえず80行程度になりました。
g++ -c
で試してみると >>428 のようになります。
2回にわけます。

---以下ファイル ---
#include <list>
#include <map>
#include <iostream>
using namespace std;
typedef unsigned long ulong;

template<typename VRTX,typename EDGE>
class _graph{
public:
 class _vwrap;
 class _ewrap;
 class _vrtx_itr;

 // 頂点リストの型
 class _vlist : public list<_vwrap*>{
 public:
  list<_vwrap*>::iterator operator[](const ulong& i){
   if(i>=size()){
    cerr << "ERROR: Index out of range" << endl;
    exit(1);
   }
   list<_vwrap*>::iterator itr = begin();
   advance(itr,i);
   return itr;
  }
 };
 typedef _vlist::iterator _vlist_itr;

 // エッジリスト型
 typedef list<_ewrap*> _elist;
 typedef _elist::iterator _elist_itr;

 // 結合マップのソートの基準
 struct _less_vlist_itr :
  binary_function<_vlist_itr,_vlist_itr,bool>{
  bool operator()(const _vlist_itr& v0,const _vlist_itr& v1) const{
   return *v0<*v1;
  }
 };

 // 結合マップ<結合先頂点,対応エッジ>
 typedef map<_vlist_itr,_elist_itr,_less_vlist_itr> _amap;
 typedef _amap::iterator _amap_itr;

433 名前:428 :01/11/24 14:05
 // 頂点のラッパ
 class _vwrap{
  friend _graph;
  friend _vrtx_itr;
 private:
  VRTX vrtx; // 頂点本体
  _amap amap; // 結合マップ
  _vwrap(){}
  _vwrap(const VRTX& v) : vrtx(v){}
 };

 // エッジのラッパ
 class _ewrap{
 private:
  EDGE edge;     // エッジ本体
  _vlist_itr vrtx[2]; // 両端点の頂点
 };

 // 頂点の内容(VRTX)にアクセスするための反復子
 class _vrtx_itr : public iterator<bidirectional_iterator_tag,_vwrap*>{
  friend _graph;
 private:
  _vlist_itr itr;
 public:
  _vrtx_itr(void){}
  _vrtx_itr(_vlist_itr v) : itr(v){}
  _vrtx_itr(_amap_itr a) : itr(a->first){}
  VRTX& operator*(){ return (*itr)->vrtx; }
  VRTX* operator->(){ return &(*itr)->vrtx; }
  _vrtx_itr& operator++(){ ++itr; return *this; }
  _vrtx_itr& operator--(){ --itr; return *this; }
 };

private:
 _vlist vlist; // 頂点リスト
 _elist elist; // エッジリスト

public:
 _graph(void){}
 ~_graph(){}
};

434 名前:428 :01/11/24 14:08
あ、もしコンパイルを試してくださるなら
全角のスペースを使ってるので注意です。

435 名前:デフォルトの名無しさん :01/11/24 14:21
std::のつけわすれじゃなくって?

436 名前:428 :01/11/24 14:48
なんだか不必要な部分も貼っつけたみたいで煩雑になってすみません。
std::は4行目で宣言してるので問題ないと思います。

それといまSUNのSPARC(gcc2.95.1)でも試してみました。
結果・・・通りませんでした。
ん〜。gccの最近のバージョンでSTLの枠が少し変わったのかなぁ。
自分のやり方が間違ってないことが判れば、今コンパイルが通らなくても
将来通るようになるだろうということで納得できるんですけど。

437 名前:デフォルトの名無しさん :01/11/24 15:08
>>436
g++ -E で、プリプロッサを通した後の <iterator> を読んでみれば? 実は struct iterator が
削除されてたりしない?

438 名前:デフォルトの名無しさん :01/11/24 15:21
とりあえず、_で始まる識別子は使うなよ。
コンパイラで使ってる名前とぶつからないかどうか
いちいちチェックしないといけないだろ

439 名前:デフォルトの名無しさん :01/11/24 15:25
__STL_USE_NAMESPACES
をソースの最初で定義するべし

440 名前:デフォルトの名無しさん :01/11/24 15:26
>>439
いい忘れたが#include よりも前の行で(つまりほんとの1行目)

441 名前:428 :01/11/24 15:45
>>437
struct iterator。
確かにコンパイルが通らなかった方には存在しませんでした・・・。
これが原因ですか?だとすればなぜこうなってしまうのでしょうか。

>>438
なんか昔から大文字と小文字がくっついてるのが気持ち悪くて
型は全部"_"で始めるようにしてます。それと定数以外は全て小文字です。
あまり複雑なプログラムは組んだことがないので(専門は流体計算です)
これまでは気にせずに来ましたが、やっぱり常識的にまずいですか?

>>439
エラーが増えました・・・。

442 名前:デフォルトの名無しさん :01/11/24 15:52
#ifdef __STL_USE_NAMESPACES
struct iterator ...

になってるはず。

443 名前:デフォルトの名無しさん :01/11/24 15:59
>>441
_で始まる名前は Cの予約語。
__で始まる名前と _ + 英大文字 で始まる名前はC++の予約語。

厳密にいえば _ + 英子文字で始まる名前は C++の予約語ではないが、
さけるべき。

444 名前:428 :01/11/24 16:14
>>442
確認しました。それでプログラムの冒頭で
#define __STL_USE_NAMESPACES
としたのですが、やはりg++ -Eで出力を見ると
struct iteratorは存在しません・・・。どこで消えてるの?(泣)

>>443
厳密には予約語ではないけれども常識的には避けるべきということですね。
了解しました。少しずつ慣れるようにしてみます。

いろいろと有難う御座います。
ちょっとピグミン買いに行ってきます。

445 名前:デフォルトの名無しさん :01/11/24 16:25
gcc 3.0.2だとエラーがちと違いますな。
> foo.cc:47: friend declaration requires class-key, i.e. `friend class
> _graph<VRTX, EDGE>'
> foo.cc:48: friend declaration requires class-key, i.e. `friend class
> _graph<VRTX, EDGE>::_vrtx_itr'
> foo.cc:65: friend declaration requires class-key, i.e. `friend class
> _graph<VRTX, EDGE>'

446 名前:デフォルトの名無しさん :01/11/24 16:28
friend class XXXXを
friend class XXXX<VRTX,EDGE>にすりゃいいのか?

試してなくてす万コ

447 名前:428 :01/11/24 16:39
>>446
駄目みたいです。

それで買い物に行く前にもう一つだけ試してみました。
無理やりですが、ファイル冒頭の#include <list>の後に
stl_iterator.h内の該当部分

template <class _Category, class _Tp, class _Distance = ptrdiff_t,
class _Pointer = _Tp*, class _Reference = _Tp&>
struct iterator {
typedef _Category iterator_category;
typedef _Tp value_type;
typedef _Distance difference_type;
typedef _Pointer pointer;
typedef _Reference reference;
};

を貼っ付けてみました・・・。
コンパイル通りました(泣)。

納得できません・・・。

448 名前:デフォルトの名無しさん :01/11/24 22:17
*.objってなんのファイルですか?

449 名前:デフォルトの名無しさん :01/11/24 22:55
コンパイル中に作られるファイルで、exeが出来た後には要らないものです。

450 名前:デフォルトの名無しさん :01/11/25 02:31
EffectiveC++改定2版のp38のサンプルでハマった以下のコード。
なぜかVC++で全然通らないのはなぜでしょう?

class CFoo {
public:
 CFoo(int foo) {m_foo = foo;}
private:
 int m_foo;
friend ostream& operator<<(ostream& s, const CFoo& r);
};
ostream& operator<<(ostream& s, const CFoo& r)
{
 s << r.m_foo;
 return s;
}

main()の中で、

 CFoo obj(10);
 cout << obj << endl;

VC++コンパイルすると以下のエラーが出る
> error C2248: 'm_foo' : private メンバ (クラス 'CFoo' で宣言されている)にアクセスできません。
> error C2593: 'operator <<' があいまいです。

最初のエラーは m_foo を public にすると通るけどpublicにはしたくない
次のエラーは friend の行を外すと通るが、理解不能。

451 名前:デフォルトの名無しさん :01/11/25 02:42
sp5で問題なくコンパイル通るけど、
それどういう環境?

452 名前:デフォルトの名無しさん :01/11/25 02:45
g++ 2.95.3-6 (mingw), Borland C++ 5.5 でも通るね

453 名前:450 :01/11/25 02:48
>>451
試してくれてアリガトウ。
cl.exe のバージョンはこのようになっています。
> Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86
> Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

sp5とか当てた覚えが無いのでやっぱりコンパイラが古いんだろうか。

454 名前:デフォルトの名無しさん :01/11/25 02:51
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86
うちのこんなかんじ。

spあてたら?(でかいけど)

455 名前:450 :01/11/25 02:56
>>454
あきらかにバージョン違うね。
sp5当ててみます。

456 名前:デフォルトの名無しさん :01/11/25 02:59
一年半以上前のバージョンだね。
古すぎ。

457 名前:デフォルトの名無しさん :01/11/25 03:04
VCの次バージョンっていつ出るの?

458 名前:デフォルトの名無しさん :01/11/25 03:05
来年2月

459 名前:450 :01/11/25 03:35
sp5いれてコンパイル出来るようになったぞ〜!

460 名前:デフォルトの名無しさん :01/11/25 03:49
>>428
class _vrtx_itr : public iterator<bidirectional_iterator_tag,_vwrap*>{
このiteratorって何者?
class _vrtx_itr : public list<_vwrap*>::iterator {
とかじゃないの?

461 名前:デフォルトの名無しさん :01/11/25 13:39
質問です。
if(!hoge)と判定するためには operator!をオーバーライドしますが、
if(hoge)と判定するためには 何をオーバーライドしたらいいのですか?

462 名前:461 :01/11/25 13:40
まちがってsageちゃったのでage

463 名前:デフォルトの名無しさん :01/11/25 13:48
operator bool かな?

464 名前:デフォルトの名無しさん :01/11/25 13:49
>>459
もう解決してるみたいだが、うちは未だにVC++5の
 Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 11.00.7022 for 80x86
だけど通った(古すぎて悪かったな)。

465 名前:デフォルトの名無しさん :01/11/25 14:04
>>461
operator void*() const
プログラミング言語C++ 3版 21.3.3参照

ついでに面白くなってるスレ
http://pc.2ch.net/test/read.cgi/tech/1005897052/l50

466 名前:デフォルトの名無しさん :01/11/25 14:16
うへ、そこが荒れるんですか。

467 名前:デフォルトの名無しさん :01/11/25 16:56
typeidで
どのクラスを継承しているかという情報は
取れるのでしょうか?

468 名前: :01/11/25 17:35
C++超初心者です。
VC++6.0を使ってWIN32コンソールアプリケーションのMFCをサポートしない
プログラムの練習をしているんだけど、画面を制御する方法が判らなくて
困ってます。
具体的に、coutで出力した文字を全て消去して、新たに文字を画面の頭から
出力したいとき、必要なライブラリと関数は何かを教えて欲しいんだけど
だれかご教授お願いします。
使用OSはWIN-Meです。

469 名前:デフォルトの名無しさん :01/11/25 17:53
ANSI.SYSとエスケープシーケンスをとりあえず調べろ。

470 名前:デフォルトの名無しさん :01/11/25 20:37
>>467
取れません。typeid で取れるのは、クラス名だけです。

471 名前:デフォルトの名無しさん :01/11/25 20:45
簡単なバイナリビューアを作ったんですけど
普通NULL文字と0x0d,0x0aはテキスト情報としてどう
表現しますか?

今のところ暫定的にNULl文字→'0'
0x0d→'D'0x0a→'A'としてるんですけどこれじゃ
だめなのはわかっています。

472 名前:デフォルトの名無しさん :01/11/25 20:48
\0\r\n って書けば?

473 名前:デフォルトの名無しさん :01/11/25 20:52
できれば1文字にしたいっす

474 名前:デフォルトの名無しさん :01/11/25 21:42
>>473
他のバイナリビュアーつかったことないの?

475 名前:デフォルトの名無しさん :01/11/25 21:47
例えば char* を int* に変換したいとき、
みんな static_cast と reinterpret_cast どっち使ってる?

476 名前:デフォルトの名無しさん :01/11/25 22:03
そんなことしない

477 名前:デフォルトの名無しさん :01/11/25 22:05
>>467>>470
あるクラスを継承してるかどうかなら
type_info::before()で判定できるはず

478 名前:デフォルトの名無しさん :01/11/25 22:17
>>475
ふつーreinterpret_castだろ。つーかコンパイラがエラー出さないか?>static

479 名前:デフォルトの名無しさん :01/11/25 22:22
>>477
それ違う。a.before(b) は strcmp(a.name(), b.name()) < 0 程度の意味。

480 名前:デフォルトの名無しさん :01/11/25 22:35
>>476
それはミもフタもないです。。。

>>478
ほんとだ。
基本型のポインタ同士では static_cast 使えないのか・・・知らなかった

481 名前:デフォルトの名無しさん :01/11/25 22:53
>>480
俺もしないと思う。
なんのメリットがあんの?

MSDN>reinterpret_cast 演算子は、const、volatile、__unaligned の各属性をキャストして除去することはできません
こんだけしかない気が・・・

482 名前:デフォルトの名無しさん :01/11/25 23:14
ようこそ!
http://pc.2ch.net/test/read.cgi/tech/986355498/

483 名前:デフォルトの名無しさん :01/11/25 23:31
ポインタだらけのソースをC++風にリファレンスを活用して
書き直しているんだけど、なぜかリファレンスにNULLが指定出来ないという
問題にぶちあたった。これってそういうもの?

484 名前:デフォルトの名無しさん :01/11/25 23:35
>>483
そういうもの。
全部参照ならNULLポインタにアクセスする危険性がなくなる。

485 名前:483 :01/11/26 00:00
>>484
あー、なるほど。リファレンスにするメリットはそこにあったのか。
-> が . で書けるって事ぐらいしか気づいてなかったよ(w

486 名前:478 :01/11/26 00:04
>>481
intをシリアライズした生メモリ(まPVOIDでもいいんだけど)がたまたま
途中の都合でchar*で与えられたときにreinterpret_castでint*に変換
してintとしてアクセスするとか。

487 名前:nori :01/11/26 01:47
a[i] = b というプログラムがあった場合、逆にa[i]をbが参照するのは、どんな
書き方があるでしょうか?

初歩的な質問で申し訳ありませんが、お願いいたします。

488 名前:デフォルトの名無しさん :01/11/26 01:51
>>487
意味わからん。aとかbとかどんなオブジェクトなんだよ。

489 名前:デフォルトの名無しさん :01/11/26 02:01
>>484
安心はできない(*´Д`*)
string *s; //初期化忘れてる
...
hoge(*s); //あぼーん

490 名前:デフォルトの名無しさん :01/11/26 02:08
>>489
純然たる「参照」では初期化は必須では...

string& s; // エラー

491 名前:デフォルトの名無しさん :01/11/26 02:31
STLで単純な2分木は実装されてますか?
赤黒木はあったんですけど、あれってツリーをいろいろいじりますよね?

492 名前:デフォルトの名無しさん :01/11/26 02:48
>>491
「2分木」なんていうコンテナはSTLにゃねえよ

493 名前:428 :01/11/26 08:01
>>460
: class _vrtx_itr : public iterator<bidirectional_iterator_tag,_vwrap*>{
: このiteratorって何者?
: class _vrtx_itr : public list<_vwrap*>::iterator {
: とかじゃないの?

ありがとうございます!そうやって
list<_vwrap*>::iterator<bidirectional_iterator_tag,_vwrap*,diff_type,ptr_type,ref_type>
と設定したらうまく行きましたー。
やはり自分の間違いだったのですね。もう少し勉強します。
お蔭様ですっきりしました。

494 名前:428 :01/11/26 13:18
・・・と書きましたが、そのようにしたら今度は

1. g++(2.96, Kondara MNU/Linux 2.0) : OK
2. g++(cygwin2.95.3-5, WIN2K) : OK
3. g++(gcc2.95.1, Solaris) : OK
4. VC++(ver6) : NG

となりました。4のVC++のエラーの内容は『コンパイルされたクラステンプレートの
インスタンス化云々』というものです。ちなみに
iterator<bidirectional_iterator_tag,_vwrap*,diff_type,ptr_type,ref_type>
とした場合だと

1. g++(2.96, Kondara MNU/Linux 2.0) : OK
2. g++(cygwin2.95.3-5, WIN2K) : NG
3. g++(gcc2.95.1, Solaris) : NG
4. VC++(ver6) : OK

となります。この場合の2と3のNGの内容は>>444のようにstruct iteratorが
消えたことによるものです。そしてこの場合は>>447のように
無理やりstruct iteratorを定義してやると、2と3(2.95以前のg++)についても
コンパイルが通ります。まだすっきりしません。

495 名前:デフォルトの名無しさん :01/11/26 15:06
>>485
参照のメリットは、もうひとつあるぞ。const 参照の場合限定だが、構造体やクラスを実引数「その場」
で作れる。

void Render(const Point& pt, Color color);
Render(Point(0, 0), Color(255, 255, 0));

496 名前:デフォルトの名無しさん :01/11/26 15:25
constで定義した変数の値を変えるのはどうすればいいのですか?

497 名前:デフォルトの名無しさん :01/11/26 15:26
>>496
1. mutable にする
2. const_cast する

498 名前:デフォルトの名無しさん :01/11/26 15:26
>>496

変数の宣言の所でconstを削除する。

499 名前:デフォルトの名無しさん :01/11/26 15:48
>>496
変えるな!

500 名前:デフォルトの名無しさん :01/11/26 15:54
>>499
理想はそのとおりだが、たまに const char * をとるべき関数/メソッドなのに、char * をとるように
書いてあるライブラリとか存在するから。

DrawString(char *s);

みたいなやつね。


■過去ログ置き場に戻る■ 1- 前250 次250 最新50
DAT2HTML 0.33f Converted.