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


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

C++相談室
251 名前:デフォルトの名無しさん :2001/04/12(木) 00:19
>>250
シンタックスもだろ。

252 名前:デフォルトの名無しさん :2001/04/12(木) 01:57
最近、難しいのはC++ではなくMicrosoft VisualC++だということがわかってきたんですが、
どうしてMicrosoftはあんな厨房めいたコンパイラを売ってるのですか?
そしてなぜそれがこんなに広まってしまっているんですか?
全てが私の理解を超えています。

253 名前:デフォルトの名無しさん :2001/04/12(木) 02:17
↑うおお、奇しくもC#相談室とならんどる!!!!
これも時代の流れか…。

254 名前:デフォルトの名無しさん :2001/04/12(木) 05:37
質問です。
newで確保したクラスは必ずdeleteしなくてはならないのでしょうか?
アプリが終了することが前提ならdeleteしなくてもオッケー?
それとも、malloc/freeと同じ問題ですか? それだったらスマソ。

255 名前:>254 :2001/04/12(木) 05:47
deleteしないとデストラクタが呼ばれないけど。
それでも良いならいいんじゃない。
ひょっとしてデストラクタの意味がわからないんだったら、
もう一度本読み直した方がいいと思うけど

256 名前:255>254 :2001/04/12(木) 05:58
ついでに言うと、newしたインスタンス(あんたのいうクラス)は
アプリが終了してもdelete呼ばない限りデストラクタ呼ばれないからね。

257 名前:233 :2001/04/12(木) 09:21
>>248
あんな感じで出来そうなんですが、
newのプロトタイプが、
void *operator new(size_t size);
なので引数を追加するとオーバーロードされないんですよ

258 名前:デフォルトの名無しさん :2001/04/12(木) 10:23
>>257
なんで?233ので引数付きnewを定義しといて、あとは普通に
ClassA* pA = new( __FILE__, __LINE__ ) ClassA;
とかすれば解決な気がするんだけど。

259 名前:233 :2001/04/12(木) 13:04
>>258
あんたすげーよ。
その通りにやったらうまくいったよ。大感謝。

260 名前:デフォルトの名無しさん :2001/04/13(金) 03:35
newのオーバーロードなんてした事ないよ。俺って厨房
リーク発見とかだよね? BoundCheckerでいいじゃん(泣)

261 名前:なまお :2001/04/15(日) 08:45
僕のサイトにC言語会話講座と言うのを作ったので、見にきてください!

http://web.kyoto-inet.or.jp/people/namao/index.html

262 名前:デフォルトの名無しさん :2001/04/15(日) 12:45
>261
indexを見た瞬間、アダルトサイトだと思ったのは俺だけ?

263 名前:デフォルトの名無しさん :2001/04/19(木) 18:00
g++で自己参照型クラスとかメンバにSTLのvectorとかiteratorを含んだクラスのオブジェクトを
ダンプ、シリアライズする方法ってどうしたらいいんですか?なんかいいライブラリとかあるのかな?
JavaのSerializableインターフェースみたいな感じで使えるとありがたいんだけど。

264 名前:デフォルトの名無しさん :2001/04/19(木) 19:36
複数のステートメントがあるマクロを定義する時に

#define MACRO do{ 処理1; 処理2; … }while(0);

と書いているものを見かけたのですけど、これって中かっこでかこっているのは当然だと思うんですが、doとwhile(0);って何か意味があるんでしょうか。

265 名前:264 :2001/04/19(木) 19:40
すみません、よく見たら

#define MACRO do{ 処理1; 処理2; … }while(0)

だった。そして解決しました。

266 名前:グラマっち :2001/04/25(水) 13:13
template <typename T>
inline btw<T>::btw( const T &val)
  : m_val(val)
{
}

template <typename T>
inline btw<T>::btw( const T &val)
{
  m_val = val;
}

では、前者の方が良いらしいのですが、
何がどういいのでしょうか?
どなたかご教示ください。

267 名前:デフォルトの名無しさん :2001/04/25(水) 13:20
>>266
上が初期化で下が代入。

268 名前:グラマっち :2001/04/25(水) 14:24
>267
それはわかるのですが、
動作は変わるのですか?

269 名前:デフォルトの名無しさん :2001/04/25(水) 14:35
>>266
前者は、
・代入演算子が呼ばれないので効率がよくなる場合がある。
・constメンバを初期化できる。
かな。「Effective C++」に載ってたね。

270 名前:グラマっち :2001/04/25(水) 14:43
>>269
では、ディープコピーが必要でない場合は前者の方が良い。
という事ですね、
Effective C++も見てみます!
ありがとうございました。


271 名前:デフォルトの名無しさん :2001/04/25(水) 21:04
class CData
{
int a;
public:
CData(int n) : a(n) { printf("set a=%d\n", n); }
CData() : a(0) { printf("set a=0\n"); }
CData &operator=(int n) { a = n; printf("set a=%d\n", n); }
};

class CFoo
{
CData data;
CFoo::CFoo();
};

CFoo::CFoo()
: data(1)
{
}

CFoo::CFoo()
{
data = 2;
}

>>270
こんなテストコードを書いてみたけど、
EffectiveC++ を読んだほうが早いかもしれないな……。

272 名前:グラマっち :2001/04/26(木) 18:31
スーパー親切な回答ありがとうございます!
今からやってみます!

273 名前:デフォルトの名無しさん :2001/04/26(木) 20:03
>>1
死ね

274 名前:うるう年の考え方おしえて :2001/04/30(月) 23:47
うるう年の考え方おしえて

275 名前:デフォルトの名無しさん :2001/04/30(月) 23:52
>>274
スレ違いです。
あとFAQは自分で調べてね。

276 名前:デフォルトの名無しさん :2001/05/01(火) 01:31
相談なんですが、
Cと、おジャ魔女どれみって関係あるんですか?
おジャ魔女どれみ←C
おジャ魔女どれみ#←C#
もーとおジャ魔女どれみ←C++
関係ないよね?

277 名前:デフォルトの名無しさん :2001/05/01(火) 02:08
>>276
すごく面白いことを書いたつもりで、
モニターの前で有頂天になっている無様な姿が目に浮かぶようだよ。

278 名前:デフォルトの名無しさん :2001/05/03(木) 15:26
vector<int> *v = new vector<int>(1);

..

cout << v[0];

でエラーでますよね?

cout << v->operator[](0);

とするしかないのでしょうか?

279 名前:デフォルトの名無しさん :2001/05/03(木) 16:02
cout << v[0][0];

newする(どこかに保存する)必要が無ければ、素直に
vector<int> v(1);
でいいし。

280 名前:デフォルトの名無しさん :2001/05/03(木) 16:08
それとも、望む動作はこっちか?
ostream& operator <<(ostream& stream, const vector<int>& v)
{
  for (vector<int>::const_iterator it = v.begin(); it != v.end(); ++it) {
    stream << *it << endl;
  }
  return stream;
}

281 名前:278 :2001/05/03(木) 16:14
ありがとう。
>>279のように要素にアクセスしたかったのれす。
new しないで逝ってみようとおもいます。

282 名前:デフォルトの名無しさん :2001/05/03(木) 16:42

cout << (*v)[0];
じゃだめなの?

283 名前:281 :2001/05/03(木) 18:05
>282
ありがとー。演算子の優先順位・・・。

cout << *v[0]

とかやってエラーだしてました。

284 名前:デフォルトの名無しさん :2001/05/03(木) 18:13
>>277
ワラタ

285 名前:デフォルトの名無しさん :2001/05/04(金) 07:57
前々から疑問に思ってること、質問させてください

Aというクラスと、それをリストで持っている管理クラスBがある。
なんてことはよくありますよね。で、管理クラスBが、Aのメンバを
keyに使い、Aのリストをソートするという場面も日常的にあると思います。

現在はA->getKey()みたいなのでkeyを返しているのですが、メンバ一つを返す
だけの関数使うのってどうもスマートじゃない気がして、いつも不安にかられて
います。こういう管理を実現するスマートな設計って無いものでしょうか。
(もちろんfriendは勘弁で)

286 名前:SAGE :2001/05/04(金) 08:32
>>285

A側にKeyの比較関数を作っといて、
ソートの時はB側でそれを呼ぶとか。

287 名前:デフォルトの名無しさん :2001/05/04(金) 13:32
STLだとかのリファレンスってどこかで落とせますか?

