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


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

C++相談室 part28
251 名前:デフォルトの名無しさん :04/03/10 14:00
言語の問題じゃないと思う。Javaは悪くないし、C++もそれほど良くない。
学者にでもなれば?と思うんだけど。

252 名前:デフォルトの名無しさん :04/03/10 14:04
BYTE型の値を、16進ダンプしたいと思っています。

BYTE b=19;
cout << hex << b << endl;
とやってみたのですが、文字化けしてしまいます。
なんででしょうか?


253 名前:デフォルトの名無しさん :04/03/10 14:06
>>252
BYTEってのは中身は(unsigned) charだろ。つまり文字として出力されてしまう。
intに格上げしる。
cout << hex << (b & 0xff) << endl;
みたいに。

254 名前:sage :04/03/10 14:10
>>249
論文なり、プログラム作品は持ってる?

255 名前:デフォルトの名無しさん :04/03/10 14:14
>>253
> cout << hex << (b & 0xff) << endl;
これでは意図が不明確なので、static_cast<int>(b)の方が良いと思う。

256 名前:デフォルトの名無しさん :04/03/10 14:30
int(b)で十分

257 名前:243 :04/03/10 14:36
>>246
>>247
ありがとうございました
>>248
具体的な解決策までどうもありがとうございました
問題が解決しました

258 名前:252 :04/03/10 14:38
253さんの方法でいけました。

intにしちゃうと2バイトなので、0xff00みたいになってしまいました。
「0xff」だけで出力したかったのです。

259 名前:デフォルトの名無しさん :04/03/10 14:41
Here is an unko.

260 名前:デフォルトの名無しさん :04/03/10 16:29
STLのmapの中味って、二分木ですか?
登録時にバランス化されますか?
登録コストはlog nですか?

mapエントリ削除、編集のコストはどうですか?
このときも逐一再バランスされますか?


261 名前:249 :04/03/10 16:38
>>251
学者というよりは目先の金ってタイプなもんで…。
Visual C++などのマイクロソフト系に
行きたくないんですが、それでは
就職は難しいのでしょうか?

262 名前:デフォルトの名無しさん :04/03/10 17:43
>>261
マ板行けよ

263 名前:デフォルトの名無しさん :04/03/10 19:02
#include <complex>
#include <iostream>

inline complex<double>&
operator+=(complex<double>& c, double dval)
{ return c += complex<double>(dval); } // ←ここが再帰的な定義になってる?

inline complex<double>&
operator++(complex<double>& c)
{ return c += complex<double>(1.0); }

int main()
{
using namespace std;
complex<double> purei(0, 2);
cout << purei << endl;

complex<double> real(2);
cout << real << endl;

// error ...
// by default, only += complex object
// ok; overloaded instance
purei += 1; cout << purei << endl;
++purei; cout << purei << endl;
purei += real; cout << purei << endl;
}
このコードがgcc-3.3.2では処理途中でアボーンします。
何が間違っているんでしょうか?C++Primerのサンプルコードです。

264 名前:デフォルトの名無しさん :04/03/10 19:08
すっとぼけてました。
エラーメッセージ見逃してました。。。

complex.C:11: error: syntax error before `&' token
complex.C:15: error: syntax error before `&' token
complex.C: In function `int main()':
complex.C:32: error: no match for 'operator++' in '++purei'

普通のシンタックスエラーですね。失礼しました。

265 名前:デフォルトの名無しさん :04/03/10 19:20
>>260
二分木である必要は必ずしもないが、規格で決まった計算量の
要求を満たすデータ構造が事実上なんらかのバランス木しかないので、
実際の実装はほとんど全て二分木。B木とかを使う実装もあるかもしれん(知らんけど)

> 登録コストはlog nですか?
> mapエントリ削除、編集のコストはどうですか?
http://www.sgi.com/tech/stl/Map.html

266 名前:デフォルトの名無しさん :04/03/10 19:22
>>249
なんで大学卒業しといて
> そこで質問なんですが、C++に将来性はあるのでしょうか?
> またC++のどのあたりを勉強したら就職に役立つでしょうか?
> あとOSはRedhatのFedoraを使ってるんですが、
> コンパイラーは何がいいんでしょうか?
そんなことくらい自分で答えを出せないのか?そりゃ職もないだろう。

267 名前:デフォルトの名無しさん :04/03/10 20:28
>239
デストラクタを起動するために配列のオブジェクトの数が必要なため、
たいていの実装では、数を格納する4Byteを余分に確保する。
そのため、デストラクタのあるオブジェクトのplacement new[]では、
与えるポインタと返されるポインタがずれる。

>241
どうでもいいけど
>operater new[](5 * sizeof(c));
>delete [] buf;
個人的に、単なるメモリ確保には
operator new(5 * sizeof(c));
operator delete(buf);
こっちを押したい

268 名前:デフォルトの名無しさん :04/03/10 21:59
>>265
> 実際の実装はほとんど全て二分木
たいてい赤黒木やね。


269 名前:デフォルトの名無しさん :04/03/10 22:40
>>249
ただの言語ヲタに仕事なんか無ぇよ。
OSの細かいことやらハードウェアやらネットワークやらの勉強をするか、
アプリの対象となるなんらかの専門分野の勉強をしれ。

270 名前:デフォルトの名無しさん :04/03/10 22:49
>>267
237の場合、
static void* operator new[] (size_t size,void* mem_p)
の中では size = 24 になってるから
5*sizeof(XX) = 5 * 4 = 20 でなく
24バイト確保せよということですよね?

242で指摘されてるように
new演算子を呼び出す前にこのメモリ分を確保してから呼び出さなきゃいけないとしたら
値が容易には推測できない気がする(コンパイラ、環境、デストラクタの有無)のですが、
何かスマートな方法があるor勘違いをしているのでしょうか?
(More Effective C++は持っていません。スイマセン)

271 名前:デフォルトの名無しさん :04/03/10 23:02
* で、半径1の円を30倍にして表示させたいんですが、どんなプログラムになりますか?
勉強しはじめでもわかるぐらいな、簡単な感じでお願いします。

272 名前:デフォルトの名無しさん :04/03/10 23:05
http://pc2.2ch.net/test/read.cgi/tech/1078157730/185
マルチやめれ
つーか自分の質問の仕方の悪さすら気づかないのか……?

273 名前:デフォルトの名無しさん :04/03/10 23:15
>>269
C++コンパイラ屋として食っていくつもりなのかもよ

274 名前:デフォルトの名無しさん :04/03/10 23:31
using boost::mpl::enable_if;
template <class T>
typename enable_if<boost::is_integral<T>, void>::type
foo(T t) {}

こんな風に使えるtypename演算子ですが、gccにあるtypeof演算子とは
どういった点で異なるんでしょうか?

275 名前:デフォルトの名無しさん :04/03/10 23:42
>>273
その場合でもOSに詳しくなければかなり厳しいだろ。

276 名前:デフォルトの名無しさん :04/03/10 23:43
つーかスレ違いなんだから構うなよ

277 名前:デフォルトの名無しさん :04/03/10 23:46
>>274 typenameは演算子じゃありません。

278 名前:デフォルトの名無しさん :04/03/10 23:50
>>274
月とすっぽんぐらい全然違う.
typenameはtemplate引数で与えられた識別子が型名であることを
コンパイラに明示するためのもの.
一方typeofはインスタンスの型を得るもの.

template<typename T> class C{};
C<int> a;
typeof(a) b; // C<int> b; と同じ


279 名前:デフォルトの名無しさん :04/03/11 00:07
>>277,>>278
なんとなくですがわかりました。ありがとうございました。


280 名前:249 :04/03/11 00:54
>>269
あんた、なんかいいこと書いてくれましたね。
で、もうちょっと教えてもらいたいんですが、
"アプリの対象となるなんらかの専門分野"って
具体的にどんなものなんでしょうか?

281 名前:デフォルトの名無しさん :04/03/11 01:05
>>280 放置確定。スレ住人の協力を切に願う。

282 名前:デフォルトの名無しさん :04/03/11 01:12
>>281
同意

283 名前:デフォルトの名無しさん :04/03/11 01:21
>>262読んでも去らないんだから、放置するのがベストだな

284 名前:デフォルトの名無しさん :04/03/11 01:27
>>281-283
荒らすな

285 名前:デフォルトの名無しさん :04/03/11 02:22
あのぉ・・・クラステンプレートのメンバクラステンプレート(と呼べばよいのかな?)を
クラススコープの外で定義するにはどうすれば良いのでしょうか?
書き方が分かりません・・・

template<typename T1> class C1{
template<typename T2> class C2;
};

// ここでclass C1<T1>::C2<T2>を定義したいのですが書き方が分かりませんヾ(;´Д`)ノ゛