288 名前:( ´∀`)さん :2001/05/04(金) 16:09
C++って、なんで実行時型情報からインスタンスを生成できないのでしょうか?
MFCのCRuntimeClassを使えばできるけど。あれはマクロでめんどくさい。
実装してない理由でもあるのでしょうか?

289 名前:デフォルトの名無しさん :2001/05/04(金) 17:55
>>288
リンク時に、必要なライブラリの選択が出来ずに、
実行ファイルが巨大化するからだろ。

290 名前:>>285 :2001/05/04(金) 18:30
AのStatic メンバにBを持たせるのは駄目か?

291 名前:288 :2001/05/04(金) 18:54
>>289
なるほど。

でも、よく考えたら実行時に保持すべき情報が多くなるからかな?
例えば、クラスのサイズとか、コンストラクタへのポインタとか。
全てのクラスについて保持すると莫大になる。

292 名前:デフォルトの名無しさん :2001/05/04(金) 22:00
4: virtual string aMethod() = 0;
と宣言すると

Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
a.cpp:
エラー E2462 a.cpp 4: 'virtual' はテンプレート以外のメンバー関数だけに適用できる
エラー E2303 a.cpp 4: 型名が必要
エラー E2139 a.cpp 4: 宣言に ; がない

と出ます。g++だったらコンパイルとおるんですけれど、
どっちが正しいの?

293 名前:デフォルトの名無しさん :2001/05/04(金) 22:12
stringをstd::stringに直す

294 名前:292 :2001/05/04(金) 22:15
>293
ありがとう。あたまに using namespace std
と加えておきました。

295 名前:285 :2001/05/05(土) 01:31
レスありがとうございます
>>286
おおなるほど、それなら無様にメンバさらすの避けられますね。
実際作るとなると・・・バブルソートで実装する位しか思いつかない自分が
憎いです(^ ^;んーこれをSTLこみで作れたら最高ですねぇ。
>>290
Aが関連するのが、Bのクラス(あるいは唯一のインスタンス)なのか、それとも
Bのインスタンスなのかによりますよね、たぶん。前者なら有効そうですが…、
やはり往々にして後者の場合が多いですからねぇ。というか私の状況説明不足です。スマソ

296 名前:デフォルトの名無しさん :2001/05/05(土) 01:47
OOPって何ですか?

297 名前:>296 :2001/05/05(土) 01:59
OOPで検索してね。

298 名前:デフォルトの名無しさん :2001/05/05(土) 02:12
ちょっと質問があります。
参照カウンタ付のオブジェクトを扱うスマートポインタを実装したんですが、
このスマートポインタに対して&演算子を使うと格納しているオブジェクトの
ダブルポインターを返すようにした所、listなどのSTLコンテナに格納出来なく
なってしまいました。
こんな感じのエラーが出ます。
error C2664: 'destroy' : 1 番目の引数を 'class foo ** ' から 'class ref_ptr<class foo> *' に変換できません。
同じ事を_com_ptr_tもやっているのですが、_com_ptr_tはこの問題が生じません。
_com_ptr_tの定義を眺めてみたんですが、どうして_com_ptr_tはOKで私のが駄目なのかわかりません。
よろしくご教授お願いします。

299 名前:デフォルトの名無しさん :2001/05/05(土) 02:37
>>298

スマートポインタの & 演算子を、rep へのポインタの取得に書きかえちゃったんだから、
「スマートポインタへの参照」ができなくなっちゃったということでは?

300 名前:298 :2001/05/05(土) 03:17
>>299
うい、そういうことなんです。
でも_com_ptr_t(COMスマートポインタのテンプレートクラス)でも同じ
事してるのにエラーにはならないんですよ。
一体どうして?

301 名前:298 :2001/05/05(土) 03:24
いまは結局ダブルポインターを返すメンバ関数で対処してるんですけど、
スマートポインタといえど、普通のポインタとほぼおんなじ感じで使え
たほうが良いじゃないですか。
引数としてダブルポインターを要求して、そのポインタに製作したイン
スタンスをセットして返す関数とかに、
  foo(&rptr); // rptrはスマートポインタ
てな感じに書けるようにしたいなぁ、って事だったんですけど。

302 名前:デフォルトの名無しさん :2001/05/05(土) 04:17
CAdapt

303 名前:デフォルトの名無しさん :2001/05/05(土) 04:46
Borland C++ Builderの初心者向けのヤツ、
定価20000だそーですが、
実際小売店ではどのくらいの値段でしょうか?
とりあえず買おうかと。メモ帳とお別れしたいの(笑)

304 名前:デフォルトの名無しさん :2001/05/05(土) 04:50
BCBのエディタには期待しない方がいいぞ。>303
VisualC++6のエディタの方がマシ。

305 名前:303 :2001/05/05(土) 05:02
>304
そうなんですか。
まあエディタはどうでも良いと言えばいいんですが(笑)

ゲームプログラミングをしてみたいのですが、
専門書(と言うより入門書)やら解説サイトの内容を見ると
すべてアプリを使用しているので。
Visual C++の方が向いてるならそっちにしてみます。
しかしいくらくらいですかね?学割きくのかな?

306 名前:デフォルトの名無しさん :2001/05/05(土) 05:22
>>305
DirectX は VC++ に基本対応なので
ゲーム作るならそっちのほうがいいかもね

google.com で Visual C++ アカデミックパックで
ひいてみそ

307 名前:303 :2001/05/05(土) 05:24
オープン価格みたいですね。
店頭にいかなきゃわからないか・・・。
約20000で販売してるサイトがありましたが。
秋葉原はそれより安いかなー。

308 名前:303 :2001/05/05(土) 05:25
>306
おお、どーもです。調べてみます。

309 名前:デフォルトの名無しさん :2001/05/05(土) 05:35
>>305
3年前に学割で買ったVC++6.0Professionalが12000円だったかな。
今はもっと安いかも。MS製品、学生なら恐れることないよ。
逆に社会人には(T-T)

310 名前:309 :2001/05/05(土) 05:37
ageちゃった

ちなみにヤマダ電気(^ ^;
秋葉原出ればもっと安いかもね

311 名前:デフォルトの名無しさん :2001/05/05(土) 05:58
>>302
>CAdapt
??? 301へのレス?
とりあえずMFCにはそんなクラス無いみたいだけど……

312 名前:デフォルトの名無しさん :2001/05/05(土) 14:48
文字列は char* と std::string のどっちを使うべきですか?

313 名前:デフォルトの名無しさん :2001/05/05(土) 19:36
両方

314 名前:312 :2001/05/05(土) 20:04
使い分け方はどうしたら良いのでしょうか?
(C++になってstd::stringだけで統一されたのかと思ったのですが、
const char* という記述を良く見ます。)

315 名前:デフォルトの名無しさん :2001/05/05(土) 20:54
string に統一なんて全然されてないよ。
使い分けの方針は「できるだけ string を使う」。

316 名前:314 :2001/05/05(土) 21:17
「統一」というのは単に自分が電波を受信していただけです・・・。
"できるだけ string" となると char* と混在して混乱しませんかねぇ。
どっちをつかっても移植性に問題がでることはありませんか?

317 名前:デフォルトの名無しさん :2001/05/05(土) 21:32
string(const char *) があるから混在してもあまり
意識しないで書けるよ。というかどの辺で混乱するのか
よくわからないなあ。

318 名前:314 :2001/05/05(土) 21:42
片方で統一できるのなら統一してしまった方が良いと思いまして。

使い分けがいまいちわからないのでもう少し質問させていただきます。

GoF の「デザインパターン」を読んでいてあるクラスが文字列を
const char* _name;
で保持しているのを見つけたのですが、
これが string じゃないのはなんででしょう?
string の方が記憶域を多く使うことくらいしか原因が思いつかないのですが・・・

319 名前:デフォルトの名無しさん :2001/05/05(土) 22:22
読者にstringの知識を強いてまで使うメリットはなかったんでしょう。
例えばstringを使えばコード量が1/10になるんだったら使ったと思います。

320 名前:314 :2001/05/05(土) 22:36
>319
ありがとうです。できるだけ string を使うということで解決しました。

321 名前:こん :2001/05/07(月) 01:50
ちわ〜
みなさんにはくだらない事なのかもしれませんが、ファイルにpassがかかっていて
passがわかったんですけど、passが全角ひらがなでpassを入力するとこは英字しか
入りません。どうやってpassを入れるんですか?
教えてください。お願いします。

322 名前:ギコ :2001/05/07(月) 04:39
>>321
メモ帳などに全角ひらがなでpassを書いた後、それをコピー
passを入れるところでctrl+v

ゴホン、あー、あー、んじゃいくかね
二度とここにくるんじゃねぇ、スレ違いの上に板違いじゃボケ
ちくしょうめ、オレがpassの代わりに呪いかけてやる
( ゚Д゚)ノノ〜x〜x〜x〜x〜x<イッテヨシ>

323 名前:デフォルトの名無しさん :2001/05/07(月) 18:26
VC++6使ってるのですけど、これが通ってしまうのってどうも納得いきません

class Foo{
};
class FooFoo : public Foo{
public:
    int no(){ return 10; }
};

main(){
    Foo* foo = new Foo;
    int result = ((FooFoo*)foo)->no(); //resurt = 10
    delete foo;
}

newしたのがFooFooクラスならまだ納得いくのですが…
インスタンスも無いような派生クラスの関数なんぞ
呼び出しちゃえていいのでしょうか?

324 名前:デフォルトの名無しさん :2001/05/07(月) 19:01
>int result = ((FooFoo*)foo)->no();
ここを
int result = ((FooFoo*)NULL)->no();
にしたって動くんだからさ。(実験してない)

325 名前:デフォルトの名無しさん :2001/05/07(月) 19:27
別ファイルを読み込んで、デフォルトの引数として、5を表示
させたいのですが、メインファンクションで、引数なしで呼び
出すと、Carという名前のクラスを実行してくれません。
呼び出しで、Car tk(78);の様に、引数を入れるとちゃんと
実行されます。なにが間違ってるのか、わかる方いれば教えて
ください。

//ファイル1
#include<iostream.h>
class Car
{
int a;
public:
Car(int num = 5){cout << num;}
}

//ファイル2
#include"toyota.cpp"
void main()
{
Car ty();
Car tk(78);
}

326 名前:SAGE :2001/05/07(月) 19:54
Car ty();
だと引数無しのデフォルトコンストラクタが呼び出されそうな気がするので、
Car ty;
でどーでしょうか。

327 名前:デフォルトの名無しさん :2001/05/07(月) 20:03
Car ty();
と書いたら、ty という関数の宣言になっちゃうからね。

328 名前:デフォルトの名無しさん :2001/05/07(月) 20:11
>int result = ((FooFoo*)foo)->no();

>インスタンスも無いような派生クラスの関数なんぞ
>呼び出しちゃえていいのでしょうか?

よくない。C++でCのキャストを使うのは厨房。

FooFoo *p = dynamic_cast<FooFoo *>(foo);
if (p) result = p->no();
が正しい。

int result = static_cast<FooFoo *>(foo)->no();
ならコンパイルは通らない。
int result = dynamic_cast<FooFoo *>(foo)->no();
なら、NULLになるから間違いなく例外割り込みが発生するだろう。

Cのコードを混ぜて、C++の問題だと思うなよ。

329 名前:デフォルトの名無しさん :2001/05/07(月) 20:14
>>326
それはおかしいだろ。
Car::Car() と Car::Car(int num = 5) は共存できず、
コンパイルエラーになるから。
共存するコンパイラは ANSI に準拠していないはず。

330 名前:325 :2001/05/07(月) 20:58
>>326
>>327
>>329
ありがとうございました。大変感謝してます。Car tyにしたら、
ちゃんとできました。助かりました。

331 名前:>328 :2001/05/08(火) 00:58
> FooFoo *p = dynamic_cast<FooFoo *>(foo);
このクラス定義で dynamic_cast は使えないぞ、普通は
> int result = static_cast<FooFoo *>(foo)->no();
> ならコンパイルは通らない。
通るだろ普通

332 名前:321 :2001/05/08(火) 02:41
>322のギコさん
  どうもすみませんでした。。。こうゆう質問どこでするかわかんないので。。。
  教えてくれてありがとうございます。。。

333 名前:323 :2001/05/08(火) 03:01
>>328
や、確かにCの問題かもしれませんね。ただ継承がらみでもありますし、さすがに
酷いなと思いまして。そもそもno()はstaticですらないのに…。これが私の
理解不足によるもので、本来なら説明可能なものなのかどうかを問いたかったのです。
>>331
static_castですら通りますねー。こうなるとエラーくるまで防ぐ手だてはない
のでしょうか…。こんなコード書かなければいいのですが…腑に落ちない。

>>324 というか
>int result = ((FooFoo*)NULL)->no();
ばっちり動きましたヽ(´д`)ノなんだか悩んでたのがバカみたい、
おかげで吹っ切れました。「まぁ、いいや」で逝くことにします。