286 名前:デフォルトの名無しさん :04/03/11 02:38
template<typename T1>
template<typename T2>
class C1<T1>::C2<T2> {
  ...
};

287 名前:285 :04/03/11 02:53
>>286
おぉ,こんな書き方になるんですね.相変わらずC++は奥が深いなぁ・・・
ありがとうございました.ちなみに<T2>は要らないですよね?
これがあると怒られます@MSVC++7.1(無い方が文法にかなってますし)

template<typename T1> template<typename T2> class C1<T1>::C2{/**/};


288 名前:286 :04/03/11 02:56
>>287
> ちなみに<T2>は要らないですよね?
すまんミスった。

289 名前:デフォルトの名無しさん :04/03/11 06:32
>270
1.placement new[]を使わない
2.何も考えずに+4余分に確保する
3.一度試しで作って(要素二個ぐらいで)ずれを調べる
俺が思いつくのはこれぐらいか

290 名前:デフォルトの名無しさん :04/03/11 12:23
>>281-283
一人でお疲れさんです。

291 名前:デフォルトの名無しさん :04/03/11 14:07
たとえば、
enum Month { January=1,February,March,…,December}
という列挙型があるときに
出力をJanuaryとかアルファベットで表示する方法はありますか?

292 名前:デフォルトの名無しさん :04/03/11 14:21
>>291
int January = 1;
という整数型があるときに、
出力をJanuaryとかアルファベットで表示する方法はありますか?

293 名前:デフォルトの名無しさん :04/03/11 14:23
>>291
マクロ使え

294 名前:291 :04/03/11 14:33
#defineですか?

295 名前:デフォルトの名無しさん :04/03/11 14:38
>>291
#include <iostream>

using namespace std;

enum AAA { BBB, CCC, DDD, };

ostream& operator<< (ostream& o, AAA e) {
  switch (e) {
    case BBB: o << "BBB"; break;
    case CCC: o << "CCC"; break;
    case DDD: o << "DDD"; break;
  }
  return o;
}

int main (int c, char**v) {
  cout << BBB << endl << CCC << endl << DDD << endl;
  return 0;
}

296 名前:デフォルトの名無しさん :04/03/11 14:40
enum Month { January=1,February,March,…,December};
const char* s[] = { "", "January", 略 };
Month e = 略;
cout << s[e] << 略

297 名前:デフォルトの名無しさん :04/03/11 14:42
enumの要素から名前(文字列)を取得する方法はない。
テーブルでも用意してindexで取得するしかない。

範囲外や疎な値を含む場合はmapでも使うといいだろ。
その場合には値->文字列の対応にプリプロセッサの文字列化が使える。

298 名前:デフォルトの名無しさん :04/03/11 14:52
ありがとうございました。

299 名前:デフォルトの名無しさん :04/03/11 16:00
C#だとその辺簡単なんだよね

300 名前:デフォルトの名無しさん :04/03/11 16:29
そこでマクロプログラミングですよ

301 名前:デフォルトの名無しさん :04/03/11 16:35
>>300
マクロでスマートに書けるか?

302 名前:デフォルトの名無しさん :04/03/11 16:37
単に、月名の列挙型を12個用意するだけでなく、
INVALIDな列挙値も1つ用意しておく事をお勧めする。
変数はその値で初期化しておくのがベスト。

303 名前:デフォルトの名無しさん :04/03/11 16:38
libcに依存しない、というかlibcをテンプレートライブラリとして
実装したら、C++ってUNIX上でも最強じゃない?動的リンクの
コストもゼロ。とろくさいGC付きの仮想マシンも要らない。
OSごとの差異はポリシーとして切り出せれば。

304 名前:デフォルトの名無しさん :04/03/11 16:40
>>302
>>291の例ならMonth(0)が使えるよな。

305 名前:デフォルトの名無しさん :04/03/11 17:43
マクロで…

#define MONTH M(InvalidMonth) M(January) M(February) M(March) … M(December)
#define M(s_) s_ ,
enum Month { MONTH };
#undef M
#define M(s_) #s_ ,
const char* strMonth[] = { MONTH };
#undef M

Month m = March;
cout << strMonth[m] << endl;


306 名前:デフォルトの名無しさん :04/03/11 18:05
std::mapでも使った方が簡単。マクロは汚ねー

307 名前:デフォルトの名無しさん :04/03/11 18:22
#include "boost/preprocessor/seq/enum.hpp"
#include "boost/preprocessor/seq/for_each.hpp"
#include "boost/preprocessor/stringize.hpp"

#define CASE_STATEMENT(r, _, elem) case elem: ost << BOOST_PP_STRINGIZE(elem); break;
#define PRINTABLE_ENUM(name, memberseq) \
    enum name{ BOOST_PP_SEQ_ENUM(memberseq) }; \
    ::std::ostream &operator<<(::std::ostream &ost, const name n) {\
        switch(n) { \
            BOOST_PP_SEQ_FOR_EACH(CASE_STATEMENT, _, memberseq)\
            default: ost << int(n); \
        } \
        return ost; \
    }

#include <iostream>

PRINTABLE_ENUM(Month, (Nullmonth)(January)(February)(March))

int main()
{
    Month m = January;
    std::cout << m << Month(0) << March;
}

どうせマクロ使うならこれくらいやらないとな。

308 名前:デフォルトの名無しさん :04/03/11 18:27
すげえ

309 名前:デフォルトの名無しさん :04/03/11 18:54
DirectSoundのラッパーライブラリ(DLL)を作成しています。
一通りのプログラムが完了し、デバッグをしてみたらデストラクタが呼ばれてない事が判明しましました。
"virtual"はもちろん指定しているのですが何か足らない点等があるのでしょうか?
以下にソース(抜粋)を載せておきますので、どうか宜しくお願いします。

//DirectSoundオブジェクトのインターフェイス
DECLARE_INTERFACE(ISoundManager)
{
  STDMETHOD_(BOOL, Initialize)(THIS_ HWND, BOOL, DWORD) PURE; //DirectSound初期化処理
  STDMETHOD_(void, Release)(THIS) PURE;                 //DirectSound解放処理
  //...
};

//DirectSoundオブジェクトを管理するクラス
class CSoundManager : public ISoundManager{
private:
  //メンバ変数
  //...
public:
  CSoundManager(void);
  virtual ~CSoundManager(void);

  BOOL __stdcall Initialize(HWND, BOOL, DWORD); //DirectSound初期化処理
  void __stdcall Release(void);              //DirectSound解放処理
  //...
}

310 名前:デフォルトの名無しさん :04/03/11 18:57
//ISoundManagerインターフェイスを作成する(DLLを使用するアプリが呼び出す)
extern "C" BOOL __stdcall CreateSoundManager(ISoundManager** ppSoundMgr)
{
  (*ppSoundMgr) = new CSoundManager;

  return (*ppSoundMgr) != NULL;
}

//ISoundManagerインターフェイスを破棄する(DLLを使用するアプリが呼び出す)
extern "C" void __stdcall DestroySoundManager(ISoundManager** ppSoundMgr)
{
  delete (*ppSoundMgr); //CSoundManager::~CSoundManager が呼ばれない
}

311 名前:デフォルトの名無しさん :04/03/11 19:34
>>310
C++っていうよりWindowsネタな感じだが…

ちゃんとAddRef, Releaseで参照カウントして
Releaseの中でdelete thisすればいいんでないか。

仮想デストラクタは、あくまでも親側のクラスに宣言(定義)されてないと呼べない。
DECLARE_INTERFACEマクロの中身は知らんが、仮想デストラクタが
定義されてないんじゃないか? もしそうなら実装クラスでvirtualつけても無駄。

312 名前:デフォルトの名無しさん :04/03/11 19:40
抜粋は気を付けて欲しいなあ
~ISoundManager() が仮想なのかわからないんだけど……。

CSoundManager のデストラクタが呼ばれてないっていうけど
別のデストラクタは呼ばれてる?
そもそもどういう手段でそれを確認したかないとこれだけじゃ判断つきにくいな。

とりあえず基本的な確認事項として
ポインタがNULLでないか、
不正なポインタ渡していないか( delete されてもたまたま動いている)
なんかはチェックした?

それとテストはDLLの形でしてるの?
その場合、基本的な単体テストなんかはきちんと通ってるの?

313 名前:デフォルトの名無しさん :04/03/11 19:52
~ISoundManager() がvirtualになってないに一票

314 名前:デフォルトの名無しさん :04/03/11 20:36
追加で1票

315 名前:デフォルトの名無しさん :04/03/11 22:18
審査員だから5票入れとくね

316 名前:デフォルトの名無しさん :04/03/11 22:19
無効票入れとく

317 名前:デフォルトの名無しさん :04/03/11 22:20
エビフライ入れとく

318 名前:デフォルトの名無しさん :04/03/11 22:39
>309
詳細不明な俺マクロをやめろ。
メンバ関数に__stdcallってなに?
BOOL返すだけならCreateはポインタを返せよ。
Destroyはポインタのポインタを受け取る必要ないだろ。

319 名前:デフォルトの名無しさん :04/03/11 22:45
>>318
このスレだから仕方ないけど・・・

320 名前:デフォルトの名無しさん :04/03/11 23:09
>>311-319
スレ違いでしたか、失礼しました。
取り合えず、参照カウンタを保持してやることにしました。

あと、ISoundManager::~ISoundManagerを実装すると、
interfaceではなくclassになってしまい、Cで使えなくなってしまうのでちょっと都合が悪かったりします。

ちなみに、DECLARE_INTERFACEは俺マクロでないです。
マイクロのヘッダにあるマクロです。

さておき、レスありがとうございました。

321 名前:デフォルトの名無しさん :04/03/11 23:18
このスレは C スレと違って
環境依存な話を禁止する条項が書かれてないんだよな。
でも、環境依存を避ける傾向はあるから、
>>318 みたいに COM プログラミング知らない人がいるのも
仕方がないかもね。

COM スレは寂れてるっぽいし、
次からは↓のスレで聞くのがいいと思う。

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

322 名前:デフォルトの名無しさん :04/03/11 23:24
>320
意味がわからん。CSoundManager::~CSoundManager()を実装して、
CSoundManager::Release()から参照カウント方式でdelete this使って
呼び出せ、という話だろ。ISoundManager::~ISoundManager()は
宣言してはいけない。

323 名前:デフォルトの名無しさん :04/03/12 00:26
>>321
ご丁寧にありがとうございます。

質問させて頂いた件ですが、
reinterpret_castを使ってダウンキャストをしてからdeleteしたところきちんとデストラクタが呼ばれるようになりました。
いろいろとお騒がせをしてスミマセンでした。

324 名前:デフォルトの名無しさん :04/03/12 00:30
>>323
あんた、ちゃんと人の話聞いてるのか?

325 名前:デフォルトの名無しさん :04/03/12 00:43
>>323
( ゚д゚)ポカーン

326 名前:デフォルトの名無しさん :04/03/12 00:43
>>323
reinterpret_castを使ったらダウンキャストじゃない
たまたま結果が一致することはあっても
あくまで無保証

327 名前:デフォルトの名無しさん :04/03/12 00:44
本人がもう解決したと言っているのだからほっとけ。

328 名前:デフォルトの名無しさん :04/03/12 00:52
>>326
確かにそうだ

329 名前:318 :04/03/12 00:55
COMなんてしらねーよ。

ようするにCでも使えるようにCOMをパクったけど、理解が足りてない、ってか。

330 名前:デフォルトの名無しさん :04/03/12 13:56
COMは考え方が汚くて嫌。例外処理もないし、コンストラクタも
デストラクタもない。ただC++でWindowsを自由自在に操るとなる
と避けて通れないから仕方ない。COMを全く知らない人でも
GUIDなら知っているだろう。

COM+はCOMの欠点が大幅に取り除かれ、だいぶC++との親和性
も良くなっている。但しWindows 2000以降でしか使用できない。

331 名前:デフォルトの名無しさん :04/03/12 13:58
例外はあるだろ

332 名前:デフォルトの名無しさん :04/03/12 14:29
>>331
ま、そうだが、エラーハンドリングはCOMではコードを返すと
いう古い設計を使っているという意味ね。

333 名前:デフォルトの名無しさん :04/03/12 15:42
コンパイラ間で例外の互換性なんてないですよね?
例えば、VC++で作ったexeからBC++で作ったdllのエクスポート関数を呼び出し
内部でthrowされた例外をexeでcatchするなんてできないですよね?
コンパイラに関係なく使える例外機構ってないですか?

334 名前:デフォルトの名無しさん :04/03/12 18:09
ばかばかしい質問なのですがおながいします。
例えば簡単なプログラムで
int main()
{
int *p=new int();
}
と、C++で何のヘッダもインクルードしなくても
operator new を呼んでくれるのですが、これは
どういうことでしょうか?(環境はVC6.0です)

335 名前:デフォルトの名無しさん :04/03/12 18:11
newが組み込みの演算子だから。+や-だってなんのヘッダも読み込まないだろ。

336 名前:デフォルトの名無しさん :04/03/12 18:59
>>335
何嘘教えてんだよ!
>>334
暗黙インクルードファイルに<new>が含まれてるんだよ。
処理系によっては<iostream>も含まれてることもあるよ。

337 名前:デフォルトの名無しさん :04/03/12 19:38
>>334
>>335 が正解。

>>336
>「暗黙インクルードファイル」
また俺用語ですか。

338 名前:デフォルトの名無しさん :04/03/12 20:35
new が <new> とは無関係なのは当然として
(placement new は無関係じゃないが)、

<iostream> とかが暗黙にインクルードされる処理系ってあるの?

339 名前:デフォルトの名無しさん :04/03/12 20:47
あるファイルにバイナリで書き込んである16or32bit値を読み出そうとしている。
いまリトルで開発中だが、同一のファイルにアクセスするビッグやバイへの
ポーティングができるだけ短時間で終わるようにしたい。
性能重視なので「解決」はできるだけ翻訳中に行い、実行環境でのオーバーヘッドを最小限にしたい。
こういうとき、336以外のお前らだったら何を使う?

340 名前:デフォルトの名無しさん :04/03/12 20:55
データが固定なら、読み出すときにエンディアンの変換が必要になる。
データと同じエンディアンの環境ならこの変換が省略されるようにすればよい。

データが固定でなくて良いなら、
データを異なるエンディアンを持つ環境に持っていく際に
データを変換すればよい。
これなら、実行時に変換が不要になる。

341 名前:デフォルトの名無しさん :04/03/12 21:33
>>340
レスどうも。自分で作るなら屁でもないんだけど、
もう1人の自分が「おめーわアフォか」と煽ってくるんだわ

342 名前:デフォルトの名無しさん :04/03/12 22:23
C++Primerは子供にも分る英語で書かれてて分り易いですね。
C++の勉強よりも英語の勉強に適してるような感じかも。

343 名前:デフォルトの名無しさん :04/03/12 23:22
遅レスだが、placement delete[] についてまとめてみた。
まず結論から。現規格では placement new[]/delete[] は使い難い。

1.>>236-239,267 で指摘されている通り、new T[n] では sizeof(T)*n+x(x≧0)
 が第一引数として operator new[] に渡される。
 new T[n]の結果は operator new[] の返り値から x だけオフセットされる。
 これは placement 版でも同じ。
 この x の値は不定であるため、事前に必要な容量を確保しておくことができない。
 つまり確保済みの領域にオブジェクトを生成することはできない。
 [参考] 5.3.4 - 12

2.>>210,217 のように Allocator を使う場合もオフセットが問題を引き起こす。
 placement operator new[] から呼び出されたコンストラクタで例外が
 発生した場合には、対応する placement operator delete[] が、
 placement operator new[] が返したポインタ値を引数として正しく呼び出される。
 しかし、一旦オブジェクトが生成されると、配列形式の placement new expression
 が返す値は、placement operator new[] が返した値より不定値分オフセット
 されている。
 このオブジェクトが占める領域を解放したい場合、現規格では配列形式の
 placement delete expression が存在しないため、placement operator delete[] を
 直接呼び出す必要がある。
 が、オフセットが不定のため plament operator new[] の返した値を引数とする
 ことができない。
 つまり、Allocator は allocate() が返すポインタ値と deallocate() に渡される
 ポインタ値が一致しないことを想定して処理しなければならない。
[参考] ttp://do.sakura.ne.jp/~junkroom/cgi-bin/megabbs/readres.cgi?bo=lounge&vi=999294620&res=146