334 名前:デフォルトの名無しさん :2001/05/08(火) 03:34
異なるクラスのオブジェクトををSTLのvectorで関連付けて運びたいのですが
仮想関数のオーバーライドがうまくいかないみたいなんです。
VC6.0++ですが、以下のようにしてvectorに格納した各オブジェクトに
おまえは誰だ?と聞いてもみんなBaseだよとしか答えてくれません。
各自が自分の名前を言って欲しいんですが・・・。
配列ならばうまくいったんですが、vector でうまくやる方法はないでしょうか?
class Base{
public:
virtual void who(){ cout << "Base"; }
};

class A : public Base{
public:
void who(){ cout << "A"; }
};

class B : public Base{
public:
void who(){ cout << "B"; }
};

class cV{
std::vector< Base > data;
public:
cV(){
data.push_back( A() );
data.push_back( B() );
}
void show_who(){
cout << "cV";
for( std::vector<Base>::iterator i=data.begin() ; i!=data.end() ; i++){
i->who();
}
}
};

main(){
cV v0;
v0.show_who();
};

335 名前:デフォルトの名無しさん :2001/05/08(火) 05:14
>>334
Base型ポインタの配列ではなく、Base型の配列に派生クラスのインスタンスを
つっこんじゃってるからですよ。やってることは要するに

Base base;
A a;
base = a;
base.cV();

なわけです。cV使ってるのはどうみてもBaseだから、当然BaseのcVが呼ばれます。
でも本当にやりたいのはこれですよね。
Base* base = &a;
base->cV();

ま、もう必要ないだろうけど一応
class cV{
    std::vector< Base* > data;
public:
    cV(){
        data.push_back( new A() );
        data.push_back( new B() );
    }
    void show_who(){
        cout << "cV ";
        for( std::vector<Base*>::iterator i=data.begin() ; i!=data.end() ; i++){
            (*i)->who();
        }
    }
    ~cV(){ /*vecotor型dataにあるのを全てdelete*/ }
};

基本クラスポインタの配列やリストを使って派生クラスをdeleteする場合は
基本クラスのデストラクタをvirtualにすることをお忘れなく