結局、メモリ割り当てのコントロールがしたければ、配列を使わず vector を使え、
ということか。

344 名前:デフォルトの名無しさん :04/03/12 23:29
plament operator new[]/delete[]は、
ヒープデバッグ以外の用途に使う事なんてないだろね。

一般PGではなく、STLを拡張したいPGにとっては重要かもしれんけど。

345 名前:デフォルトの名無しさん :04/03/13 19:04
じゃあvectorはどうしているかというと
コンストラクタではアロケータで確保したメモリを使って
uninitialized_copyまたはuninitialized_fillをしている。
これは実質的には要素ごとにplacement newをしている。
デストラクタでは要素ごとに~T()をしている。

ちなみにuninitialized_copyなどに対応した廃棄用関数は標準関数にはなぜかない。

346 名前:デフォルトの名無しさん :04/03/13 19:33
uninitialized_copyや何やらにはアロケータが渡せないけどいいんだろうか。

347 名前:デフォルトの名無しさん :04/03/13 20:51
柴田望洋先生の本からの転載で

//複素数クラス
class Complex{
double re;
double im;
public:
//コンストラクタ省略
friend double Real(const Complex& x) {return(x.re);}
friend double Imag(const Complex& x) {return(x.im);}
//中略
Complex& operator+=(Complex& x){
re+=x.re;
im+=x.im;
return (*this);
}
Complex& operator-=(Complex& x){
re-=x.re;
im-=x.im;
return (*this);
}
friend Complex operator+(const Complex& x,const Complex& y){
return (Complex(x.re+y.re,x.im+y.im));
}
//以下省略

というソースなのですが、これに関して質問させて下さい。
friendについてなのですが、Complex& operator+=(Complex& x){〜〜〜}はfriend修飾しなくて良いのでしょうか?
引数の私的部にアクセス出来るようにするのがfriendだと思ったのですが、
Complex& operator+=(Complex& x)は私的部にアクセスしていますよね?
どうか解説お願いします。

348 名前:デフォルトの名無しさん :04/03/13 20:54
this返してるってことはメンバ関数だろ? クラスメソッドは firendにする必要ないよ。

349 名前:デフォルトの名無しさん :04/03/13 21:06
ところで何で +=, -= のオペランドだけ定数参照になってないんだ?


350 名前:デフォルトの名無しさん :04/03/13 21:30
たとえば、Calcというclassを作ったとして、
そのmember関数、double Calc::function(const double& x)の中身を
Calc a;
の中では
return x*x;
Calc b;
の中では
return x+1;
などのようにすることは出来ますか?
派生class作って、それぞれにfunctionを定義するしかないですかね。
外部のfileに関数を沢山定義しておいて、
それをCalcのconstructorに引数として渡すような事がしたいのです。

351 名前:デフォルトの名無しさん :04/03/13 21:38
aとbの差は一体なにさ?
生成された順番?変数の識別子?スコープ?

352 名前:450 :04/03/13 21:41
>>451
順番で御座います。

353 名前:デフォルトの名無しさん :04/03/13 21:43
>外部のfileに関数を沢山定義しておいて、
>それをCalcのconstructorに引数として渡すような事がしたいのです

渡せばいいんじゃないのか

354 名前:347 :04/03/13 21:49
>>348
なるほど。*thisを返す場合には必要ないのですか。
勉強になりました。ありがとうございます。

>>349
すみません。
本に書いてあったソースを写し書きしただけなので、分かりません。

355 名前:デフォルトの名無しさん :04/03/13 21:51
>>347
そのクラスのメンバなら、
引数のであっても直接アクセスできる。

あと、friend つけてクラス内で直接定義してある関数は、
メンバ関数ではなく通常の関数になる
(名前空間はそのクラスの属している名前空間と同じになる)。
operator+= は friend でなくていいのではなく、
friend であってはならない。

356 名前:デフォルトの名無しさん :04/03/13 22:00
まあ、フレンドクラスとフレンド関数の違いを理解しろってことだな。
あと、どうしてoperator+を外部関数にするのか、とか。

357 名前:デフォルトの名無しさん :04/03/13 22:11

 12日午後、ファイル交換ソフト「shsre」を使用して、違法なファイル交換を
行ったとして、神奈川県横浜市緑区2-66-9に住む無職 戸塚薫容疑者31歳
を著作権法違反など3つの罪で逮捕したとの発表が神奈川県警ハイテク課
からあった模様。ハイテク課ではひきつづき捜査を行っているが、戸塚容疑者は
意味不明な言語を発し、捜査には全く応じていないという。


神奈川新聞  無断転載禁止

http://news2.2ch.net/test/read.cgi/news7/1076656479/
 


358 名前:397 :04/03/13 22:43
C++を勉強し始めたばかりです。
本を見ながらDOSで作動するものを作っているのですが、Windowsの(DOSじゃない)を作りたいのですが、全然わかりません。

359 名前:デフォルトの名無しさん :04/03/13 22:46
>>358
http://www.kumei.jp/c_lang/

360 名前:デフォルトの名無しさん :04/03/13 22:47
猫でもわかるプログラミング(C だけど)に行って、
それを C++ 使って書き直してみたら?

361 名前:デフォルトの名無しさん :04/03/13 22:48
普通friendな関数はclass内部には宣言だけにして、外に実装を書かないか?

362 名前:デフォルトの名無しさん :04/03/13 22:54
どちらにしろ普通の関数になることは同じだから、
どうでもいいっちゃぁ、どうでもいいな。

363 名前:デフォルトの名無しさん :04/03/13 22:57
>>346
無名コンストラクタの場合

T* p = _allocator.allocate(size,0);
uninitialized_fill_n(p,size,T());




364 名前:デフォルトの名無しさん :04/03/13 23:04
>>353
最後の一文から判断すると、
class Calc {
double (*func_)(double);
public:
explicit Calc(double (*func)(double)) : func_(func) {;}
double function(double x) { return func_(x); }
};
みたいなことがやりたいのか?(ちなみに double は値渡しがふつう)
言葉通り外部から関数を与えてを実行させたいのなら
オーバーライドを使うのはおかしいと思うんだが。

365 名前:デフォルトの名無しさん :04/03/13 23:10
>>358
Win32 API入門 http://black.sakura.ne.jp/~third/system/winapi/win.html

366 名前:デフォルトの名無しさん :04/03/13 23:26
>>358
C++の基礎がきちんと身につくまではWindowsアプリなんぞ手を出すな
まず今読んでる本をきちんと最後まで読んで理解しろ
それが結局自分のためだぞ

367 名前:397 :04/03/13 23:27
ありがとうございます、がんばってみます。

368 名前:デフォルトの名無しさん :04/03/13 23:40
>>367
Win32 APIならC++ではなくCだけで十分
C++が事実上必須になるのはCOM関係
C++が必須なのはMFC

369 名前:デフォルトの名無しさん :04/03/13 23:52
C なんて使ってらんne-

370 名前:デフォルトの名無しさん :04/03/14 00:18
C言語原理主義

371 名前:デフォルトの名無しさん :04/03/14 00:26
テンプレートを基底クラスとして継承をやる方法を教えてください。
たとえばリストテンプレートで、
class B: public list<A>
のようにやってもコンパイラが受け付けてくれません。

372 名前:デフォルトの名無しさん :04/03/14 00:29
>>371
{};

373 名前:デフォルトの名無しさん :04/03/14 00:30
#include <list>
class A {
};
class B : public std::list<A> {
};

で試したけど、大丈夫だよ。
コンパイラは何?

374 名前:347 :04/03/14 00:32
>>355,356,361,362
解説ありがとうございます。

要するに、
friend指定にすると普通の関数になるということは、つまりthisが破錠してしまう。
だからthisを使いたい場合にはfriend指定をしてはいけない。
ということなのでしょうか?

更にもう1つ質問なのですが、
引数や戻り値をポインタ(参照?)にしている意味はあるのでしょうか?
僕自身Cから入ったもので、関数の引数としてのポインタの用途は実引数を書き換えたい場合しか思い浮かばないのですが、
この場合、実引数を書き換えているようには見えません。
解説お願いします。

375 名前:デフォルトの名無しさん :04/03/14 00:32
コンパイラはVisualC++です。
エラーは名前空間のstdを指定していなかっただけでした。
どうもありがとうございました。

376 名前:デフォルトの名無しさん :04/03/14 00:41
>>374
1引数 operator+= はメンバ関数で、
2引数 operator+= は普通の関数だ。
operator+=(Complex& own, Complex& x) とするなら friend 関数でいいんだが、
operator+=(Complex& x) とするならメンバ関数だ。
a += b; と等価な表現は、
前者は operator+=(a, b); で、
後者は a.operator+=(b); だな。

>引数や戻り値をポインタ(参照?)にしている意味はあるのでしょうか?
foo(a += b); とか (a += b) *= c; とかできるように。

377 名前:デフォルトの名無しさん :04/03/14 00:42
>>374
>関数の引数としてのポインタの用途は実引数を書き換えたい場合しか思い浮かばないのですが、
それは「C から入った」とかいう以前の問題のような……。
コピーのコストが高くつくオブジェクトは、コピーを避けるために
const 参照で渡すのが常套手段。

C でも、でかい構造体は const ポインタで渡すのが普通だよ。

378 名前:347 :04/03/14 00:47
>>377
確かに云われてみれば…。気付けなかった自分が恥ずかしいです。
中学3年生の頃からCを勉強して早2年…、Cは大体網羅したと勝手に思っていましたが、全然ダメダメですね。
C++とか云う前に修行し直してきます…。

379 名前:デフォルトの名無しさん :04/03/14 01:11
>>378
ていうかやめれ。おまえには向いてない。

380 名前:デフォルトの名無しさん :04/03/14 01:17
>>379
お前がやめれ。>>378=>>347が後釜になるから人手に困らん。

381 名前:デフォルトの名無しさん :04/03/14 01:39
ま、向いてないかどうかはともかく、
>>347は2ちゃんなんか見てる暇があったら、
とっととまともな入門本を読めってこった。

メンバ関数と非メンバ関数とか、参照とかポインタ渡しとか、
こんなもののはC++の基本中の基本。
こんなレベルでいちいち疑問が浮かぶたびに質問されてたら、
スレがいくつあっても足りん。


382 名前:デフォルトの名無しさん :04/03/14 02:20
347=380だろ?なんだよこのバレバレの自演・・・
C++の前に2chやめれ

383 名前:デフォルトの名無しさん :04/03/14 03:02
ドリーマー登場。

384 名前:353 :04/03/14 04:18
>>364
そういう、関数を渡す方法があったんですか。
いくつか本を読んでみても、
「関数渡し」とかでググってみても無かったんで。
ありがとうございます。

385 名前:デフォルトの名無しさん :04/03/14 05:17
今後、>>347みたいな質問/ヤシは初心者スレに誘導したら?
むこうでも「入門書嫁」で終わりそうではあるが。

386 名前:デフォルトの名無しさん :04/03/14 06:12
>>374

thisを使いたいかどうかっていうよりも、
クラスのメンバ関数にしたいなら、friendをつけない。
外部関数にしたいときは、単にクラスの外で宣言・定義する。
外部関数にしたいけれど、クラスのprivateメンバにアクセスしたいときは、
friendをつけてクラスの中で宣言する。

まあ、引数をポインタや参照で渡すことも含めて、
この辺のことはEffective C++とかにも書いてあるから、
暇だったら読んでみたら? それ以前にCの理解が不十分な気がするけどね。

387 名前:デフォルトの名無しさん :04/03/14 14:31
std::list<int*> value_list;
といった形で値のリストを保持しているのですが、これを後ろから5以上
の場合だけ削除し、5未満が出た場合は中断するといった場合
bool isstop = false;
std::list<int*>::iterator it;
for (it = value_list.end(); it != value_list.begin(); --it) {
 if (*it >= 5) {
  delete *it;
  value_list.erase(it);
 } else {
  isstop = true;
  break;
 }
}
if (!isstop) {
 it = value_list.begin();
 delete *it;
 value_list.erase(it);
}
これ以外に一度のforですますような方法はありますか?
スレ違いでしたら申し訳ないのですが誘導お願いします。


388 名前:デフォルトの名無しさん :04/03/14 14:34
>>387
rbegin(), rend()

389 名前:デフォルトの名無しさん :04/03/14 14:59
>>387
そのコードはendを逆参照しているし、無効になった反復子をデクリメントしているからまずい。
特に理由がないなら、標準アルゴリズムを使うべし。

390 名前:デフォルトの名無しさん :04/03/14 15:16
>>387
rbegin(), rend()を使って5未満の要素をfind_ifして、そこから後ろを全て消すというのはどう?

391 名前:389 :04/03/14 15:21
スマートじゃないと思ったらやっぱり別の方法があったんですね。
ありがとうございます。調べてみます。


392 名前:デフォルトの名無しさん :04/03/14 19:14
>>387
こんなもんかな。

//ファンクタを用意
#include <functional>
struct comp_val : public std::binary_function<const int*,int,bool> {
bool operator() ( const int* ptr, int val ) { return *ptr < val; }
};

//後ろから検索して初めて見つかった5未満の要素より後ろのものを削除
value_list.erase( std::find_if( value_list.rbegin(), value_list.rend(),
std::bind2nd(comp_val(),5) ).base(), value_list.end() );


393 名前:デフォルトの名無しさん :04/03/14 19:15
>>392
単にeraseではまずいと思われ。

394 名前:デフォルトの名無しさん :04/03/14 19:29
>>393
ああ、要素の破棄もするのか。
訂正
//ファンクタを用意
#include <functional>
struct comp_val : public std::binary_function<const int*,int,bool> {
bool operator() ( const int* ptr, int val ) { return *ptr < val; }
};
struct del_ptr : public std::unary_function<int*> {
void operator() ( int* ptr ) { delete ptr; }
};

//後ろから5未満の要素を検索
std::list<int*>::iterator i=std::find_if( value_list.rbegin(), value_list.rend(),
 std::bind2nd(comp_val(),5) ).base();
//要素の破棄
std::for_each( i, list_value.end(), del_ptr() );
//リストの削除
value_list.erase( i, value_list.end() );

これから飯食いに行くんで走り書き。
何か不味かったら誰か突っ込んどいてください。
んじゃ。

395 名前:デフォルトの名無しさん :04/03/14 19:36
↑とりあえず自分で直す
×unary_function<int*>
○unary_function<int*,void>

×std::for_each( i, list_value.end(), del_ptr() );
○std::for_each( i, value_list.end(), del_ptr() );

んじゃ。

396 名前:デフォルトの名無しさん :04/03/14 21:35
>387
純粋に素朴な疑問なんだが、なんで要素が"int *"なの?

397 名前:389 :04/03/14 21:50
わざわざソースまでご呈示頂いてありがとうございます。
こんな風にできるんですねぇ、まだまだ勉強が足りないと思いました。

>>396
実際にはクラスのポインタを入れてるんですが、簡単のためにint*と
いたしました。

398 名前:デフォルトの名無しさん :04/03/14 22:03
あるclassが存在して、
それと全く同じ機能を持つ別名のclassを作りたいのですが、
どういう風にやるのが最も簡単でしょうか。

399 名前:デフォルトの名無しさん :04/03/14 22:09
class SomeClass { ... };
typedef SomeClass AnotherNameClass;

あるいは
class AnotherNameClass : public SomeClass {
 // コンストラクタを全部再定義
};

400 名前:デフォルトの名無しさん :04/03/14 22:11
>>399
コンストラクタ再定義しないとまずい?

401 名前:デフォルトの名無しさん :04/03/14 22:13
>>398
typedef はダメ?

402 名前:デフォルトの名無しさん :04/03/14 22:21
>>398
もっと条件を絞ってもらわないと、質問があまりにも一般的すぎ。
SomeClassの定義如何では全く同じ機能を持つクラスを派生できない場合もあるし。


403 名前:デフォルトの名無しさん :04/03/14 22:22
>>400
マズい。
コピーコンストラクタと代入オペレータは派生されないから。

404 名前:デフォルトの名無しさん :04/03/14 22:28
s/派生/継承/

405 名前:デフォルトの名無しさん :04/03/14 22:30
template <int n> class Foo { ... };
typedef Foo<0> Bar;
typedef Foo<1> Hoge;

ってのはどう?

406 名前:デフォルトの名無しさん :04/03/14 22:32
意味分からんが、サブクラス作れ、幾らでも作れるぞ。


407 名前:デフォルトの名無しさん :04/03/14 22:33
>>403
ということは、コピーコンストラクタと代入オペレータをprivateで封印している場合は
何も再定義しなくて使えるってことですよね。

でも、なんでコピーコンストラクタと代入オペレータが継承されない仕様になっているのだろうか。

408 名前:デフォルトの名無しさん :04/03/14 22:34
別のクラスだからな。

409 名前:399 :04/03/14 22:46
えー?コピーコンストラクタとかの話は漏れはわからんけど、
派生側でこんすとらくた定義しとかないと

class A { public: A(int) {} };
class B : public A {};

B obj( 5 );

ってコンパイル通らないよね?

410 名前:デフォルトの名無しさん :04/03/14 22:50
class Bの時点で通らん。

411 名前:デフォルトの名無しさん :04/03/14 22:52
>>407
オブジェクト指向は、ベースクラスの仕様がサブクラスの仕様拡張に
影響されないので良いんだよ。何やっても良い。

412 名前:デフォルトの名無しさん :04/03/14 22:55
>>407
コピーコンストラクタと代入オペレータがprivate宣言されているっつーことは、
SomeClassの性質上、それはやっちゃいけないか、そもそもそういう操作があり得ないからと
考えるのが自然だろな。
さもなくば、SomeClassからfriend宣言されている関数またはクラスのみが、
コピーコンストラクタと代入オペレータを呼び出すことができる。


413 名前:デフォルトの名無しさん :04/03/14 23:24
>>409
コンストラクタは継承されない。自分で明示的に呼び出す必要あり。

414 名前:デフォルトの名無しさん :04/03/14 23:54
C言語は俺に聞け!スレが香ばしい(w

ほとんどC++を知らないらしいヤシらが勝手な事言ってるよw

415 名前:デフォルトの名無しさん :04/03/15 00:42
禿本のspecial editionって3rdとの違いは何?両方持ってる人がいたら情報キボン

416 名前:デフォルトの名無しさん :04/03/15 00:57
>>415
http://www.research.att.com/~bs/bs_faq.html#SE

417 名前:398 :04/03/15 04:52
>>399-413
みなさんレスありがとうございます。
実はi)派生させる場合とii)typedefする場合を、
それぞれ試したのですがうまくいかなかった為質問しました。
i)派生させる場合
class A {
private:
double val;
public:
A(const double& rval){val = rval;}
};