336 名前:335 :2001/05/08(火) 05:18
> vecotor型data
(^-^;

337 名前:デフォルトの名無しさん :2001/05/08(火) 11:52
334です。できました。激多謝!>335

338 名前:デフォルトの名無しさん :2001/05/09(水) 01:14
再起法をつかって2のk乗を求めるプログラムなんですが、
エラーは出ないけども、数値を入れると強制終了になってしまいます。
何が原因でしょうか?どなたか教えてください。
よろしくお願いします。
#include <stdio.h>
int fact(int n)
{
if (n != 0)
return(2^n+fact(n-1));
else
return(2);
}
int main(void)
{
int x;
scanf("%d",x);
printf("%d",fact(x));
return(0);}

339 名前:デフォルトの名無しさん :2001/05/09(水) 01:30
>>338
scanf("%d",&x); //&が抜けてる

340 名前:デフォルトの名無しさん :2001/05/09(水) 01:41
>>338
再帰

341 名前:デフォルトの名無しさん :2001/05/09(水) 01:48
>>339
あ・・・どうもです・・・
なさけない・・・

342 名前:デフォルトの名無しさん :2001/05/09(水) 01:50
2^n>>338

343 名前:デフォルトの名無しさん :2001/05/09(水) 04:29
やさしい。イイ

344 名前:303 :2001/05/10(木) 02:04
いまさらだがVisual C++のStandardEditionの
アカデミーパックは、秋葉原のソフマップで
税抜き8980円だったことを報告したいと思います。
っつーか買いました。

345 名前:デフォルトの名無しさん :2001/05/10(木) 06:41
C++ではないですが
DWORD dw;
dw = 0xFFFFFFFF;
printf("%d", dw);
とすると-1が出てきます
0xFFFFFFFEとすると-2が出てきます
どうして?unsignedじゃないの??%ldでもだめ

よろしくお願いします

346 名前:デフォルトの名無しさん :2001/05/10(木) 06:49
>>345
%dはdwのビットイメージをsignedで解釈するから。
%uを試してみれ。

347 名前:309 :2001/05/10(木) 07:15
>>344
なんだか自分を責めたい気分。あと一言いっておけば…、と。

348 名前:デフォルトの名無しさん :2001/05/10(木) 10:42
>>344
学割なら+3000円くらいで、Pro版買えたのにね

349 名前:デフォルトの名無しさん :2001/05/10(木) 19:23
344じゃないけど
Proだとなんかちがうんですか?

350 名前:SAGE :2001/05/10(木) 20:41
>>349
MFCのスタティックリンクができたりとか。
最適化もStandardだとダメだったっけ。(あんまり覚えてない)

351 名前:デフォルトの名無しさん :2001/05/10(木) 21:03
http://www.microsoft.com/japan/developer/vstudio/vs6/pages/image0500.htm

352 名前:344 :2001/05/11(金) 02:41
>347
いやーどーなんですかねー?
別にプロを目指してるわけでもないので
スタンダードで良いだろう程度に考えてましたが。
まず不便を感じられるようになりたいですね。

353 名前:デフォルトの名無しさん :2001/05/11(金) 20:53
発展してるのでage

354 名前:309 :2001/05/12(土) 02:00
>>352
うん、杞憂だったよ。どうせなら…って程度だし、きみなら大丈夫だと思う
勉強なら別に問題ないし、そろそろ次もあるしね

355 名前:デフォルトの名無しさん :2001/05/12(土) 10:37
Windows環境でCSVファイルを読まないといけないくなりました。
一行をcharの配列にいれて、一文字ずつカンマを調べようかと思ってますが
何か効率的なやり方や、csvを読むクラスがあれば教えてください〜。

356 名前:基本的でごめんね :2001/05/12(土) 13:50
ポインタの参照渡しってどうやるのでしょうか?

int a, b, *ptr;
ptr = &a;

printf("ptr = %X, &a = %X, &b = %X\n", ptr, &a, &b);
func(&ptr, &b);
printf("ptr = %X, &a = %X, &b = %X\n", ptr, &a, &b);

------------------
// この関数のダブルポインタ引数をポインタの参照渡しにしたい。。
void func(int **pptr, int *pb)
{
 *pptr = pb;
}

よろしくおねがいしまちゅ。。。

357 名前:お騒がせしました :2001/05/12(土) 13:55
int a, b, *ptr;
ptr = &a;

printf("ptr = %X, &a = %X, &b = %X\n", ptr, &a, &b);
func(ptr, b);
printf("ptr = %X, &a = %X, &b = %X\n", ptr, &a, &b);

------------------
void func2(int * &ptr, int &b)
{
 ptr = &b;
}

で出来ましたです。。

358 名前:デフォルトの名無しさん :2001/05/12(土) 16:16
>>355
それでだいたい問題ありません。
あとはファイルを読み込む際のバッファリングなどに気を配りましょう。

359 名前:ルーマニア人 :2001/05/12(土) 18:33
C++の例外の必要性がわかりません。
戻り値で値を返せば例外なんて必要ないんじゃないでしょうか?
どうしてわざわざ、Throwなんて機能があるんですか?

360 名前:デフォルトの名無しさん :2001/05/12(土) 18:42
ヽ( ´ー`)ノ オブジェクト思考と例外は相容れない関係なんだよ。>359

361 名前:デフォルトの名無しさん :2001/05/12(土) 18:45
ヽ( ´ー`)ノ >>360思考→指向。どっちでもいいけどね。

362 名前:デフォルトの名無しさん :2001/05/12(土) 18:51
>>360
大嘘。凄く関係有るぞ。

363 名前:デフォルトの名無しさん :2001/05/12(土) 18:58
ヽ( ´ー`)ノ ちゃんと読め。>362

364 名前:デフォルトの名無しさん :2001/05/12(土) 19:24
>>359
例外クラスを継承してポリモーフィズムできるから、
例外処理はおいしいんだよ。
EFileErrorクラスを継承して、EFileReadErrorやEFileOpenErrorとかを作るんだ。
例外に価値を感じないということは、例外クラスを継承するという考えが欠落しているか、
ポリモーフィズムを理解できていないか、どっちかだろうね。

365 名前:デフォルトの名無しさん :2001/05/12(土) 19:30
>>360-363
なんだか会話が成り立っていません。

>>359
Throwしたものが、メソッドコールスタックのどこででも拾えるんだぞ?
オブジェクト指向うんぬんを除外しても、超便利だぞ?

366 名前:デフォルトの名無しさん :2001/05/13(日) 00:08
STLのfor_eachとかのアルゴリズムに渡す関数オブジェクトって値渡しで
定義されてますよね(egcs,VC6)?
関数オブジェクトの中で渡された引数の集計を行って、あとから結果を引出したいことが
よくあって、参照渡しに修正したアルゴリズムを作って使ってますが、
なんか漠然と気持ち悪いと思ってます。

…こういった使い方ってどうなんですかね?(質問まで漠然としててスマソ)

367 名前:デフォルトの名無しさん :2001/05/13(日) 00:14
コンストラクタの中での致命的なエラーとかはどうするよ?
例外で通知するしかないだろ。

368 名前:ルーマニア人 :2001/05/13(日) 20:10
オブジェクト指向との関連はわかりませんが、
例外の必要性(便利性?)はわかりました!みなさん、頭イイですね!!
私も例外の理解が浅かったのがいけませんでした。

クラスでの例外を考えると夢が広がりますね。
あとコンストラクタでのエラー通達方法も初めて気づきました。
皆さんのおかげで、とても幸せになれそうです。

369 名前:デフォルトの名無しさん :2001/05/13(日) 20:24
>>366
参照(やポインタ)のほうが値渡しより
役立つことが少し多いと思う。大抵どんな場合でも。
その話もまた一例なんじゃないかと推察します。

>例外
なんてゆーか、プログラム実行の流れと
エラー通知の流れとを、別々に作ってくれた
ってのは凄く嬉しいと思うってのが1つ。

あと例外「クラス」ってのも美味しいよね。
例外の種類分けを、エラー番号なんていうダサダサのやり方より
数段マシな方法で管理できるのは、随分よい。

370 名前:デフォルトの名無しさん :2001/05/14(月) 23:55
>>369
激しく同意

371 名前:デフォルトの名無しさん :2001/05/15(火) 09:46
gea

372 名前:>>369 :2001/05/15(火) 10:35
>あと例外「クラス」ってのも美味しいよね
別に例外でクラスオブジェクトを投げる必要はないし、returnで
クラスオブジェクトを返さない理由もないんだけど。

373 名前:デフォルトの名無しさん :2001/05/15(火) 15:41
>>372
じゃ一生そうやってろ

374 名前:デフォルトの名無しさん :2001/05/15(火) 21:59
>>372
必要性、おおありだよ。
例外クラスの継承図しだいで、
リカバリーのしやすさが飛躍的に高まる。

375 名前:デフォルトの名無しさん :2001/05/16(水) 03:20
int& MyMethod(int n){ return n; }
こういう戻り値がint&とかの関数の意味がわかんない。
これってどういうことなの?
関数が参照???
誰か教えてください。

376 名前:デフォルトの名無しさん :2001/05/16(水) 05:55
上の場合はローカル変数の参照を返す事になるので激意味無い
というかやったらヤバイが、
int& MyMethod(){static int n=0;return n;}
とかだと
MyMethod()=3;
みたいにしてnに代入できると思う。

377 名前:デフォルトの名無しさん :2001/05/16(水) 10:00
参照返しは、メンバ変数を返したり、演算子をオーバーロード
するときによく使います。これを使ってるソースは標準C++
ライブラリやMFCの文字列あたりを参考にするといいでしょう。

378 名前:>374 :2001/05/16(水) 10:30
・例外機構と
・エラーの返り値を数値じゃなくてクラスにすること
は全く関係がないと主張してるんだけど。
元レスのエラーコードよりクラスまんせー、っていうのは例外がなくっても
成り立つでしょ?

379 名前:デフォルトの名無しさん :2001/05/16(水) 12:06
>>378
例外ってのは、適当な例外ハンドラが見つかるまでスタックを辿る機能があるだろ。
そこにポリモーフィズムを組み合わせて、あるときは基底クラスで、
またあるときは派生クラスでキャッチするのがおいしいんだ。

エラーの種類毎に細かくリカバリしたいときは、できるだけ派生クラスを、
エラーが発生した場所と近いところでキャッチする。
あまりエラーの種類を厳密に判別する必要が無く、たとえば
エラーメッセージを表示して終わりとかいうばあいは、
基底クラスをmainに近いスタックでキャッチするようにすれば、
ファイルの読み込み処理毎にリカバリ処理を書く必要が無くなる。

こうしたことはエラークラスがうまく継承されてないと実現できないし、
またスタックを辿る機能がなければ、基底クラスのキャッチを
呼び出し元に任せることもできない。

だからポリモーフィズムと例外は切っても切れないんだよ。

380 名前:デフォルトの名無しさん :2001/05/16(水) 18:23
>>376-377
つまり、最初から関数の「外」に有った変数を返せ、
ってことだよね?この理解で合ってるっすか?

メンバ変数も、関数そのものの中のものじゃない、っと。

381 名前:VB厨房 :2001/05/16(水) 18:24
>>379
とても興味のある回答です、
単純なものでいいので具体的なコードお願いできない?

382 名前:デフォルトの名無しさん :2001/05/16(水) 19:10
>>378
>・例外機構と
>・エラーの返り値を数値じゃなくてクラスにすること
>は全く関係がないと主張してるんだけど。
>元レスのエラーコードよりクラスまんせー、っていうのは例外がなくっても
>成り立つでしょ?

うーん。面白い主張だが、なんかノリがちょい違うなあ。
切っても切り離せないってのは確かに嘘だが、
合体させないより合体させるほうが「ごりやく」が
大きいのも確かなんで、まぁ。

例外クラスのInstanceをわざわざ自分で作って自分で返し値として返す
ってのは、可能であってもあんまりメリットないなあ。
ふつーしないじゃん。ソース汚くなるだけ。
成り立つけど成り立たせても意味が無いという。

てゆーか言語お仕着せの例外クラスが無い世界の人は
こういう考え方もするんだなってのが新鮮だった。
すまん。俺の常用言語には例外クラスが有るんで(^^;、
そんな面倒なこと考えたことも無かったよ。

383 名前:375 :2001/05/16(水) 19:43
>>377
メンバ変数にアクセスするのは普通にメンバアクセス関数を
作ればいいですよね。
ということは、参照返し関数は演算子のオーバーロードくらいにしか
使うことはないんだね。

どうもありがと!

384 名前:デフォルトの名無しさん :2001/05/16(水) 21:01
>>381
探してみたけど、ぴったりこれだというページは見つからなかった。
簡単に書くなら、こんな感じか。

foo()
{
 char *p1 = new char[256];
 char *p2 = new char[256];
 char *p3 = new char[256];
 char *p4 = new char[256];
 foo();
 foo();
}

bar()
{
 try
 {
  foo();
 } catch(bad_alloc &e)
 {
  cout<<"メモリがねぇぞゴルァ!"<<endl;
 } catch(exception &e)
 {
  cout<<e.why()<<"だってさ"<<endl;
 }
}

あとはstlのexceptionの継承図でも眺めてね。
Javaでも可。

例外クラスを継承構造にするのは、エラー処理の責任の問題。
誰が何のエラーに責任を持つのかはっきりさせることができる。

言い換えれば、責任がもてないエラーはキャッチしなくてもいい。
もしくはキャッチした後で、責任がもてないと判明したら、
より強い責任を持つはずの呼び出し元にthrowする。
こうすることで、各関数が持つ責任を減らすことが出来る。
サンプルコードの例では、fooはメモリ確保エラーの責任を負っていないし、
負ったところで何もできないはず。

エラーコードを使う方法は、呼び出した関数が返したエラーに
必ず責任をもたないといけなくなる。
サンプルコードの例では、fooはメモリ確保1つ1つを、
正しいかどうか管理する、無駄な責任を負う。
呼び出し先のエラーコードを呼び出し元へ伝達することも
一つの責任だ。

そしてmain関数は、他の関数が責任を取れなかった
全ての例外に対する責任を負わないといけない。
エラークラスは必ずstd::exceptionを継承しているなら、
これをキャッチしてエラー内容を表示することができる。
だからintやstringを安易に投げてはいけない。
...では、main関数でキャッチしても、十分な責任を負えない。

385 名前:デフォルトの名無しさん :2001/05/16(水) 21:05
>>384
しまった、再帰が永久ループになってる。
単にメモリを確保する関数をさらに呼び出している、
と書きたかっただけなので、
以下のように読み替えてください。

foo()
{
 char *p1 = new char[256];
 char *p2 = new char[256];
 char *p3 = new char[256];
 char *p4 = new char[256];
 foo2();
 foo2();
}

foo2()
{
 char *4 = new char[256];
}

386 名前:デフォルトの名無しさん :2001/05/16(水) 22:10
>>385
もうちょっとおちつくアルよろし。
>char *4 = new char[256];
char *p4 = new char[256];

387 名前:デフォルトの名無しさん :2001/05/17(木) 13:18
ちょいごめん。
Perlの連想配列って、C++だと何になるの?

388 名前:デフォルトの名無しさん :2001/05/17(木) 13:23
mapかもな

389 名前:デフォルトの名無しさん :2001/05/17(木) 15:33
ハッシュのこと?

390 名前:デフォルトの名無しさん :2001/05/17(木) 21:27
http://www.amris.co.jp/cpp/c16.html
mapの解説>>387

391 名前:デフォルトの名無しさん :2001/05/18(金) 00:29
初期化にどうしても引数が必要なオブジェクトを
Singletonパターンでスマートに実装する方法ってありますか?
初期化メソッドを用意するしかないんですかね、ヤパーリ

392 名前:デフォルトの名無しさん :2001/05/18(金) 00:44
>>389
ハッシュテーブルをmapの実装手段にすることはあるけど…
連想配列の実装を、2本のvectorにしようと、2本の配列にしようと、
場合によってはBツリー使おうと、それは実装者の自由でしょ。

ハッシュ=mapつうのは、なんか勘違いしてるぞ。

393 名前:デフォルトの名無しさん :2001/05/18(金) 02:47
>392
一応フォローしとくとさ、389は単にPerlの連想配列ってハッシュのこと?
て聞いてんじゃねーの?最近(?)名前が変わった(連想配列→ハッシュ)らしーから。

394 名前:389 :2001/05/18(金) 09:35
すんません。
言葉足らずでした。
393さんの言うとおりです。

395 名前:デフォルトの名無しさん :2001/05/18(金) 15:56
>>392
ハッシュ値が得られないからmapの実装にハッシュは使えないと思う。

396 名前:VC++です :2001/05/18(金) 22:38
コンパイル時に配列の大きさがわからないという場面に出くわしたので、STLのvectorクラスを使うことにしました。
STLのvectorクラスは自分で作った構造体などは使えないんですか?
vector <oreno_kouzoutai> hoge;
などとやったらエラーが70出てきて、しょぼんとなりましたよ。

397 名前:デフォルトの名無しさん :2001/05/18(金) 22:58
エラーの内容をMSDNで調べろ。話はそれからだ。

3時間調べてわからなかったら、エラーの内容を正確に書いて再投稿せよ
話はそれからだ。
適切な回答が得られるかは、君の質問文作成スキルによるがな...

398 名前:デフォルトの名無しさん :2001/05/18(金) 22:59
C++の例外処理について質問があります。
どうもいまいち例外の使い方(上手な使い方)がわからないので困っています。

まずthrowする物について。
C++の本を見るとたいてい例外でエラー用のクラスをthrowしています。
そしてこれらの例外クラスはエラー別に分かれていると思います。
例外用のクラスを使って安全に開放するというのはわかります。

しかし、この例外クラスは何処に記述したらよいのだろうか?
と悩んでいます。

今は仮にAというクラスがあった場合Aクラス用の例外クラスを
Aクラスを記述してあるヘッダに記述しています。
しかし、エラーの種類別にクラスを作っているとそれだけ
名前空間を占有する事になります。(何かいまいち)

仮にnamespaceを使ったとしても、例外を受け取るのは
Aクラスの外の場合も多いと思うので、結局そのAクラスのヘッダを
インクルード & using...する事になると思います。
するとエラー用のクラスが多くなってごちゃごちゃしてしまいます。
さらにその他のクラスと同じような例外を通知するのに
同じような例外クラスを何個も作るのはいまいちなきがします。

それならばと各クラス共通の汎用的な例外クラスMemoryError等を作成したとします。
(例外専用ヘッダ&ソース作成。開放等はデストラクタ任せで主にエラーの通知に使う)
すると自作のクラスライブラリすべてでその例外クラスヘッダをインクルードする事になります。
それだと、各クラスのソース的なまとまりというかなんというか(説明下手でスイマセン)
そういうものが薄れてしまってやっぱりいまいちなきがします。

ながくなったので続きます。スイマセン

399 名前:デフォルトの名無しさん :2001/05/18(金) 23:10
つづきです。

自作例外クラスヘッダ等を複数のクラスからインクルードするのは抵抗があります。
それならば標準でついている例外クラスを派生させずにそのまま使うとします。
(標準ヘッダならある程度なっとくできるので)

しかしそれでは本当に文字列ぐらいしか通知できません。
わざわざクラスにする意味が薄れてしまいます。


例外にクラスを使うのは主にリソースの開放等安全に終了させるための物
だと思っています(まだよくわかってないですが)

そこでまた疑問が湧いてきます。
ある処理の途中で例外が発生した場合その例外以前で確保したメモリを
開放したり、安全な処理をさせなくてはなりません。

そしてそれらの事は例外クラスを使わなくてもデストラクタによって
適切に行われるのが理想だと思います。
するとやはり例外をクラスで投げる必要があるのだろうかと考えてしまいます。

そこでまた悩みが増えます。
オブジェクトが自分自身のデストラクタで安全に終了させるのが理想だと書きました。
そのためにはちょっとしたバッファをnewで確保する時にもSTLのauto_ptr等を
使用したり、ほぼすべての物をクラスで管理するべきなのだろうと悩みました。


まだつづきます(長文スイマセン)

400 名前:デフォルトの名無しさん :2001/05/18(金) 23:12
>>398-399
3行で要約しろ。話はそれからだ。

401 名前:デフォルトの名無しさん :2001/05/18(金) 23:20
続きです。
ここから書く事は若干別問題という気がしますが一応聞いてください。

結局のところC++はクラスとSTLを中心に作っていくのが正しいのだろうと
感じました。

・・・・しかし
この辺ちょっとあやふやなんですがSTLって一応C++的に標準なんですよね?
ところがSTLをサポートしていない環境というものがあります。

そこでauto_ptr的なものを自作するとします。
しかしそこでまた
「自作の汎用クラスをその他のクラスでインクルードするのはソース的なまとまりが無くなるような気がする」
という悩みが出てきます。
なんかC言語で作っている時とあまり変わらないような気がしてくるのです。

例外とはいかに使うのが正しいのかどなたかアドバイスをください。
お願いします。


・・・・・・STLを使えない具体例とはWindowsCEなのです。
そこでまた例外とSTLについて悩みが出てきました。

まだつづくんですがちょっとこれまでの質問とは別分野になるのでいったん切ります。

402 名前:聞こえてるか? :2001/05/18(金) 23:22
>>398-399 >>401
3行とはいわない。
4行で要約しろ。話はそれからだ。

403 名前:398 399 401 :2001/05/18(金) 23:26
>>400

長すぎですよね。(ごめんなさい)

1:例外の正しい使い方とは?
2:デストラクタで安全開放するのなら例外でクラスを投げる事にどのような有効利用があるだろうか?
3:例外用のクラスを多数追加する事に抵抗があるのですが普通なのでしょうか?

404 名前:396 :2001/05/18(金) 23:27
>>397
Roger. ・・・って俺(396)に向かって言ったんですよね?どちらにせよ、少し調べるのをさぼってました。
スイマセン。

405 名前:398 399 401 :2001/05/18(金) 23:28
>>402
400を見る前に401を書いていました。
(書いてる間に更新していなかったので時間差が・・・)

ごめんなさい。

406 名前:名無しさん :2001/05/19(土) 00:17
age

407 名前:名無しさん :2001/05/19(土) 00:17
age

408 名前:名無しさん :2001/05/19(土) 00:17
age

409 名前:名無しさん :2001/05/19(土) 00:18
age

410 名前:名無しさん :2001/05/19(土) 00:18
age

411 名前:デフォルトの名無しさん :2001/05/19(土) 00:30
>>406-410

?

412 名前:デフォルトの名無しさん :2001/05/19(土) 00:33
恐らくkylix相談室を荒らしたのと同一犯。

413 名前:396 :2001/05/19(土) 00:37
解決しました。vectorはテンプレート引数を比較するコードがあるのを発見しました。(というか、コンパイラが
教えてくれたエラー内容そのものです。何やら長いエラーメッセージだったので、読み飛ばしていました・・・)
するってえとvectorは、構造体は駄目なんですね。仕方なく構造体へのポインターにすることにより回避しました。

って言うか、これは完璧な一人相撲ですね。こういう幕引きは辛いものがあります・・・。

414 名前:デフォルトの名無しさん :2001/05/19(土) 00:49
>>413
struct Foo{ int m_nFoo };
std::vector<Foo> vecFoo;

はコンパイル通るだろ? なら「vectorは、構造体は駄目なんですね」とか言うな。

415 名前:デフォルトの名無しさん :2001/05/19(土) 01:36
>>413
構造体でも大丈夫だろ。
比較が必要なら比較のコードを書けばいいし、
クラスでも比較のコードを書かなかったら同じエラーが出る。

struct hoge
{
 int a, b, c;
 bool operator==(const struct hoge &x) const { return a == a.x && b == b.x && c == c.x; }
 bool operator!=(const struct hoge &x) const { return !(*this == x); }
 bool operator>=(const struct hoge &x) const { どっちが大きいのか、それは君が決めるしかない }
};

416 名前:デフォルトの名無しさん :2001/05/19(土) 01:40
bool operator==(const struct hoge &x, const struct hoge &y)
{
 return x.a == y.a && x.b == y.b && x.c == y.c;
}

417 名前:391 :2001/05/19(土) 02:12
できればどなたか>>391にも引導を渡していただけませんか。
人に言われるまであきらめきれないので・・・

418 名前:デフォルトの名無しさん :2001/05/19(土) 02:18
>>417
今どうやって Singleton の実装してる?

419 名前:通りすがりの名無し :2001/05/19(土) 02:21
>>417
俺にもわからん。
やっぱstaticな初期化メソッドを作って、それを呼んでもらうのが普通だよね。

プロキシ経由でしかアクセスできないことにして、
最初に生成されたプロキシが、
シングルトンのオブジェクトを作るというのはどう?

だけどそんな複雑にしてまで安全を確保する必要性があるのかなぁ。
気持ちはわからなくも無いけど。

420 名前:デフォルトの名無しさん :2001/05/19(土) 02:47
Game Programming Gems に載ってた方法だと、こんなのがある。こいつを
継承したクラスのインスタンスを、適当なところで new, delete する。

----------
template <typename T>
class Singleton
{
        static T* m_Singleton;
        Singleton(const Singleton&);        // コピー禁止
public:
        Singleton()
        {
                assert(m_Singleton == 0);
                int offset = (int)(T*)1 - (int)(Singleton <T>*)(T*)1;
                m_Singleton = reinterpret_cast<T*>(reinterpret_cast<char*>(this) + offset);
        }
        ~Singleton()
        {
                assert(m_Singleton != 0);
                m_Singleton = 0;
        }
        static T& GetSingleton()
        {
                assert(m_Singleton != 0);
                return (*m_Singleton);
        }
};

template <typename T> T* Singleton <T>::m_Singleton = 0;
----------

421 名前:391 :2001/05/19(土) 03:00
>>418
一般的なやり方だと思います。いわゆるprotectedメンバに
コンストラクタをおき、次のメソッドのみでオブジェクトを返すような。
Class * Class::instance = NULL; //staticメンバ
Class* Class::getInstance(){
    if( instance == NULL ){
        instance = new Class;
    }
    return instance;
}
まさか毎回getInstance( value );ってわけにもいきませんし…
>>419
レスありがとうございます。
> staticな初期化メソッドを作って、それを呼んでもらうのが普通
やはりこれですかね、ただ折角Cから移行してきた所なので悔しくて(笑
また初心者ながらにSingletonをサブクラス化したとき面倒そうかなと。
> プロキシ
なるほど、試してみます。

422 名前:391 :2001/05/19(土) 03:02
>>420
すいません、書き込んでて気づきませんでした
これはすごい、ちょっとじっくりみさせていただきます

423 名前:デフォルトの名無しさん :2001/05/19(土) 03:13
>>421
私なら条件変数を使わず、ローカル static 変数を使います。これだと
インスタンスを作成するタイミングは明確(初めて関数が呼ばれたとき)
ですが、インスタンスを壊すタイミングが明示的に指定できないので困
る場合アリ。

で、結局 >>420 に行き着くんだけど。

class Class {
public:
        static Class& GetInstance()
        {
                static Class obj;
                return (obj);
        }
};

#define g_Class Class::GetInstance()

424 名前:391 :2001/05/19(土) 03:47
>>420
なるほど、二つ目のインスタンスが作成される可能性をことごとく潰して
いるんですね。しかもテンプレートで使い回しがきき、どんな引数をとる
クラスであろうと対応できると。感動しました、C++にきて良かったです。
>>423
ふーむ、こんなやり方もあるんですね。NULLチェックが省けちゃうとは。
どのみちSingleton使うのは実行時の変更がなさそうなシステム領域のクラスが
多いから壊すタイミングに留意する必要はなさそうですしね。素晴らしい。
初期化なしのSingletonパターン適用クラスを作るときに使わせて頂きます。

識者のご指摘を伺えて今日は幸せでした。レス下さった方々に深く感謝です。

425 名前:デフォルトの名無しさん :2001/05/19(土) 04:49
幸せage

426 名前:デフォルトの名無しさん :2001/05/19(土) 20:34
class A
{
void f1();
void f2();
void f3();
};
このクラスにメンバ関数ポインタf0を追加して、
f1、f2、f3をf0を介して呼び出すようにしたいのですが
こういうことってどうすれば出来るのでしょうか?

427 名前:デフォルトの名無しさん :2001/05/19(土) 21:25
class A {
void (A::*f0)();
void test() { f0 = &f2; (this->*f0)(); }
};

428 名前:426 :2001/05/19(土) 21:47
>>427
その方法でうまくいきました。ありがとうございます。
ですがこうするとエラーになります。
なぜでしょうか?

// コンストラクタ
A()
{
f0 = &A::f1;
}

void main()
{
A* a = new A;
(a->*f0)();
delete a;
}

429 名前:デフォルトの名無しさん :2001/05/19(土) 21:57
(a->*a->f0)();

430 名前:426 :2001/05/19(土) 22:10
うまくいきました。
何度もありがとうございました。

431 名前:デフォルトの名無しさん :2001/05/19(土) 23:16
>>398
>>399
>>401

誰かこの質問に愛の手を
壁|_-)

432 名前:デフォルトの名無しさん :2001/05/19(土) 23:18
>>431
正しい引用の仕方>>398-401

433 名前:デフォルトの名無しさん :2001/05/19(土) 23:19
>>431
3 行とは言わないが、10 行程度にまとめて、論点を明確にせよ。
話はそれから。

434 名前:デフォルトの名無しさん :2001/05/19(土) 23:31
>「自作の汎用クラスをその他のクラスでインクルードするのはソース的なまとまりが無くなるような気がする」

気にすんな。
以上。

435 名前:デフォルトの名無しさん :2001/05/19(土) 23:44
>>434同意
C++はクラスをインクルードするのを前提に設計されたのだよ。
コンパイラの都合(性能の話)だそうだ。
どうしても隠したいならラッパーを作るしかないようだ。

>STLをサポートしていない環境
STLのヘッダをインクルードするだけで使えるものもあるが..だめか?
http://www.stlport.org/download.html
(SGI風iostream以外は大丈夫だったと思うぞ)

あまり悩むな。

436 名前:デフォルトの名無しさん :2001/05/20(日) 00:46
ちょっとお聞きしたいです。
クラスをエクスポートするDLLを作っているんですが、クラスのデータメンバにSTLを用いたものがいくつかあるん
です。しかしそれが問題らしく、stringやvectorの変数を宣言する行で警告を食らいます。警告内容はstringやvector
をエクスポートしろ、というものですが、これは無視していいんですか?

437 名前:デフォルトの名無しさん :2001/05/20(日) 00:54
>>436
DLLってWindowsでしょ?
こんなことしていいの?
リンクするランタイム違っただけで死んでしまわない?

438 名前::2001/05/20(日) 01:07
typedef list<PROCESSENTRY32> ProcessEntriesList;

つー、リストを

for_each(pel.begin(),pel.end(),&addProcessEntry);

つー、アルゴリズムに

void __fastcall TForm1::addProcessEntry(PROCESSENTRY32 pe)

を上記のように&渡ししたら動いちゃった・・・
いや、関数オブジェクト書くのがかったるくて適当書いたんだけど、
動いたことに驚いたのは初めて。(動いてて驚くソースは仕事で頻繁に見るけど)

これって処理系依存?BCB5なんだけど。

439 名前::2001/05/20(日) 01:19
追加情報。

addProcessEntry() って関数名だけど、単にリストを順処理させてる関数です。
なんかリスト追加する関数と誤解されそう。
名前付けセンスないなぁ俺。

440 名前:デフォルトの名無しさん :2001/05/20(日) 08:47
>>438
どこでも動く、非常に普遍的なコードに見えるっす。

441 名前:デフォルトの名無しさん :2001/05/20(日) 08:48
>>438
for_each(pel.begin(),pel.end(),&addProcessEntry);
この行がTForm1のメンバ関数の中にあるなら、
規格の範囲内で、コンパイラには依存しません。

要するに、
this->(&addProcessEntry(pe));
が成立すれば大丈夫ということ。

442 名前:デフォルトの名無しさん :2001/05/20(日) 10:02
>>438
「処理系依存」をどう捉えるかによって答えが異なる。

すなわち、「C++ の言語仕様の範囲内」なのか、
「(たとえば)VC でもビルドできる」のか。

前者だとすると(Win32 API な処理系と仮定しても)、
一部分だけ言語仕様から逸脱している。 → __fastcall

後者だとすると(勿論、必要な宣言がすべて正しく揃っているとして)、
「VC でもビルド可能」(たぶん)。

ただし __fastcall は C++ の言語では定義されていないので、
今仮に VC でもビルドできたとしても、
__fastcall な大域関数のアドレスを取得できるかどうかは、
将来の VC でも同じという保証はないと思う。

ちなみに(当たり前のことだけど)、
もし TForm1::addProcessEntry が仮想メンバ関数なら、
たとえその行が TForm1 のメンバ関数の中にあっても、
コンパイルエラーになるはず。
…だよね? >>441

などなど、もっと詳しい条件が定義されないと、「言語仕様内/外」とか、
「VC でもビルドできる/できない」は、一概には言えないと思う。

443 名前:436 :2001/05/20(日) 11:45
>>437
どういうことですか?すいません、まずい理由をもう少し詳しく教えてもらえるとありがたいところです。

444 名前:441 :2001/05/20(日) 15:27
>もし TForm1::addProcessEntry が仮想メンバ関数なら、
>たとえその行が TForm1 のメンバ関数の中にあっても、
>コンパイルエラーになるはず。
>…だよね? >>441

コンパイルエラーにはならないよ。
ちゃんと仮想関数としてコールされるから、
TForm1を継承してaddProcessEntryを書きかえたら、
書きかえたほうが呼ばれる。

__fastcallのことは、すっかり見落としてた(藁。
C++Builder使いなので許しておくれ。

445 名前:デフォルトの名無しさん :2001/05/20(日) 17:06
メンバの宣言のとき
privateって使ってます?
protectedとprivateの使い分けがいまいちわからない。
皆さんの意見を聞かせてください。

446 名前:初心者名無しさん :2001/05/20(日) 17:09
とりあえず、C++の入門書読み終えたんですけど
次はどんな本を購入すればいいんですか?
題名、著作者、出版社をできれば教えてください

447 名前:デフォルトの名無しさん :2001/05/20(日) 17:13
>>445
必要がない限りprivate。

448 名前:デフォルトの名無しさん :2001/05/20(日) 17:13
>>446
http://www.amazon.co.jp/exec/obidos/ASIN/475611895X/qid%3D985068930/249-3030546-3461946

449 名前:初心者名無しさん :2001/05/20(日) 17:27
>>448
た、高いっす

450 名前:デフォルトの名無しさん :2001/05/20(日) 17:44
>>449
「プログラミング言語 C++」はバイブル。C++ でプログラムを組むなら、手元に
置いておかないと話にならない。

7000 円分の価値はあるから、さっさと買え。

451 名前:初心者名無しさん :2001/05/20(日) 17:50
>>450
わかりました。
在庫切れみたいなので
デッカイ本屋行って買ってきます

452 名前::2001/05/20(日) 18:00
>>440-442

for_each() の実装が

template <class InputIterator, class Function>
Function for_each (InputIterator first, InputIterator last, Function f)
{
while (first != last) f(*first++);
return f;
}

だから

(&addProcessEntry)(*first++);

ってやってる事だと解釈したんだけど…
同じ事は C だと(Cと比べるのも問題あることは分かってるけど)

for_each(first,end,addProcessEntry)

と渡しといて、

(*addProcessEntry)(*first++);

で受けるよな〜(確か)と、いう点が疑問なんです。
関数のアドレスに関して、C++ではどういう解釈をすれば良いのかに悩んでいるのが現状です。
関数オブジェクト渡しならば()をオーバーロードしてるから分かるんですが。

そこらへんの解釈を理解するにはARM買って読むしかないのかな?

453 名前:デフォルトの名無しさん :2001/05/20(日) 18:57
fileのラッパークラス CFileを作ってと演算子のオーバーロードで

file >> MyClass; // load

見たいのをやりたいんですけど、 >> 演算子だと 右辺に新しいクラスが
来るたびに CFileクラス定義に追加しないといけないですよね?

グローバル関数で operator >> を定義 するのと
MyClass << file;
と逆向きにしてMyClass内でoperator<<を定義 するのとどっちがいいかな?

前者は operator>>関数が無数に出来るので、VC++とかのツールで見にくい(探し難い)
後者は 普通の使い方と逆ですよね??

どういう方法がいいでしょうか?

454 名前:デフォルトの名無しさん :2001/05/20(日) 19:09
あ、後者は
file >> MyClass >> MyClass2

とか、連続して書けないから駄目か

455 名前:デフォルトの名無しさん :2001/05/20(日) 20:28
すいません、friendの使い方について教えてください。

class A
{

classB
{
int i;
};

friend class B;
int i;
};
これだと問題なしなのに、

class A
{
friend class B;

classB
{
int i;
};

int i;
};
これだとfriend宣言が無視されます。エラーは出ません。

同様に、
class A
{
friend class B;
int i;
};

class B
{
int i;
};
これも無視されます。
何が悪いのでしょうか?
VC++5.0ラーニングエディションです。

456 名前:デフォルトの名無しさん :2001/05/20(日) 21:35
>>455
空のクラス宣言を前置せよ。

class B;
class A {
friend class B;
ほげほげ
};
class B {
ほげほげ
};

457 名前:デフォルトの名無しさん :2001/05/21(月) 00:08
>>456
アドバイスありがとうございます。
それを試したのですが、
同じようなソースなのに出来る場合があったり、
出来ない場合があったりします。
コンパイラが狂ってるのかなあ?

あとちなみにこういう場合はどうなんでしょうか?
class A {
friend class C;
ほげほげ
};

class B {

class C {
ぼげぼげ
}

ほげほげ
};

458 名前:デフォルトの名無しさん :2001/05/21(月) 00:19
Bの中のCは、Bの外(たとえばA)から見るとB::Cになるんでは?

class B {
public:
class C {
}
};

class A {
friend class B::C;
};

なら分からんでもない。
しかしキモいなあ。

459 名前:デフォルトの名無しさん :2001/05/21(月) 00:28
>>457
クラスのプロトタイプ宣言をしても駄目か?
class A;
class B;
class C;
を先頭に表記。

というか個々に定義して継承するか包含しないか?

460 名前:455 :2001/05/21(月) 21:49
>>458-459
度々お答え申し訳ないです。
>>458さんの方法でうまくいきました。
クラスのプロトタイプ宣言で class B::C;
と表記出来ればいいんだと思うんですが、こればかりは駄目みたいですね。
納得しました。ありがとうございました。

>というか個々に定義して継承するか包含しないか?
自分がネストしたがるのは、単にデベロッパスタジオのワークスペースのツリーが
見栄えが良くなるからです。それだけ。^^;

461 名前:デフォルトの名無しさん :2001/05/21(月) 23:47
const int x = 3;
const int y = 3;
int hairetu[y][x] = {
{1, 0, 0},
{1, 0, 0},
{1, 0, 0},
};
void proc(int x, int y, int **data)
{
int i, j;
for(i = 0; i < y; ++i){
for(j = 0; j < x; ++j){
data[i][j] = 0;
}
}
}
int main(int argc, char* argv[])
{
proc(x, y, (int**)hairetu);
return 0;
}
↑このプログラム実行時にエラー出ちゃうのですが
出ないようにする方法教えて下さい。

二次元配列を、
関数の引数として渡す方法が、分からないのです。

462 名前:ウンキョ :2001/05/22(火) 00:01
>>460
新しいフォルダ作ればいいのに

463 名前:デフォルトの名無しさん :2001/05/22(火) 00:50
>>438

void __fastcall TForm1::addProcessEntry(PROCESSENTRY32 pe);
が静的メンバ関数でないのなら、
for_each(pel.begin(),pel.end(),&addProcessEntry);
は完全に間違っている。

次のような特別バージョンが生成されると考えることができたとしよう。

typedef void (TForm1::*FUNCTION)(PROCESSENTRY32);
typedef std::list<PROCESSENTRY32>::interator INPUTITERATOR;

FUNCTION A_for_each(INPUTITERATOR __first, INPUTITERATOR __last, FUNCTION __f)
{
// 束縛されていないメンバ関数へのポインタからは呼び出せない。this->が天から振ってくることはない。
while (__first != __last) __f(*__first++);
return __f;
}

束縛後のメンバ関数へのポインタの型 というものはない。


関数オブジェクトの最も簡単なものが関数ポインタである。
__fastcallが暗黙にstaticを主張しているとコンパイラが考えるのは突飛だろうか。

次のような特別バージョンが生成される。

typedef void (*FUNCTION)(PROCESSENTRY32);
typedef std::list<PROCESSENTRY32>::interator INPUTITERATOR;

FUNCTION A_for_each(INPUTITERATOR __first, INPUTITERATOR __last, FUNCTION __f)
{
while (__first != __last) __f(*__first++);
return __f;
}

464 名前::2001/05/22(火) 01:10
>>463
そうなんです、&func が何で関数ポインタ?というのが疑問なんです。

ちなみに、疑問にお答えします。
静的メンバ関数ではありません。
しかし、for_each() はメンバ関数で実行しているので見えてます。
正確には &(this->func) でしたね。
指摘されるまでうっかり忘れてました。

多分この疑問も分かってしまえばな〜んだ、となるでしょう。

465 名前:デフォルトの名無しさん :2001/05/22(火) 01:35
>>461

配列が int hairetu[y][x] なのに、どーして
> void proc(int x, int y, int **data)
> proc(x, y, (int**)hairetu);
なんだよっ!

コンパイラの警告を無視するな(したはずだろ?)。

466 名前:Rip_Mapiro :2001/05/22(火) 01:57
>>461
template<Temp> //Tempは何らかの二次元配列
void
Proc(int x,int y,Temp data){
//省略
data[i][j];

}
と関数を定義して
proc(x,y,hairetu);
でコール。

本当は板違いだが++なレスで答えたぞ。

467 名前:onamae :2001/05/22(火) 02:37
>>465-466
わいもようわかりません。
こんなかんじだしょか。

#include <iostream>
using namespace std;
const int x = 3;
const int y = 3;
int array[][x] = {
{1, 0, 0},
{1, 0, 0},
{1, 0, 0}
};

template<class T>
void proc(int x, int y, T (*data)[3])
{
int i, j;

for(i = 0; i < y; ++i){
for(j = 0; j < x; ++j){
data[i][j] = 0;
}
}
}

int main(void)
{
proc(x, y, &array[0]);
return 0;
}

468 名前:デフォルトの名無しさん :2001/05/22(火) 03:02
>>464

>しかし、for_each() はメンバ関数で実行しているので見えてます。
見えない。for_eachはマクロではない。メンバ関数への
ポインタがthisに暗黙に束縛されることはない。

>正確には &(this->func) でしたね。
不正確だ。束縛された非静的メンバ関数へのポインタは
()オペレータ以外に使えない。
多くの場合コンパイラはthis->を無視するだろう。

>静的メンバ関数ではありません。
その関数に非静的メンバ変数を参照する文を追加するとどうなるだろうか?
確かにstaticでないなら、実装依存というより
マクロ的に実装しているコンパイラの不具合と言えるかもしれない。

469 名前:Rip_Mapiro :2001/05/22(火) 03:16
>>466訂正:
template<Temp> -> template<class Temp>
Proc(int x,int y,Temp data){ -> proc(int x,int y,Temp data){

470 名前:onamae :2001/05/22(火) 04:30
>469
質問君なわいにもわかりました。ありがとうございます。

471 名前:387 :2001/05/22(火) 12:29
どうも、お久しぶり。
で、連想配列(ハッシュ)ですが、C++自体にはないが、
プログラマーの考えでどうにかなる、というものでしょうか?

472 名前:デフォルトの名無しさん :2001/05/22(火) 14:45
だからmapじゃだめなの?>>471

473 名前:>387 :2001/05/22(火) 15:26
だから STL にあるって...
大抵の環境では std::hash_map が用意されてる。
でも std::map でも普通は十分だし、
hash_map の方が遅いケースもある。

474 名前:387 :2001/05/22(火) 17:35
了解。

475 名前:デフォルトの名無しさん :2001/05/22(火) 20:29
C++標準にstd::hash_mapは存在しない。
SGIのSTL実装には含まれる。

476 名前:あたま :2001/05/22(火) 20:29
DirectXを用いてラインからリアルタイムに音波形表示するにあたって何かよい方法ってありますか?
MSC++4.0とDirectXSDK8.0なのですが・・・

477 名前:デフォルトの名無しさん :2001/05/22(火) 22:41
>>476
DirectX8は、VisualStudio5.0SP3以上じゃなきゃ
駄目じゃなかったけ?

478 名前:461 :2001/05/22(火) 23:19
>>466さん
エラー無しで、完璧に動いてくれましたです。
有難うございますぅ〜

479 名前:デフォルトの名無しさん :2001/05/23(水) 00:23
>>478
それじゃ結局多次元配列の使い方はわからないままじゃん。
いーのかそれで。
つっても俺もわからんかった。
これで正解なの?

const int x = 4;
const int y = 3;
int hairetu[y][x] = {
{1, 2, 3, 4},
{1, 2, 3, 4},
{1, 2, 3, 4},
};
void proc(int x, int y, int* data)
{
int i, j;
for(i = 0; i < y; i++){
for(j = 0; j < x; j++){
*data++ = 0;
}
}
}

int main(int argc, char* argv[])
{
proc(x, y, (int*)hairetu);
return 0;
}

480 名前:デフォルトの名無しさん :2001/05/23(水) 00:47
>>478>>479
君らC-faqって知ってるか?

481 名前:461 :2001/05/23(水) 00:55
>>480
C-faq?
Cの参考書ですか?

482 名前:480 :2001/05/23(水) 01:02
>>481
その何でも人に聞こうという姿勢を何とかしようよ。
検索すればすぐに見つかるんだからさ。世の中親切な人ばかりじゃないよ。

483 名前:デフォルトの名無しさん :2001/05/23(水) 01:06
C-FAQは、↓参照
http://piza.2ch.net/test/read.cgi?bbs=tech&key=989929288&st=1&to=1&nofirst=true

484 名前:461 :2001/05/23(水) 01:16
>>482-483
親切な人、有難う。

485 名前:あたま :2001/05/23(水) 01:57
>477さん
あれ、そうでしたっけ?
そうしたらSDKの7で製作しますがどんなもんでしょうか?

486 名前::2001/05/23(水) 02:28
>>468
>見えない
それは、呼びもと(もしくは展開元)側では見えても、for_each()内部では見えないはずだ
という意味なのでしょうか?
464はメンバ関数内で別のメンバ関数を見ているのだから見えるという意味で書きました。

>非静的メンバ関数へのポインタは()オペレータ以外に使えない
そ・・・そうなのか。知らなかったです。

やっぱりARM買って読んどかないとまずいかな。

487 名前::2001/05/23(水) 02:35
>>468
>その関数に非静的メンバ変数を参照する文を追加
フォーム上のリストボックス(当然非静的メンバ変数)に->add()してますから、既に存在してます。
あ、だったら当然に動的メンバ関数じゃなきゃ駄目じゃん。
・・・は、今ごろ理解が進んだ。
そうか、動的メンバ関数なら隠された引数(this)が必要なはずだから、関数ポインタだけ渡しても
呼べるはずが無い。
だから変だと言われていたわけですね。

488 名前::2001/05/23(水) 03:03
おかしいですね・・・ソースの必要部分載せときます。
コンパイルオプションの警告設定はデフォルト指定の選択モードですが、コンパイル・リンク
などのエラーなしです。

// ProcessEntriesList定義
typedef list<PROCESSENTRY32> ProcessEntriesList;
// ProcessEntries
class ProcessEntries {
private:
public:
ProcessEntriesList& ProcessEntries::getEntriesList(ProcessEntriesList& EntriesList);
};
ProcessEntriesList& ProcessEntries::getEntriesList(ProcessEntriesList& EntriesList)
{
EntriesList.clear();

HANDLE ph = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (ph<0) return EntriesList;

PROCESSENTRY32 pe;
AnsiString str;

pe.dwSize = sizeof(PROCESSENTRY32);
Process32First(ph, &pe);
EntriesList.push_back(pe);

while (Process32Next(ph, &pe)) EntriesList.push_back(pe);
CloseHandle(ph);
return EntriesList;
}
// TForm1定義
class TForm1 : public TForm
{
__published: // IDE 管理のコンポーネント
TListBox *ListBox1;
TTimer *Timer1;
void __fastcall Timer1Timer(TObject *Sender);
private:
void __fastcall addProcessEntry(PROCESSENTRY32 pe); // ユーザー宣言
ProcessEntries pe;
public: // ユーザー宣言
__fastcall TForm1(TComponent* Owner);
};

// メンバ関数
void __fastcall TForm1::addProcessEntry(PROCESSENTRY32 pe)
{
AnsiString str;
ListBox1->Items->Add(str.sprintf("%d : ",pe.th32ProcessID) + pe.szExeFile);
}
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
ListBox1->Clear();

ProcessEntriesList pel;

pe.getEntriesList(pel);
for_each(pel.begin(),pel.end(),&addProcessEntry);
}

489 名前:デフォルトの名無しさん :2001/05/23(水) 03:34
 まだC++の勉強始めて4日ぐらいなんですけど、Cに比べて機械語との
対応関係が見えにくいってことはないですか? 慣れればそんなことない
んかな。っていうか、そんなこと考えるような時代じゃないのか?

490 名前:デフォルトの名無しさん :2001/05/23(水) 06:32
ttp://www.csc.titech.ac.jp/~j91831/document/callback.html
なるほど。確かに、addProcessEntryは、普通のメンバ関数ではなかったのだ。
addProcessEntryは、__fastcall指定によって、
こっそりとレジスタからthisポインタを取り出し、あたかもメンバ関数のように動作する。
コンパイラからは、普通の関数、静的メンバ関数に見えるに違いない。

この動作は、TForm1ポインタをコンストラクタ引数に取る関数オブジェクトを使用するのに似ている。
__fastcall指定がほとんど決定的で、__fastcallを使っている以上、
そのテクニックを使っても当然だという人もいるだろう。

ちなみに、VC++では、__fastcallにこれほどの意味はなく、もちろんエラーとなる。

491 名前:デフォルトの名無しさん :2001/05/23(水) 21:57
>>489
見えにくいだけで、見ることは出来る。
むしろ、オブジェクト指向言語の中で、
最も「マシン語コードがどうなるか丸見え」のはC++。

C言語しか使ったことがない人は、
動きが把握できなくて不安になるかもしれない。
それは単に新しい言語だから知らないことが多いというだけで、
わかってみれば大した事は無い。

492 名前::2001/05/24(木) 00:21
>>490
メンバ関数とはいえ、addProcessEntry()はコールバック関数ではないので、
オブジェクトインスタンスは存在しないはず・・・
こ、こりはもしかしてEAXレジスタのゴミ(この場合thisポインタ)が偶然に効いて
実行できたという話でしょうか?(呼び元のTimer1Timer()はコールバック関数だけど)

493 名前:デフォルトの名無しさん :2001/05/24(木) 05:02
>>492
addProcessEntryもTimer1Timerも静的メンバ関数という意味で
コールバック関数であり、メンバ関数ではない。
もはや君に言うべき言葉を見つけられない。
addProcessEntryは静的メンバ関数である。
暗黙にthisポインタを使用することができることがまさに
非静的メンバ関数であると主張できるが、コンパイラが
そうとは思っていない以上、さらに、__fastcall指定が
存在していることから、非静的メンバ関数ではない。
何度でも言うがaddProcessEntryは静的メンバ関数である。

494 名前::2001/05/24(木) 19:12
>>493
静的メンバ関数か否かは突き詰めればthisポインタ参照可能か否かに左右されるの
では無いのですか?(もしくはthisポインタ参照不要)
どう実装しているかは関係ないと思われますが。

現に静的メンバ関数にしてしまうと、当然に
E2231 メンバー 'member' はオブジェクトなしでは使用できない  コンパイラエラー
が発生してコンパイルできません。
というようにコンパイラは非静的メンバと認識しています。

以上から__fastcall宣言は静的メンバ関数とは無関係な宣言と思われます。

495 名前:デフォルトの名無しさん :2001/05/25(金) 00:28
>>494
それは私の言ったことを逆から言っているように見える。
私は、束縛なしに利用できるのだから静的メンバ関数に違いないと主張する。
束縛なしに非静的メンバ関数へのポインタを使用できるなら不正である。
これがメンバ関数ではないことを証明するかどうかは確かに不明瞭のように見える。
しかし、考えてほしい。もし正確にメンバ関数ならば、__fastcall指定がなぜ必要なのか?

束縛なしに利用できるなら、その関数へのポインタは、文字通り静的である。
そこで表現を和らげ、実装として静的メンバ関数である、というのは同意できると考える。
実際、これは水掛け論のように思える。__fastcall指定の存在自体がそれを暗示する。

ここで質問に答えなければならない。
__fastcallゆえ、Timer1Timerを呼ぶ際に、thisポインタがレジスタへプッシュされる。
その中で、for_eachに、ある関数へのポインタを渡す。
ある関数へのポインタは、__fastcallゆえ、残っていたthisポインタをそれが何かを気にせずポップして使用する。
これはTimer1Timerから呼ぶ以上、レジスタにたまたま残っているわけではないので、
実装として完全に正しいだろう。
言語としては、束縛なしに非静的メンバ関数へのポインタを使用することは不正である。

496 名前::2001/05/25(金) 01:17
>>495
>これはTimer1Timerから呼ぶ以上、レジスタにたまたま残っているわけではないので
なるほど。最適化のせいとすればゴミとは意味が変わってきますね。了解しました。


しかし、__fastcallのせいとも言えないのではないかという状況になってきました。
以下のコードを見てください。
これがBCBだと何故かやっぱり動いてしまうんです。

#include <stdio.h>
#include <list.h>
#include <algorithm>
typedef list<int> IntList;
class ForEachTest {
IntList il;
public:
ForEachTest() {
for ( int i=0 ; i<10 ; i++ ) {
il.push_back(i);
}
}
void PrintList(int i) {
printf("%d\n",i);
}
void DumpList() {
for_each(il.begin(),il.end(),&PrintList);
}
};
int main(int argc, char* argv[])
{
ForEachTest fet;
fet.DumpList();
return 0;
}


ちなみに手元のUNIX機では当然にコンパイルできません。
bash-2.02# g++ -v
cc -v
gcc version 2.7.2.1
bash-2.02# g++ ForEachTest.cpp
/usr/include/g++/algo.h: In function `void (ForEachTest::* for_each(class list<int>::iterator, class list<int>::iterator, void (ForEachTest::*)(int)))(int)':
/usr/include/g++/algo.h:65: warning: argument passing to `ForEachTest *' from `int' lacks a cast
/usr/include/g++/algo.h:65: too few arguments to function



経緯はともかく結論として、&addProcessEntryをfor_each()に渡すのは、やっぱり
怪しすぎるコードである。
ということだけは間違いないですね。

intel系のアセンブラコードを読めれば、BCBの謎は解明できると思うのですが、私は読めないので
どうにもお手上げです。

497 名前:デフォルトの名無しさん :2001/05/25(金) 04:14
>>496
なるほど私は、ただ踊らされているだけのようだ。
addProcessEntryは__fastcall指定のコンパイルオプションが
あったとしてもメンバ関数である。
だが依然として、実装として静的メンバ関数であることは
それほど間違っていないと言う。
私は__fastcall指定をなくすコンパイルオプションがあると信じるが、
for_each(pel.begin(), pel.end(), &addProcessEntry);
を許してしまうのは、明かにそのようなコンパイラの不具合と断言でき、
thisポインタをレジスタを介して渡すメカニズムのために、たまたま動く。

498 名前:デフォルトの名無しさん :2001/05/25(金) 05:10
OS(Linuxとか、Winとか*BSDとかOSX)って、C++でかけるのかな。
すくなくとも、Linux はCでしょ。

499 名前:デフォルトの名無しさん :2001/05/25(金) 10:56
Beは++らしいでぇ

500 名前:デフォルトの名無しさん :2001/05/25(金) 11:19
class A、struct Bがあったとして、

Aのメンバ関数の返り値にBを使いたいんだけど
BのメンバにAも入れたい・・・
どうすればいいんでしょ??


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