class B : public A{};

こうすると、
double val = 0;
B b(val);
が通りません。
B(double&)は存在しなくて、B(const B&)しかないと言われます。

ii)typedefする場合
同じように、constructorまわりでerrorを吐きます。

やはり、constructorの再定義は必要なわけですね。
405さんのも使えそうですね。

418 名前:デフォルトの名無しさん :04/03/15 17:25
>>417
#define temp(x) class x {public:x(){} x(int){}};

temp(hoge)
temp(huga)

419 名前:デフォルトの名無しさん :04/03/15 17:29
>>417
typedefなら出来るはずだが、いったいどんなコンパイラ使ってるんだ?

420 名前:398 :04/03/15 20:17
typedef A B
した後にBを引数として、
他のclassのconstructorに渡したのですが、
which is of non-aggregate type
というerrorが出ます。
compilerはg++です。
何度もすみません。

421 名前:398 :04/03/15 20:43
もすこし、具体的に書きます。
A or Bのconstructorにはdoubleを渡し、
他のclass CのconstructorにBを渡すようにしてあります。
で、B b(1.0)とした後に、
C c(b)とするとcompileが通るのですが、
C c(B(1.0))とすると通らないのです。
Cのmember関数を呼び出すところで、
which is ...のerrorが出ます。
もしかしたらこのmember関数が悪さをしているのかも知れませんが、
cの宣言の違いで結果が変わるため、
constructorあたりが悪いのかと想像しました。

422 名前:デフォルトの名無しさん :04/03/15 20:53
>>421
> C c(B(1.0))とすると通らないのです。
本当にそれが通らないのか?
 double x = 1.0;
 C c( B(x) );
 c.member( ... );
は通らない( 2行目が、B型の引数xを取ってC型を返す関数cの
宣言と見なされる )が。

423 名前:デフォルトの名無しさん :04/03/15 21:59
class CHoge{
int * hoge;

private:
CHoge::~CHoge( kill());
CHoge::initial( *hoge = new int[1];);
CHoge::kill( delete [] hoge;);
};

void ugu(CHoge fuga){ fuga.hoge[0] ++; };

void main(){
CHoge piyo;
piyo.initial();

piyo.hoge[0] = 10;

ugu(piyo);

cout << piyo.hoge[0];
}

とすると、デストラクターで元のpiyoのhogeもdeleteされてしまいます。
このような場合、どうすればいいのでしょう?

424 名前:デフォルトの名無しさん :04/03/15 22:10
>>423
コピーコンストラクタを書く。

425 名前:デフォルトの名無しさん :04/03/15 22:11
何だそのおもいっきり文法違反なソースは。
>このような場合、どうすればいいのでしょう?
どうなって欲しいのか書いてくれないと答えられない。

ポインタメンバのコピーコンストラクタと代入オペレータは
用途にあわせてきちんと実装する必要がある(何も書かなきゃポインタがそのままコピーされるだけ)。
典型的な処理ならば”スマートポインター”と呼ばれるものが使える。

ついでにいっておくと ugu で引数のオブジェクトを変える目的があるなら
コピーでなくて参照で渡すべきだぞ。今はコピー先とメンバを共有してるから書き換えられてるけど

426 名前:デフォルトの名無しさん :04/03/16 00:09
>>421
そのBをAにしたらエラーは消えるか、試しましたか?

427 名前:デフォルトの名無しさん :04/03/16 13:05
お願いします。
a.cppで

const int a;

b.cppで

extern const int a;

とやったのですが、名前解決が出来ない
と言われてリンクできません。
constを外すとできます。
どうしてでしょうか?

428 名前:デフォルトの名無しさん :04/03/16 13:21
>>427
a.cppでも

extern const int a;

とする事。C++ではconstは内部リンケージを持っているので
外からは見えない。

429 名前:デフォルトの名無しさん :04/03/16 13:22
C++は「デフォルトで」constは内部リンケージ・・・・と読み替えてくれ。

430 名前:デフォルトの名無しさん :04/03/16 13:31
>>428>>429

それだけじゃだめだよ。a.hに

const int a = 7;

とでも書いて初期化し、a.cppとb.cppでa.hをインクルード
        ~~~~~~~
しなければ。

431 名前:デフォルトの名無しさん :04/03/16 13:37
>>430
それは時と場合による。a.cppとb.cppのどちらかでexternを
つけたconstを初期化しておけばこの場合はよい。

a.cpp

extern const int a = 123;

みたいに。

432 名前:デフォルトの名無しさん :04/03/16 13:45
>>430
>a.cppとb.cppでa.hをインクルード

それだとa.obj、b.objの両方に別々にaが確保されるから
externする意味がないじゃん

433 名前:デフォルトの名無しさん :04/03/16 13:49
STGゲームなどの弾の管理をlistで行っているのですが削除のときの方法で質問です。
void FlagCheck()
{
 std::list<SHOOT>::iterator S;

 for(S = shoot.begin(); S != shoot.end(); S++)
 {
  if(T->GetFlag())
  {
   shoot.erase(T++);
  }
  else ++T;
 }
}
とやっています。
SHOOTは弾が物体にあたったときにflagがtureになるようなクラスです。
一応今は問題なく動いているのですが作るときに色々試した結果たまたま動いただけで
あまり理解ができていません。
shoot.erase(T++)をerase(++T)にしたりshoot.erase(T);T++;にするとエラーになってしまいます。
前者は無論理由はわかるのですが後者の理由がよくわかりません。
上の関数に欠点がないか、それとshoot.erase(T);T++;がエラーになってしまう理由を教えていただけないでしょうか。
よろしくお願いします。

434 名前:427 :04/03/16 13:50
みなさんありがとうございます。
constは定義ですでにextern指定
しないといけないんですね。

ところがMFCのAFXTMPL.hという
ファイルの中で
extern const TCHAR _afxWnd[];
と宣言されていて、これの定義は
WINCORE.cppのなかで
const TCHAR _afxWnd[] = AFX_WND;
とされていて、定義のほうにexternが
ついてないのですがこれはどうして
でしょうか?
なんかわけがわからなくなってきました(TT

435 名前:デフォルトの名無しさん :04/03/16 13:56
>>433
shoot.erase(T++)の実行順序は、
1. Tの値を引数として保存
2. T++を実行
3. 保存された引数をshoot.eraseに渡す(この結果旧Tの指していた要素は消滅する)

だよ。
これがshoot.erase(T); T++;になると:
1. Tの値を引数としてshoot.eraseを実行し、Tの要素が消滅しているため無効になる
2. 無効になってしまったTに対してT++を実行するのは駄目

436 名前:デフォルトの名無しさん :04/03/16 14:11
>>435
なるほど。「保存」ですか。
ひとつ賢くなりました。
ありがとうございました!

437 名前:デフォルトの名無しさん :04/03/16 14:44
>>433
STGなんて作ったことないので想像でしかないけど、
弾なんて生成と破棄が激しそうだからstd::listは
パフォーマンス悪くない?
SHOOT型オブジェクトを配列で用意しておいて、
SHOOT型内に次SHOOT型オブジェクトへのポインタ
とか持たせた埋め込みタイプのリンクリストで
連結したほうが良いような気がするけど。

あ、Allocatorいじってんなら話は別だけど。

438 名前:デフォルトの名無しさん :04/03/16 16:25
まずは正しく作れ。それからプロファイラなどで調べて必要な部分だけ最適化せよ

439 名前:398 :04/03/16 16:34
>>422
通らないのは、c.member()のところです。

>>426
試しましたが、駄目でした。
そうすると他の所の記述が悪いせいでしょうか。
ただ、
C c(B(1.0));
とすると駄目だったのに、
C c = C(B(1.0));
という風に書き換えると走るようになりました。
これは、実質的に同じ表現ではないのですか?

このようにすると、c.member()も通るようになりました。

結論としては、typedefでは駄目なのでしょうか。

440 名前:デフォルトの名無しさん :04/03/16 16:54
>>438
C のコンストラクタの引数の型は何?

441 名前:デフォルトの名無しさん :04/03/16 17:06
>>398は質問に関する情報を一旦まとめて欲しいなあ。

442 名前:398 :04/03/16 19:27
>>441
まとめます。さらにいくつか試したのも書きます。

■目的■
class Aと全く同じ機能を持ったclass Bを作りたい。
(性質は一緒だが、実世界で概念の異なる物を表現したいため。)

■方法■
一番簡単な方法として、typedef A B;によって、Bを扱えるようにした。

443 名前:398 :04/03/16 19:28
■結果■
(実際にはもう少し複雑なclassを扱っていますが、
内容をかなり省略して書きます。)
Cというclassのconstructorに、引数としてBを渡した。
C(const B& rb) { b = new B(rb);}
ここで、A(or B)のconstructorはA(const double& rval){ val = rval;}
という単純なものである。
copy constructorは、A(const A& rA){ val = rA.val;}である。
また、Cのmember関数としてC::func()を用意した。
このとき、main()の中で、
C c(B(1.0));
c.func();
という記述を行うと、二行目で
error: request for member `func' in `c(A)', which is of non-aggregate type `C ()(A)'
と出る。(あくまで簡略して書いています。)
1行目は何も怒られない。
そこで、c.func();をcomment outして再compileさせると、
compileは通った。(OS Xのg++です。明日、他の環境も試してみます。)
ただし、gdbでデバッグしてやると、
この1行目は何故か読み込まれていなかった。
また、先のをさらに書き換えて、
B b(1.0);
C c(b);
c.func;
としてやるとcompileは通り、
動作も期待通りのものであった。

444 名前:398 :04/03/16 19:29
■結論■
分かりません。

■附記■
もっとも単純な構成でtypedefが機能するかを調べるために、
以下のcodeをcompileしたところ問題は生じなかった。
ここに貼り付けると長くなるのでやめるが、
自分で書いた他のcodeで同様のtypedefを行った場合、
先に書いたerrorが生じた。

#include <iostream>

using namespace std;

class A {
private:
double val;
public:
A(const double& rval) : val(rval){;}
A(const A& rA) : val(rA.val){;}
~A(){;}
A& operator=(const A& rA){val = rA.val;}

void print_val(){cout << val << endl;}
};

typedef A B;

445 名前:398 :04/03/16 19:30
class C {
private:
B* b;
public:
C(const B& rB){b = new B(rB);}
C(const C& rC){b = new B(*(rC.b));}
~C(){delete b;}
C& operator=(const C& rC){delete b; b = new B(*(rC.b));}

void print_val(){b->print_val();}
};

int main(){

C c(A(0.1));
C c(B(0.1));
c.print_val();

return 0;
}

長文スマソ。

446 名前:398 :04/03/16 19:33
それか、
C c = C(B(1.0);
c.func();
でも大丈夫でした。

447 名前:デフォルトの名無しさん :04/03/16 19:37
まこてんの g++ ってバージョンいくつだっけ?


448 名前:398 :04/03/16 20:03
>>447
3.3使ってます。
g++の2.95.2、3.1も試しましたが、
両方とも同様のerrorを吐いています。
念のため、明日はLinuxでやってみるつもりです。

449 名前:デフォルトの名無しさん :04/03/16 20:17
>>444-445
どうして代入演算子のオーバーロードで*thisを返してないのか
わからん。

#include <iostream>

class A {
double val;
public:
A(const double& rval) : val(rval) {}
A(const A& rA) : val(rA.val) {}
A& operator=(const A& rA) {
val = rA.val;
return *this;
}
void print_val() { std::cout << val << std::endl; }
};

typedef A B;

class C {
B* b;

450 名前:デフォルトの名無しさん :04/03/16 20:18
public:
C(const B& rB) : b(new B(rB)) {}
C(const C& rC) : b(new B(*rC.b)) {}
~C() { delete b; }
C& operator=(const C& rC) {
delete b;
b = new B(*(rC.b));
return *this;
}
void print_val() { b->print_val(); }
};

int main()
{
C c1(A(0.1));
C c2(B(0.1));
c1.print_val();
c2.print_val();
}

451 名前:デフォルトの名無しさん :04/03/16 20:45
実は C c(B(1.0)); が関数宣言とみなされてるとか。
…と、Effective STL P34 を見てちょぃっと思ってみるテスト。

452 名前:デフォルトの名無しさん :04/03/16 21:30
>434
const 整数型 はC++では基本的に「定数」だから

それよりもグローバル変数を使うな。素直に共通ヘッダを作るべし。
どうしてもヘッダファイルを作りたくないなら、まだマシな関数にしろ。

453 名前:デフォルトの名無しさん :04/03/16 21:41
class A;
void Test(A *a);
みたいな関数をツクって
それでAをリストなりベクトルなりで管理し、イテレータで操作した場合
Test(&(*q)); // qはイテレータ
みたいなやり方ってスマートじゃないですかね。見た目からして…

454 名前:デフォルトの名無しさん :04/03/16 23:36
> error: request for member `func' in `c(A)', which is of non-aggregate type `C ()(A)'

おもいっきり、関数として認識されてんじゃねーか。
いいかげんに気付けよ。

C c(A(1.0)); // 1.0で初期化した class A の一時オブジェクトで class C のローカル変数 c を初期化して定義
C c(A(x)); // class C を戻り値とし、 class A の引数を一つ(仮引数名 x で)受け取る関数 c を宣言

455 名前:デフォルトの名無しさん :04/03/16 23:38
>>453
Test(A* a)にヌルを渡すことが無いなら、Test(A& a)のほうがいいかも。

456 名前:デフォルトの名無しさん :04/03/16 23:47
漏れはそもそも
> A(const double& rval)
が気に食わん。
double程度に、なぜ参照を使うかなぁ。

で A(1.0) なんて書いても、そりゃおかしいんじゃねーの?
だって、定数のアドレスを求めようとしてるじゃんかよ。


457 名前:デフォルトの名無しさん :04/03/17 00:06
>>456
上半分は同意.
下半分はconst &をリテラルで初期化したときの挙動を理解していらっしゃらないだけかと.

458 名前:456 :04/03/17 00:39
・・・と思ったけど,Exceptional C++引っ張り出してきて項目46を
読み返してみると,上半分も場合によりけりなのかな?
ちょっと混乱してきた.教えて,エロい人!!

459 名前:457 :04/03/17 00:40
ずびばぜん・・・↑のレスは私(457)です.

460 名前:デフォルトの名無しさん :04/03/17 01:29
>>458
最適化でインラインになっちゃえば同じという説も。

俺はそれより>>356も言ってるようなoperator+を外に出す方が課題。
どうしても継承したり複雑になってくるとoperator+を外に出したときに問題が出てくる。
部分特殊化が出来ないとoperator+の引数が曖昧になってあらゆる+を奪っちゃったりとか。

461 名前:398 :04/03/17 02:38
>>454,456,457
レスどうもです。
そうすると、明示的に書くしかないということですね。
compilerに関数として認識させないように。
typedefは悪くない、と。

462 名前:デフォルトの名無しさん :04/03/17 06:45
C c = B(1,0) じゃだめなのか?

463 名前:デフォルトの名無しさん :04/03/17 07:24
, じゃだめだろうなぁー

464 名前:デフォルトの名無しさん :04/03/17 07:29
>>456
プリミティブ型は値渡しが普通っていうのはわかるが、
昨今の32bit環境の場合は
sizeof(int) < sizeof(double)
が普通なわけで。
doubleの場合は参照渡しの方が良くない?

465 名前:デフォルトの名無しさん :04/03/17 07:35
>>464
sizeof(int) と 値渡し/参照渡し の間に何の関係が??

466 名前:デフォルトの名無しさん :04/03/17 08:34
どっちかってとsizeof(double*) < doubleのほうが関係あると思うがな。

467 名前:デフォルトの名無しさん :04/03/17 11:51
const 参照に定数(リテラル)を渡せるのは
C++ の仕様なんだけどな。
まぁ、それはともかく、わざわざ参照を使う理由が分からないのは同意。

468 名前:デフォルトの名無しさん :04/03/17 13:34
ちなみにboost::call_traits<T>::param_typeの実装を見てみると
is_arithmetic<T> == true && sizeof(T) <= sizeof(void*)のときは値渡しで
それ以外なら参照渡しという実装だった.@1.31.0
(もちろんpointer渡しはpointer渡しで)

469 名前:デフォルトの名無しさん :04/03/17 16:15
398が抱えてる問題って、Effective STLの6項にあった問題と同じかな?

470 名前:デフォルトの名無しさん :04/03/17 18:11
>>469
>>451

471 名前:469 :04/03/17 19:17
ありゃスマン、既出だったか

472 名前:デフォルトの名無しさん :04/03/17 21:15
お願いします。
C++というかC標準ライブラリの関数(strcpyとかatoiとか...)の
使い方ってみなさんどうして学習したんですか?
C++標準ライブラリのリファレンスってよくありますが、Cのって
見かけないんですが...
スレ違いかも知れないのですが宜しくおながいします。

473 名前:デフォルトの名無しさん :04/03/17 21:17
info libc

474 名前:デフォルトの名無しさん :04/03/17 21:23
help

475 名前:デフォルトの名無しさん :04/03/17 21:33
俺もヘルプ

476 名前:デフォルトの名無しさん :04/03/17 21:41
>>472
 MSDN http://www.microsoft.com/japan/msdn/library/ja/vclib/html/vcrefruntimelibraryreference.asp
 JM http://www.linux.or.jp/JM/
 望洋タンとこ http://www.bohyoh.com/CandCPP/C/Library/hindex.html
とか色々…俺は逆にC++のよりCの標準ライブラリのリファレンスの
方が遙かに沢山あると思うんだけど…

477 名前:デフォルトの名無しさん :04/03/17 21:43
>>472
http://www.google.co.jp/search?q=C%E8%A8%80%E8%AA%9E+%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9

478 名前:472 :04/03/17 21:52
みなさんどうもありがとう。
いろいろあるんですね。
めちゃくちゃ参考になりました。。。

479 名前:デフォルトの名無しさん :04/03/18 01:01
>>472
てかK&Rの付録がまとまってて非常に良いと思われ

480 名前:472 :04/03/18 01:19
>>479
ほんとだ!

481 名前:デフォルトの名無しさん :04/03/18 09:44
LSI-C試食版のライブラリリファレンスにお世話になりました。
Vzで、常に開いてたような気がするなあ。


482 名前:デフォルトの名無しさん :04/03/18 21:31
関数の宣言をするところで
void buy()とint buy()
voidとintの違いってなんですか?
よくわからないです。

483 名前:デフォルトの名無しさん :04/03/18 21:42
釣や領収書を期待するならば int buy()



484 名前:デフォルトの名無しさん :04/03/18 21:46
返り血を浴びたいなら int buy()

485 名前:デフォルトの名無しさん :04/03/18 21:54
釣りはいらねぇぜなら void buy()

486 名前:482 :04/03/18 21:58
戻り値がを返すならint、他ならvoidってことしょうか?
全部intなら問題ないってことですか?

487 名前:デフォルトの名無しさん :04/03/18 22:11
返り値とは何かを調べてきたら?

488 名前:デフォルトの名無しさん :04/03/18 22:11
それはどんな関数かによる。
商品とお金を渡しておつりが欲しいなら戻り値を考慮すべきだし、
関数が成功したか否かが欲しいならboolだし、っていうかC++の
質問じゃないじゃん。

489 名前:482 :04/03/18 22:23
いろいろ試してみます。
ありがとうございました。
C++の本を見ながら試していたので、ここのスレでいいのかとおもいました。

490 名前:デフォルトの名無しさん :04/03/19 11:13
今更なんだけど、

-- aaa.h --
#include "bbb.h"
class A {
 B bbbb;
};

-- bbb.h --
#include "aaa.h"
class B {
 A aaaa;
};
これだと例えばbbb.h側でクラスAが定義されていないとか認識されちゃうんだけど、
どうしたらいいでせう。#ifndef・#define〜#endifでは囲ってます。

491 名前:デフォルトの名無しさん :04/03/19 11:22
>>490
認識以前に、もしできても無限に大きな構造体にする気ですか?

ポインタや参照でなら、前方宣言
class B; // これ
class A {
B * bbb;
};
とか、まとめて
class A {
class B * bbb;
};
ならできるが。

492 名前:デフォルトの名無しさん :04/03/19 12:34
>>491
あ、そうか。確かに無限大サイズになってまうですね。なるほど。
・・・それで片方だけポインタ使っとけば問題ないかなと思って
↓こんなの試してみたんだけどエラーでてしまいました。

-- aaa.h --
#include "bbb.h"
class B;
class A {
 B *bbbb;
};

-- bbb.h --
#include "aaa.h"
class B : public A { // Aは定義されていない
};

これも同じような問題あるですか?

493 名前:492 :04/03/19 12:45
あ、いや。↑のはコンパイル通りますた。無問題ですた。スマソ。
>>491 どうもThanXです〜。

494 名前:デフォルトの名無しさん :04/03/19 13:07
>>493
bbb.h は class A の宣言の後にインクルードすべし。

495 名前:492 :04/03/19 13:30
>>494
あれやっぱ動かないと思ってたらincludeの位置が問題だったか。
ありがd

ただ、class A内のB型ポインタからclass Bの適当なメンバにアクセスを
させようとした途端、class AからはBが見えないため、
また未定義のエラーが出てきてしまいますね。
クラス間の相互アクセスはどうがんばってもできないのでせうか。

496 名前:デフォルトの名無しさん :04/03/19 13:33
>>495
-- aaa.h --
class B;
class A {
B *bbbb;
void hoge();
}

-- bbb.h --
#include "aaa.h"
class B {
A *aaaa;
};

-- aaa.cpp --
#include "aaa.h"
#include "bbb.h" // class Bを実際に使うのに必要
void A::hoge()
{
// bbbb->aaaaが使える
}

497 名前:492 :04/03/19 14:01
>>496
そっか、そうすれば可能なのか。かなり勉強になったよ。ありがとう!

498 名前:デフォルトの名無しさん :04/03/19 16:14
おねがいします。
コンストラクタは明示的に呼べないのでしょうか?
例えば今
class CTest{
public:
int m_nData;
CTest():m_nData(0){};
CTest(int n){m_nData=n;}
void Init(int n);
};

というクラスがあったとして
メンバ関数Init()を
void CTest::Init(int n){
CTest::CTest(n);
}
と実装してもちゃんとnが設定されません。

int main()
{
CTest a;
a.Init(5);
printf("%d\n",a.m_nData);// ←0のまま
}

なんででしょう。。。

499 名前:デフォルトの名無しさん :04/03/19 16:19
>>498
>コンストラクタは明示的に呼べないのでしょうか?
呼べません。
Initでコンストラクタを呼ぶ代わりに、
Initで実際の初期化をして、コンストラクタでInitを呼ぶのがいいでしょう。

500 名前:498 :04/03/19 16:24
>>499
ありがとうございます。そうしますです。。。


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