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


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

C++相談室
1 名前:デフォルトの名無しさん :2001/01/22(月) 23:54
v(^・^)v

2 名前:デフォルトの名無しさん :2001/01/22(月) 23:57
あげとくのv(^・^)v

3 名前:デフォルトの名無しさん :2001/01/23(火) 00:08
CやめてC++に移ることのメリットとデメリットを教えてv(^・^)v

4 名前:デフォルトの名無しさん :2001/01/23(火) 00:11
C/C++って書いたらハッカーを名乗る人に怒られました
どうしてですか?

5 名前:デフォルトの名無しさん :2001/01/23(火) 00:18
>>4
そいつ、「ハッカー」じゃなくて「バッカー」じゃなかったですか?
もしかしたら、プロブラマかもしれません。

6 名前:4 :2001/01/23(火) 00:32
そのひといわく

CとC++は別のものだから一緒にしちゃだめだよ〜(笑
キミ、もっとべんきょうしたほうがいいよ
いまどきC/C++なんて書いてるようじゃだめだめだね。

ということだそうです。
「別だから」って意味不明です。


7 名前:デフォルトの名無しさん :2001/01/23(火) 00:42
|C/C++って書いたらハッカーを名乗る人に怒られました
|どうしてですか?

ザーメンがたまってむしゃくしゃしていたんだよ。
そーゆーもんよ

8 名前:デフォルトの名無しさん :2001/01/23(火) 00:58
C++でPerlなどのようなパターンマッチをしてくれる関数は無いんですか?


9 名前:デフォルトの名無しさん :2001/01/23(火) 01:07
>>6
>いまどきC/C++なんて書いてるようじゃだめだめだね。
時代は関係無いぜ。
そいつだってC++でCのライブラリ使ってんだろ?
コンパイラはC/C++両用だろ?
違うなら「別」でいいけど、氏んで欲しいナ!>バッカー

>>8
Perlよく知らんのだけど、正規表現とか?lexとかじゃダメ?


10 名前:デフォルトの名無しさん :2001/01/23(火) 01:09
class A {
public:
class B {
public:
void Set(const A& a);
private:
int m_nCnt;
}
private:
int m_nNum;
};



void A::B::Set(const A& a)
{
m_nCnt = a.m_nNum;
}

がコンパイルエラーになります。
コンパイラは「A::m_nNumにアクセスできないよ」
といいます。
そういうものなのでしょうか?


11 名前:10 :2001/01/23(火) 01:11
あらら、インデントがなくなってる・・・
見づらくてごめんなさい。


12 名前:>10 :2001/01/23(火) 01:13
privateだし。
publicにしちゃだめなの?

13 名前:10 :2001/01/23(火) 01:21
>>12
publicしてもいいんですが
せっかくクラスをネストさせてるのに
アクセスできないんじゃさみしぃなぁとおもったので。
イテレータっぽいの書いてたんですけど
イテレータって、どうしてもコンテナの内部にアクセスしなきゃ
ならなくて、
なるべく公開するもの少なくしようとしてクラス(この場合イテレータ)を
ネストさせたんですが、上のようなエラーが無常にも出てしまったんです。
ネストしたクラスの特権(特徴)ってあんまりないんですかね??


14 名前:デフォルトの名無しさん :2001/01/23(火) 01:55
MFC的
#define offsetof(s,m) (size_t)&(((s *)0)->m)

class A {
public:
class B {
public:
void Set();
private:
int m_nCnt;
} m_xB;
friend class B;
private:
int m_nNum;
};

void A::B::Set()
{
A* pThis = ((A*)((char*)this - offsetof(A, m_xB)));
m_nCnt = pThis->m_nNum;
}



15 名前:10 :2001/01/23(火) 02:16
MFCってなんかすごそう。。。
ヌルポインタから->伸ばすあたりはドキドキものですね。。。

ところで
friend class B;
ならば、そこまでトリッキーにならなくてもいいんじゃないかと・・・
(というか、pThisがどこをアクセスしているのか良く分かりません・・・)

16 名前:デフォルトの名無しさん :2001/01/23(火) 02:32
>>15
同じこと思いました。>>10のclass Aの中にfriend B;を加えれば全て解決です。

friend は誤解されることが多いのですが、これは安全のためにあるのですよ。
隠蔽度を高くするためにあるのです。
public な A::GetNum() const; を作るほうがはるかに危険だから、
firend を使うわけですよ。


17 名前:デフォルトの名無しさん :2001/01/23(火) 02:37
class A に public インターフェースで m_nCnt を変更する
メソッドをつけるのはためしました?
ネストしたクラスっていうのは書いたこと無いんでわからないんだけど

18 名前:デフォルトの名無しさん :2001/01/23(火) 02:39
あーごめん ボケですな >>17

19 名前:10 :2001/01/23(火) 02:41
>>16
friendは安全のためなのですか。
そうだったのですか・・・了解です。
「friendは悪」と思っていたので
friend使わないで良い方法を探していたのですが
(それでネストしたクラスとか試してたんですが)、
friend使うことにします。

20 名前:10 :2001/01/23(火) 02:44
>>17
ありがとうございます。
とりあえずfriend使う方針で逝きます。
ネストしたクラスについても知りたかったのですが、
もうすこし自分で調べてみます。
では。。。

21 名前:デフォルトの名無しさん :2001/01/23(火) 03:02
C++とJavaを較べると将来生き残ってそうなのはどちらですか?

22 名前:初心者 :2001/01/23(火) 03:29
2つ疑問があるのですが
VC++6でDOS画面での実行結果がすぐに閉じてしまう。
あと、コマンドライン引数を打ち込むことができない。
よかったらおしえていただけますか。

23 名前:>22 :2001/01/23(火) 03:36
[プロジェクト]-[設定]-[デバック]-[プログラムの引数]
で設定できると思う。


24 名前:>22 :2001/01/23(火) 03:45
>VC++6でDOS画面での実行結果がすぐに閉じてしまう。
!ボタンなら閉じないと思う。
それか、main()の最後に、_getch()とでも書いておく。

25 名前:初心者 :2001/01/23(火) 04:04
>23
ほお。
>24
なるほど。

ずっとCの勉強はLSIC86でやってたんでなれてないです。
また疑問があったら質問しにきます。
ほんとにありがとうございました。

26 名前:デフォルトの名無しさん :2001/01/23(火) 20:59
CLASS B{
 B();
 ~B();
 AA* aa;
}

CLASS A:public AA{
 A();
 ~A();
 B b;
}

という二つのクラスがあったとき
b.aaにAのthisポインタを渡したいんですけど、
AのコンストラクタではthisはNULLでした。
thisはコンストラクタが動いた後からしか使えないんでしょうか?

27 名前:デフォルトの名無しさん :2001/01/23(火) 21:19
>thisはコンストラクタが動いた後からしか使えないんでしょうか?
そんなことは無い。

28 名前:デフォルトの名無しさん :2001/01/23(火) 22:34
>>26
class B
{
private:
 AA *aa;
public:
 B(AA &);
};

B::B(AA &a)
: aa(&a)
{
}

class A : public AA
{
private:
 B b;
public:
 A();
};

A::A()
: b(*this)
{
}

こういうことをしたいのでしょうか?

>>19
>「friendは悪」と思っていたので
>friend使わないで良い方法を探していたのですが

gotoと同じで、無闇に使うのは悪です。
friendを使わなくてもいいのに済むならそのほうがいいですし、
上手く使うにはある程度の技量が必要です。
しかしこの例の場合のように、明らかに friend を
使ったほうが安全な場合もあるため、
無闇に嫌うのもまた問題があるのです。


29 名前:26 :2001/01/23(火) 23:02
>>28
ごめんなさい
A::A()
: b(*this)
{
}
みたいなのがちょっと良くわかんないので勉強してきます。

簡単にいうと、
AAは既製のクラスなんですが、
一部機能がわかりにくいので使いやすくまとめたクラスがBなんですが
やっぱり機能を使うには
aa->〜〜()
みたいにAAクラスのポインタを使ってるんです(^^;

単に馬鹿なだけでしょうか(^^;

30 名前:ひげ :2001/01/23(火) 23:18
>>29

これをコンパイル実行してみてください。
この方法は「初期化」と呼ばれる方法です。
「代入」と同じ効果を生むのですが、厳密には異なります。
 (たとえば、メンバフィールドが const 変数であった場合など)
詳しい議論は『Effective C++』の第12項を参照すると良いと思います。

// 実行結果
// 777

#include <iostream>
using namespace std;
class Test
{
public:
int number;
Test();
};

Test::Test() : number(777)
{
}

int main()
{
Test t;
cout << t.number << endl;
}

31 名前:デフォルトの名無しさん :2001/01/23(火) 23:29
>29
A::A():b(*this)は、
Aのメンバ変数bを、thisポインタが参照しているインスタンスの値
(つまり自分自身の値)を引数とするコンストラクタを起動して
初期化する、っていう意味だよん。

class BB{
private:
 AA* aa;
public:
 void hage(){aa->hoge();}
}
とやるのは、オブジェクト指向の委譲の考え方。別に変じゃないよ。

ただ、そもそもclass Aとclass Bが相互参照している必要があるの
かどうかをチェックしてある?


32 名前:26 :2001/01/23(火) 23:37
>>28
申し訳ない、どあほうでした

単にクラスAが準備出来てないタイミングで
機能使おうとしてただけでした・・・・

鬱だ・・・・

>>30 >>31
たった今調べ終わったとこでした
解説ありがとうございました。

簡単に言うとMFCでCView(AAクラス)のスクロール関数を
外(Bクラス)にまとめただけです(^^;

AクラスがCViewの派生クラスで、いろいろと使いまわせないかなぁと(^^;

33 名前:デフォルトの名無しさん :2001/01/24(水) 00:16
>32
最近Javaしかやってないので、間違ってると思うが
一応FactoryMethodパターンをどうぞ。
詳しい人突っ込みよろしく。

class B{
public:
 static const int TYPE_AA;
 static const int TYPE_A;
private:
 AA* aa;
 setAA(AA* in){aa = in;}
 B(){}
public:
 B~(){delete aa;}
 static B* create(int B){
  B* instance = new B();
  switch(B){
   case TYPE_A:
    instance.setAA(new A());
    break;
   case TYPE_AA:
    instance.setAA(new AA());
    break;
  }
  return instance;
 }
}
//static変数初期化
static const int B::AA=0;
static const int B::A=1;

使用法
B* bAA=B::create(B::AA);//AAのインスタンスをBに持たせたいとき
B* bA=B::create(B::A); //AのインスタンスをBに持たせたいとき

34 名前:デフォルトの名無しさん :2001/01/24(水) 00:17
間違った。

//static変数初期化
static const int B::TYPE_AA=0;
static const int B::TYPE_A=1;

使用法
B* bAA=B::create(B::TYPE_AA);//AAのインスタンスをBに持たせたいとき
B* bA=B::create(B::TYPE_A); //AのインスタンスをBに持たせたいとき



35 名前:質問の名無しさん :2001/01/24(水) 00:31
ARMだったかプログラミング言語C++かなんかに書いてあったのですが、
「operator T()の定義は避けよう」と有ったのですが
理由がよくわかりません。やっぱり、あいまさの問題が出てくるからでしょうか?

36 名前:デフォルトの名無しさん :2001/01/24(水) 01:18
operator T()?そんな定義できるなんて知らんかった。
デフォルトコンストラクタのテンプレート(になるのでしょうか?)
なんか作ってどうするの?

37 名前:デフォルトの名無しさん :2001/01/24(水) 02:26
>>36
いや、キャスト演算子だと思う。

避ける理由は良くわかんないですが、
僕は暗黙の型変換がどうも好きになれないので書かないようにしてます。
(明らかに便利&安全そうなものには書いちゃいますけど)
引数が1つだけのコンストラクタにはexplicit付けてます。


38 名前:ミトコンドリ子 :2001/01/24(水) 10:12
>>35
36のいうとおり、キャスト演算子ね。

避ける理由は
「More Effective C++」,Scott Meyers,安村 通晃 他訳,アジソン・ウェストレイ,1998
ISBN4-7561-1853-4
項目5:ユーザ定義の変換関数に気をつける
を参照してちょうだい。

ちょう要約すると「基本的な問題は、このような関数がしばしばあなたが望みもしなければ
期待もしないようなときに呼ばれてしまうことにある。結果は正しくなくなることもあれば、
診断が気の狂うほど難しくなるような、直感的でないプログラムの振る舞いに
なることもある。」

39 名前:デフォルトの名無しさん :2001/01/24(水) 17:17
 wide characterを使った処理をしたいのですが、
wofstream に wchar_tで出力しても、ofstreamにcharで出力しても
結果がまったく変わりません。バイナリモードでファイルを開いても
だめです。例えば、L'A'を出力したときに、0x4100がファイルに
入っていればいいんですけど。
この厨房をお助けください。

40 名前:デフォルトの名無しさん :2001/01/24(水) 17:23
 すいません。39です。処理系を書くべきでした。
 環境はWindowsNT4でVC6です。ただ、質問がVC関係ではないので
ここを選ばせてもらいました。よろしくおねがいします。

41 名前:名無しさん@@ :2001/01/24(水) 17:44
>>39
うん、だから入出力時にマルチに変換してる。
ライブラリの問題以前に規格やフォントの問題もあるし。
linuxだとwctomb関数がマニュアルにある。
(マルチスレッド云々と状態の切り替えの話に注意して読んで)



42 名前:デフォルトの名無しさん :2001/01/28(日) 00:51
みんなC++を使うのだage

43 名前:デフォルトの名無しさん :2001/01/28(日) 01:55
DOSの16bitの環境で動作するANSI C++に追従してる処理系ってあります?
DJGPPみたいに、DPMI上で動く様なのは除外してください。
つまり80186で動く様な物です。
テンプレートはでかくなるので無くても良いですが。
(すると、ライブラリの大半が使えない?)
「例外」程度は使いたいです。

44 名前:デフォルトの名無しさん :2001/01/28(日) 02:26
BCC45

45 名前:デフォルトの名無しさん :2001/01/28(日) 03:14
>>44
Borland処理系は4以降からDPMI使ってるみたいなのでだめです。

46 名前:デフォルトの名無しさん :2001/01/28(日) 04:10
>>45
TC++1.0
一番初期のヤツね。ディスク3枚組みのヤツ。
正真正銘16BitDOSでC++。
80186オプションもちゃんとあるぞ。


47 名前:デフォルトの名無しさん :2001/01/28(日) 15:00
>>46
43の「ANSI C++に追従している」という意味は、多分
RTTIやnamespaceや例外やテンプレートのような後発の仕様、
および STLその他現在の標準C++ライブラリをサポートしている
という意味だと思うが....俺は知りません。
しかしテンプレート使うとモノがでかくなりがちであり
pureなDOS環境ではちと厳しいのでは。


48 名前:デフォルトの名無しさん :2001/01/28(日) 15:03
複数のクラスから使いたいサブルーチン(memcpy類似のアプリ固有
のよく使う処理)って、どういう名前空間に置きますか?
アプリのメインのクラス内にpublicで置くと、そのクラスのインス
タンスをexternするか、子クラスにポインタを渡していかなければ
ならず、すっきりしません。
かといって大域に置くのも何かCくさくて嫌なのです。

49 名前:デフォルトの名無しさん :2001/01/28(日) 15:08
singletonにすればー.

50 名前:46 :2001/01/28(日) 16:10
>>47
43はテンプレート無しで良いっていってんじゃん。よく読め。
RTTIって使ってる奴いんの?その辺はどうだか知らん。


51 名前:デフォルトの名無しさん :2001/01/28(日) 18:42
>>48 はstaticなメソッドを知らないらしい。

>>50 Embedded C++ だね、それ。
RTTI を使っているやつは存在する。
オブジェクト指向初心者は多重継承を下手に使って失敗する。
オブジェクト指向中級者は多重継承を嫌って使わない。
オブジェクト指向上級者は多重継承を上手く使って楽をする。

ちなみに俺は中級者。


52 名前:デフォルトの名無しさん :2001/01/28(日) 20:01
ATL固有の話になってしまって申し訳ないのですが、
CWindowImpl<>::Create()
ってオーバーライドしても平気なのでしょうか?
オーバーライドする必要があるのですが、virtual宣言されていないので
どうなってしまうのでしょうか。

実際に使ってみたところ問題なく使用できているのですが、
正しいのか間違いなのか、教えてください。

53 名前:デフォルトの名無しさん :2001/01/28(日) 21:07
>>52
virtualをちゃんと勉強しよう。
ライブラリ的には問題ないと思う(信じたい)けど、
52の使い方次第。
virtual宣言すると、派生元のクラスのポインタで呼んでも、
派生クラスで生成してれば派生クラスのメンバ関数が呼ばれる。
(デストラクタだとちょっと違うが)


54 名前:デフォルトの名無しさん :2001/01/28(日) 21:27
オーナードローボタンクラスを作ってたのですが、
生成するたびにBS_OWNERDRAWを指定させるのもなんだかな、って思ったので、
CreateをオーバーライドしてBS_OWNERDRAWをしていしてから
CWindowImpl<>::Create()に渡しているのですが、
この場合問題なさそうですね。

>virtual宣言すると、派生元のクラスのポインタで呼んでも、
>派生クラスで生成してれば派生クラスのメンバ関数が呼ばれる。

これはわかっていましたが、オーバーライドさせるときは無条件で
virtualと思ってたので、質問しました。
やっぱりプログラミング言語C++買うべきですね。
あれってCと違ってべらぼうに高いんですが(^^;

55 名前:デフォルトの名無しさん :2001/01/28(日) 21:36
高いのは理解できなくなもないが、
分厚くてでかいのがきつい。
持ち運び不便。

56 名前:55 :2001/01/28(日) 21:37
1行目
なくな→なく

57 名前:デフォルトの名無しさん :2001/01/28(日) 21:50
おいら、多重継承は前まで絶対しないことにしてたんだけど、
Javaを覚えてからは、C++で多重継承するときは必ず片側は
完全抽象クラスのみにするようになった。
関数実装の多重継承は禁止。これで安心。僕って上級者???

58 名前:43 :2001/01/28(日) 23:46
ボーランドサイトでTurboC++1.01が見つかりましたので、これで我慢します。
ちなみに例外は使えない様です。4.0からかな?
ついでですが、RTTIや名前空間とかは使わないです。>47
#C++はもっとCみたいにコンパクトな言語にならないですかね。

59 名前:43 :2001/01/29(月) 00:02
いままでわたしはCでOO風に書いてきました。
CでOO風に書く利点としては、Cさえ動けばどんな環境でも使える事ぐらいですが、こういう事やってる(やってた)人います?
不便な点は、Cではinlineキーワードが標準で使えないから、アクセサの効率を上げる為に、処理系毎に__inlineだの、static __inline__だのをマクロ定義しなきゃいけないとか、色々面倒が多いですが。
それと、他人にソースを渡す場合は困りますね。
いちいち書き方の説明する様な事をしなくちゃいけないんで。
そういう時はC++でラップして渡しています。(二度手間ですが)

60 名前:デフォルトの名無しさん :2001/01/29(月) 00:18
RTTIって何に使うの?用途が思い浮かばない。デバッグ?

61 名前:名無しさん@Emacs :2001/01/29(月) 00:20
callback してきたオブジェクトをいつ delete するか悩んでいます.
例えば...

class B {
public:
 B(A* a) { a->onCallBack(); }
};

class A {
public:
 B* createB() { return new B(this); }
void onCallBack();
};

とかなってる場合,
B のインスタンスはいつ delete すればよいですか?
A::onCallBack() に B* を乗せて
void onCallBack(B* b) { delete b; }
とかするのはだめですよね.

つまり, callback 後は必要ないオブジェクトの破棄をいつ行うか?
ということなんですが, いい方法あるでしょうか?

62 名前:デフォルトの名無しさん :2001/01/29(月) 00:25
>59
多分CでOO風に書くって、1ファイル1クラスに見立てて、ファイルスコープ
のグローバル変数をインスタンス変数に見立てて、そのファイルの関数を
唯一のそのグローバル変数へのアクセス手段にするようにするとかだよね。

CでOO風に書いても、クラスとインスタンスの関係は実現できないので
ポリモルフィズムが表現できないと思うんだけど、其の辺は無視?
単なる概念モジュールの階層構造化を指してOOと呼んでるのでしょうか?

>60
ポリモーフィズムの意義を勉強せよ。

63 名前:デフォルトの名無しさん :2001/01/29(月) 00:32
>61
よう分からんが、Bのインスタンスはスマートポインタで
ラップして値で持ちまわるようにしたら?

64 名前:60 :2001/01/29(月) 00:46
>>62
RTTIでポリモフィズムとなると、
typeid演算子を使って、実際のクラスを判別するんですか?
かえっておかしなことになるような。

なんか勘違いしてます?

65 名前:43 :2001/01/29(月) 01:25
>>62
グローバル変数は一切使いません。
インスタンスはスタック、またはヒープに確保します。
シングルトンパターンの実装やリソースカウンタなどはstaticな変数を使いますが。
多態が必要な場合、typeid(実はenumやint)と関数のポインタテーブルを使って実装します。(かなり面倒ですが。)

66 名前:ミトコンドリ子 :2001/01/29(月) 09:54
>>60
RTTIはtypeidよりはdynamic_castでよく使うんじゃないかしら。

用途としては、抽象クラスのポインタ(参照)しかとれない場合(たとえば
抽象クラスのポインタのコンテナをイテレートするとき)に、なんらか
(派生クラスでしか定義されていないメンバを呼びたいとか)の理由で
ダウンキャストしなくちゃいけないときが一番多いかしら。
なるべく使いたくないけど、compositeパターンなんかを使うと
ある程度は使わざるをえなくなることが多いわ...

なるべくdynamic_castを使わずにすむように心がけながら設計
してるけどね。

67 名前:ミトコンドリ子 :2001/01/29(月) 10:01
>>61
まず所有関係に注意しながら設計を見直すのが最初だと思うわ。多くの場合は
きちんと考えれば、どのインスタンスをいつ破棄すれば良いかは明確にできると
思うけど。
それが難しい場合(スレッド間で受け渡しするインスタンスなど)は、63の言うとおり
何らかのスマートポインタを使うのがいいんじゃないかしら。
でもうまく使わないとバグの温床になるわよ。気をつけてね。

68 名前:デフォルトの名無しさん :2001/01/29(月) 10:13
わかったからそのネカマ言葉をやめてくれ

69 名前:デフォルトの名無しさん :2001/01/29(月) 10:17
>67
C++を知らない奴が、スマートポインタに関数内のローカル変数の
アドレス渡して、その後原因不明で落ちる!と大騒ぎするのを
多々目撃しております。


70 名前:60 :2001/01/29(月) 11:48
>>66
RTTIってdynamic_castも含めるのね。dynamic_castなら使っていますので解かります。
てっきりRTTI=typeidで得るclass type_infoのことかと思い込んでいました。
親切な回答ありがとうございました。

では改めて質問。
typeid演算子、ならびにclass type_infoって何に使っていますか?


71 名前:デフォルトの名無しさん :2001/01/29(月) 12:00
デバッグ用機能です

72 名前:ミトコンドリ子 :2001/01/29(月) 12:55
>>69
やりがちよね。
class Foo {
protected:
Foo();
public:
virtual ~Foo();
public:
static SmartPointer<Foo> create();
};
みたいにして、スマートポインタの使用を強制するようにしてるわ。

>>70
めったに使わないわ。おもにassertで使うわね。
派生クラスじゃなくて、ぜったい特定のクラスのインスタンスが
欲しいときとかに assert( typeid(*ptr)==typeid(Foo) );とか。


73 名前:デフォルトの名無しさん :2001/01/29(月) 14:45
ミリ秒間、何かの処理をさせるみたいな時に使う時間をはかるもの
タイマーって言うんでしょうか?
そういったタイマーで、一般的に使われる関数を教えて下さい


74 名前:SAGE :2001/01/29(月) 14:56
>>73
時間を計るなら clock かな?

75 名前:デフォルトの名無しさん :2001/01/29(月) 15:05
winapi -> SetTimer()

76 名前:デフォルトの名無しさん :2001/01/29(月) 16:40
精度が必要ならマルチメディアタイマー

77 名前:61 :2001/01/29(月) 21:02
>>63
B を作るオブジェクトは最後まで死なないので
スマートポインタは使えなさそうな気がします.
なんか間違ってるかな.

>>67
設計見直しですか.
いや, そんな気はしてんだよなぁ.

もちっと考えてみます.
2人ともありがとっ


78 名前:73 :2001/01/29(月) 22:07
なるほど
ありがと、74・75・76


79 名前:age :2001/02/15(木) 04:19
class A
{
public:
  A();
private:
  const int m_data[10];
};

で、class AのコンストラクタA::A()を書こうとして困ってしまいました。
A::m_data[10]の初期化はどのように書けば良いのでしょうか?
constにしているのは困っているところを強調するためなのでご了承ください。
メンバ配列の初期化ってムリなんですかね・・・

80 名前:minima :2001/02/15(木) 06:31
>>79さん
const を外して
A::A(){
  for( int i=0; i<10; i++)
    m_data[i] = i;
}
です。

・・・だと思います・・・自信なし・・・。

81 名前:80 :2001/02/15(木) 06:35
あああ〜〜〜〜
やっぱし違うと思います。すいません。無視してください。

82 名前:デフォルトの名無しさん :2001/02/15(木) 06:54
A() {
 int i;
 int * p = (int *)m_data;
 for( i = 0; i < 10; i++ ) p[i] = 0;
}
こんなんど?

83 名前:79 :2001/02/16(金) 01:31
>>80,82
質問のしかたがまずかったかもしれません。
やりたいこととしては

A::A()
: m_data(????)
{
 //ここには書きたくないのです・・・
}

のように初期化列の中に配列の初期化を書きたいなぁと思ったのです。
普通のメンバ変数だったら

class B
{
public:
B() : m_data(0) {}
private:
const int m_data;
};

みたいに書けるのに、配列はどう書けばよいのやら・・・
どうあがいてもムリ??

84 名前:デフォルトの名無しさん :2001/02/16(金) 02:56
配列はできないような…?std::vectorじゃだめ?

85 名前:79 :2001/02/16(金) 03:43
>>84
std::vectorほどの柔軟性は必要なかったりしてるんです。
動的にメモリ確保されても困るので・・・
具体的には今3Dのプログラム組もうとしていて、
4次元ベクトルのクラスとか作ろうとしたとき
struct Vector
{
  Vector(float x, float y, float z, float w);
  float m_data[4];
};
てな具合にしたのですが
m_data[4]の初期化で困ってしまったということでした。

やっぱり配列はどうしようもないようですね。
あきらめて80,82さんのようにコンストラクタの{}中に書きます。
ありがとうございました。

86 名前:デフォルトの名無しさん :2001/02/16(金) 04:43
つうか、配列でそんな書き方できるほうが危ないんだよ。
もうすこし勉強しないとわからんかもしれんが。

87 名前:デフォルトの名無しさん :2001/02/16(金) 09:01
最近、vectorやlistを独自の使ってるのを見ると、
素直にSTL使ってくれって思うぜー。
メモリは先に必要な分だけ確保しておけば問題ないぜー。

88 名前:デフォルトの名無しさん :2001/02/16(金) 09:53
初期化列の中に、初期化する変数書く利点ってなんだ?
配列は初期化できないし…?

89 名前:デフォルトの名無しさん :2001/02/16(金) 12:13
利点というよりそこに書かなきゃならない場合があるだけです。
逆に言えば初期化列に記述できないものはそもそも初期化列
で初期化する必要がないという事。
つまり今回の例は「ここに書きたくない」なんてゴネてないで素直に
{}に書けつーことです。

90 名前:デフォルトの名無しさん :2001/02/16(金) 12:15
デバッグ用に内部データがデバッガで見やすくかつ鬼のように
チェックの厳しいSTLの実装ってどこかにない?

91 名前:デフォルトの名無しさん :2001/02/16(金) 12:45
>>87
キミ、ちょっとズレてるよ。

92 名前:デフォルトの名無しさん :2001/02/16(金) 13:21
>>89 利点というよりそこに書かなきゃならない場合
ってのはどういう場合なのん?

93 名前:だめだこりゃ :2001/02/16(金) 14:17
デフォルト以外で初期化したい基底クラスや
デフォルトコンストラクタを持たないオブジェクト、
参照やconstオブジェクト、
効率のためデフォルトの初期化を行ないたくない場合とか
その他いろいろあるっしょ

94 名前:わざわざすまんのお :2001/02/16(金) 15:03
{ } 内では、できない初期化があるってことなのか…。


95 名前:デフォルトの名無しさん :2001/02/16(金) 16:50
配列自体を病める方に一票。

96 名前:デフォルトの名無しさん :2001/02/16(金) 16:55
Cでは
struct ta sub()
{
struct ta a;
return a;
}
は禁じ手ですが(autoのstructを返すため)
C++では
CString xxxxx()
という関数がいっぱいあるのはなぜでしょう?
C++ではクラスのリターン値は保証されるのですか?


97 名前:デフォルトの名無しさん :2001/02/16(金) 18:14
>>96
C++でもauto領域のリターンは御法度だ
ソースはみたか?
CString xxxx()のなかでauto変数領域返してるか?


98 名前:デフォルトの名無しさん :2001/02/16(金) 18:48
御法度じゃないぞ。代入コンストラクタって言葉知ってるか?

99 名前:デフォルトの名無しさん :2001/02/16(金) 18:54
returnで代入コンストラクタが働くって意味かい?


100 名前:98じゃないけど :2001/02/16(金) 19:01
>returnで代入コンストラクタが働くって意味かい?

そうよ。

AnyClass obj;
obj = anyFunc(なんかの引数);

とかで、anyFuncがAnyClassのautoオブジェクトをreturnしてたら、
1.AnyClass::AnyClass(const AnyClass&)でリターン用臨時オブジェクトが作られる。
2.AnyClass::operator=(const AnyClass&)で臨時オブジェクトがobjへコピーされる。
3.臨時オブジェクト消滅
てなことが舞台裏で行われるのです。

処理系の実装によっては、もちょっと最適化されるかも知れんけど。


101 名前:100 :2001/02/16(金) 19:05
でも、96みたいなのも近頃のCでは
御法度じゃなかったんじゃない?

struct ta* func() {
 struct ta taObj;
 return &ta
}

は、おもくそまずいけど。


102 名前:100 :2001/02/16(金) 19:06
ちがった、

struct ta* func() {
 struct ta taObj;
 return &taObj;
}

だ。


103 名前:デフォルトの名無しさん :2001/02/16(金) 19:07
ちなみに
AnyClass obj = anyFunc(なんかの引数)
ってやったらどうなるか考えると面白いぞ



104 名前:いさましいチビの女 :2001/02/16(金) 19:57
>>96
101も言ってるけど、それが禁じ手なんて初めて訊いたよ。
どこのダレがどういう理由で禁じ手にしてるか教えてくれ。


105 名前:デフォルトの名無しさん :2001/02/16(金) 20:08
コピコンちゃんとつくるの忘れてるくせに
オブジェクトリターンかましたあほが広めてるんじゃないの?
>>104

106 名前:デフォルトの名無しさん :2001/02/16(金) 20:15
おそらく,
 ・構造体はでかいからポインタでやりとりしたほうがいい
 ・autoなオブジェクトへの参照を返してはいけない
が,どこをどう勘違いされたのか
 ・autoな構造体オブジェクトは参照でかえせないから,
  リターンしてはいけない
と勘違いされたんじゃないかな。C言語でもautoオブジェクト
を値で返す分には支障はないよ。

原理がわかってないとこういう勘違いが起こるんだろうね。

107 名前:デフォルトの名無しさん :2001/02/16(金) 20:16
>>105
ありそうだな。でも96は、
「Cでは…は禁じ手ですが…」
と言ってんだよね。

108 名前:デフォルトの名無しさん :2001/02/16(金) 20:19
       うぇーん、C++なんかきらいだー
         ̄ ̄ ̄∨ ̄ ̄ ̄ ̄ ̄ ̄
           ∩_∩
          ( ´Д⊂ヽ
         ⊂    ノ
           人  Y
          し (_)


109 名前:105 :2001/02/16(金) 23:24
>>107
む、確かに。

101、102!
余計な口挟むんじゃねぇ!C厨房ゴルァ!

なんつってな、無視したんだよ、虫。

110 名前:105 :2001/02/16(金) 23:34
番号間違えた。
よって意味不明。
逝ってきま〜す。

111 名前:79 :2001/02/16(金) 23:34
もりあがってるところ申し訳ないのですが、
>>93
constなメンバ変数の初期化は初期化列に書くしかないわけですよね。
で、僕が最初に質問してたんですが、

class A
{
public:
  A();
private:
  const int m_data[10];
};

みたいな作りにしなきゃいけないってことになっら
A::m_data[10]はどのように初期化すればよいのでしょう?
>>82 みたいに強引にやるしかないんですかね。。。

112 名前:デフォルトの名無しさん :2001/02/16(金) 23:39
初期化のときだけconst_castしたら?

113 名前:79 :2001/02/16(金) 23:49
そうですね・・・あきらめます。
あぁ、どうも配列だけC++の中で異質な感じがする今日この頃。。。

114 名前:部外者A :2001/02/16(金) 23:49
96の言い分も少しは正しい。(かった?)
まず、昔のCコンパイラは構造体の(ポインタではなく)インスタンスを返せない物があるって事。
返せても特別な領域(strtokと同じ様な場所)に一旦コピーするものもあったから、そういう処理系ではスレッドセーフにもできなかった。
よって、そういった処理系での互換性をも保とうとしているプログラマから見れば、構造体を返却値に持つ関数を定義する事は「禁じ手」であると言える。
現在のANSI-Cに準拠する処理系でのみ動作を期待するプログラムならば、スタックにコピーするので問題ない。
こんなんでどう?>96,その他

115 名前:デフォルトの名無しさん :2001/02/16(金) 23:52
>113
まあねー。クリティカルセクションじゃなけりゃSTL使うわな。

116 名前:106 :2001/02/17(土) 01:43
>>114
まぁ,確かに。

>>113 ,(111,79)
うーん,要素数をテンプレート引数に取るテンプレートな
スマートアレイじゃだめなの?

117 名前:デフォルトの名無しさん :2001/02/17(土) 01:46
const配列メンバはstaticじゃなきゃ。
よって、素直にクラス使っとけ。

118 名前:>113 :2001/02/17(土) 03:02
クラス内のconstは実装部で宣言して初期化もそこでする。
effective c++、ずばり一章。

class aaa{
public:
static const int const bbb[10];
void showprivate(void)
{
for(int i=0;i<10;i++)
cout << ccc[i] << ":";
}
private:
static const int const ccc[10];
};

const int const aaa::bbb[]={0,1,2,3,4,5,6,7,8,9};
const int const aaa::ccc[]={10,11,12,13,14,15,16,17,18,19};

int main(int argc, char* argv[])
{

for(int i=0;i<10;i++)
cout << aaa::bbb[i] << ":";

cout << endl;

aaa c;

c.showprivate();

cout << endl;

return 0;
}

119 名前:79 :2001/02/17(土) 03:29
>>116
template <class T, size_t N>
struct CArray { T m_data[N]; };
みたいな感じのを配列の代わりに使えってことでしょうか?
んんん、、、問題を先送りにしている感じがしないでもないですが
改善になるのかな?
class A
{
public:
  A(const CArray<int,10>& data)
  : m_data(data)
  {}
private:
  const CArray<int,10> m_data;
};
で無事constな配列の初期化ができました(なのかな???)

>>117 >>118
staticなconstの配列だったら悩まなくてもokですね。
でも今回の場合staticではないconstな配列の初期化で悩んでたので・・・

>>115
思う存分STLが使える開発っていうのも一度やってみたいです。。。
(でもきっとSTLの実装が気になって思う存分使えないんだろうなぁ>自分)

120 名前:106=116 :2001/02/17(土) 04:09
>>119
そうそう,そういうの。メモリ上の配置も素の配列と変わらないから
いけると思うんだけど。


121 名前:デフォルトの名無しさん :2001/02/17(土) 04:32
そこまで初期化式にこだわる理由がわからない・・・

122 名前:79 :2001/02/17(土) 04:39
>>120
たしかにCArrayのコピーコンストラクタで初期化できるようになったのは
改善だと思うのですが、class A に
A::A(int a0, int a1, int a2, int a3, int a4,
   int a5, int a6, int a7, int a8, int a9)
みたいなコンストラクタも欲しいなぁとなると、またconst_castの
お世話になってしまいますよね・・・
CArrayの初期化の方法が、コピーコンストラクタと配列の初期化の
方法しかないからしょうがないんですけど・・・

まあ、あまりダダをこねないで、
配列と仲良くやっていこうと思ったのでした。

123 名前:79 :2001/02/17(土) 04:41
>>121
気になるとこだわってしまう性格でして・・・すみませんでした。

124 名前:106=116 :2001/02/17(土) 04:42
>そこまで初期化式にこだわる理由がわからない・・・

79氏は,リアルタイム処理やゲームプログラミングをなさってるんじゃないかな?
初期化式で初期化すれば,デフォルトのメンバ初期化をスキップできて
効率がいいし,STLを使わないのも,メモリ領域を静的にとりたいのか,もしくは
開発環境が組み込み用とかでSTL自体が整備されてない環境とか?


125 名前:デフォルトの名無しさん :2001/02/17(土) 05:27
<stdio.h> ってスタンダードアイオーヘッダーって読みますよね。
今日学校の教師に <string.h> の読み方を 「スタンダードリングヘッダー」って教わりました。
これって「ストリング」って読むんじゃ無いですか?
自分は間違いだと確信有るんですが。

それと教師に指摘してあげるべきだったでしょうか。

126 名前:79 :2001/02/17(土) 05:30
>79氏は,リアルタイム処理やゲームプログラミングをなさってるんじゃないかな?
むむむ、、、なんか書きこみにクセとかありました??
んーとりあえず退散します。ありがとうございました。

127 名前:デフォルトの名無しさん :2001/02/17(土) 05:41
>>125
stdio.h ... スタジオ・ヘッダー
と読んでいました。学生の頃。

というか、C的話題?

128 名前:デフォルトの名無しさん :2001/02/17(土) 08:46
>>125
そういうのは、わかっていても言わないの。

129 名前:96 :2001/02/17(土) 14:53
みなさんありがとうございました。そしてごめんなさい。
Cの所は引き合いに出すために適当に書いてしまいました。
101さんのようなことはまずいと言いたかったのです。
知りたかったのはCStringの戻り値のみなので
理解できました。
もっと勉強します。

130 名前:デフォルトの名無しさん :2001/02/17(土) 23:45
質問なのですが
http://demo.and.or.jp/makedemo/mini_class/file_search/index.html
にあるソースをbcc5.5.1でコンパイルしたのですが
エラー E2285 'output_filename::operator () <_NAME,_MORE_INFO>(string,_WIN32_FIND_DATAA)' に一致するものが見つからない(関数 search_file<string,output_filename>(string,string,const bool,output_filename &) )
*** 1 errors in Compile ***
というエラーが出て困ってます。どうすれば回避出来るのでしょうか?

131 名前:部外者A :2001/02/18(日) 00:26
ネタなんだろうけど・・・
#include <windows.h>
って行は先頭辺りにある?>130

132 名前:部外者A :2001/02/18(日) 00:31
あ、#endifが無い様だね。そのソースとヘッダもう一度よく見てみると良いよ・・・>130

133 名前:デフォルトの名無しさん :2001/02/18(日) 01:48
>131>132
#include <windows.h>はあります。
#endifもエラーで出たのですぐに書き加えました。
それでもやっぱりエラーになるんですよね。
なぜなんでしょうか?記述ミスがまだあるんでしょうか?

134 名前:ミトコンドリ子 :2001/02/18(日) 03:08
>>130
テンプレートメンバ関数は、コンパイラによっては正確にコンパイルできないことが
多かったわ。
テンプレートメンバ関数を無くして書き直してみたらどう?
動けばメンバテンプレート周りのコンパイラのバグ。
動かなければその他の原因ね。

#この程度の機能をテンプレートメンバにする必要性は感じないけどね。

135 名前:130 :2001/02/18(日) 03:26
>>134
それはもう既にやってみたんですが、一応ちゃんと動きました。
やはりbccのバグなんでしょうか?
バグならあきらめるしかないですね・・・。


136 名前:ミトコンドリ子 :2001/02/18(日) 03:32
>>135
バグだと思うわよ。
短いコードでバグが出せるなら、サポートに送っておくといいわ。
次のバージョンで直る「かも」しれないしね。

あとは
・テンプレート引数の数を減らす
・テンプレート引数を明示する
とかして、コンパイラが探索しなくちゃいけない範囲を限定してあげると
通ったりすることもあるわよ。でも不毛な努力になることが多いから
お勧めはしないわ。

137 名前:130 :2001/02/18(日) 03:40
>>136
わかりました。出来たらサポートに送ってみようと思います。
不毛な努力の方も試してみます。
ありがとうございました。



138 名前:デフォルトの名無しさん :2001/02/18(日) 05:07
>>130
テンプレートメンバ関数の引数をconstにするとうまくいったよ。

template<class _NAME, class _MORE_INFO>
void operator()(_NAME &filename, _MORE_INFO &info)



template<class _NAME, class _MORE_INFO>
void operator()(const _NAME &filename, const _MORE_INFO &info)

でどう?

ちなみにこれはテンプレートメンバ関数が原因ではないかも。
下のコードでも同様なエラーになります。

template <class T>
T add(T& lhs, T& rhs)
{
  return lhs + rhs;
}

int main()
{
  return add(1, 2);
}

これも同様に引数にconstを付けるとokになります。
この動作って、bcc固有? C++の仕様?
手元にあるコンパイラがbccしかないので確認のしようがない・・・
どなたかhelp・・・

139 名前:130 :2001/02/18(日) 06:26
>>138
おお!const付けると上手く行きました。ありがとうございます。
自分もbccしか使ってないので
VCとかで確かめられないのがつらいです。

140 名前:デフォルトの名無しさん :2001/02/18(日) 08:50
VC++ ではconst無しでも通るみたいっす。>>138-139

141 名前:デフォルトの名無しさん :2001/02/18(日) 14:40
質問です。レベル低くてすいません。
ファイルポインタをファイルの先頭に移動するために
ifstream::seekg() を使用しましたが、うまくいきません。

ifstream ifs("filename");
<-- 読みこみ処理 -->
ifs.seekg(0, ios::beg); // <- ポインタを先頭に
<-- 読みこみ処理。でも読めない…

間違ってますか?



142 名前:デフォルトの名無しさん :2001/02/18(日) 15:23
>>138
C++の仕様上、非const参照の初期値は左辺値でなければならない。
だからエラーになるのが正しいと思う。
エラーにならないコンパイラは古いソースとの互換性を
考慮してるのではないかな。

143 名前:138 :2001/02/18(日) 15:49
>>142
なるほど。 >>138 の add(1,2) の「1」とか「2」は
左辺値ではないですね(右辺値?)
>>130 の例では、filesrc.hの65行目の
op(strCurrentFolder+"\\"+FindData.cFileName, FindData);
の第1引数「strCurrentFolder+"\\"+FindData.cFileName」が
左辺値ではないんですね。

侮りがたし>bcc

144 名前:106 :2001/02/18(日) 16:47
>>141
オープンには成功しているわけですね。
お使いの処理系は? C++の規格だと,ios::begじゃなくて
iso_base::begですよ。古いヘッダを使ってるとか?

145 名前:144=106 :2001/02/18(日) 16:49
あ,ごめんなさい。タイプミスです。

iso_base::beg

ios_base::beg


146 名前:106 :2001/02/18(日) 18:51
>>79

効率はどうでもいいなら,こんなのはどうですか?

#include <iostream>
#include <cstdarg>
#include <cstddef>
#include <algorithm>
using namespace std;

template<class T, size_t sz> class Array {
T buff[ sz ];
public :
Array() {}
Array( size_t n, ... ) {
va_list ap;
va_start( ap, n );
for( size_t i = 0, lim = min( sz, n ); i < lim; i++ ) buff[i] = va_arg( ap, T );
va_end( ap );
}
template<class T2, size_t sz2> Array( const Array<T2, sz2> & a ) {
size_t lim = min( sz, sz2 );
for( size_t i = 0, lim = min( sz, sz2 ); i < lim; i++ ) buff[i] = a[i];
// sz < sz2 の場合は例外を投げても良いかもしれない
}
// コピーコンストラクタとコピー代入演算子はデフォルトで十分

T& operator[]( size_t i ) { return buff[i]; }
const T& operator[]( size_t i ) const { return buff[i]; }
// 添え字範囲が範囲外なら例外を投げるat()を定義しても良いかもしれない
operator T*() { return &(buff[0]); }
operator const T*() const { return &(buff[0]); }
};

template<class T, size_t sz>
Array<T, sz> AIL( T first, ... ) { // ArrayInitList
Array<T, sz> temp;
va_list ap;
va_start( ap, first );
temp[0] = first;
for( size_t i = 1; i < sz; i++ ) temp[i] = va_arg( ap, T );
va_end( ap );
return temp;
}

template<class T, size_t sz, size_t n> // 一応用意
Array<T, 0> AIL() { Array<T, 0> temp; return temp; }

struct A {
typedef Array<int, 10> myArray;
const myArray array;
A( const myArray & a ) : array( a ) {}
};

int main() {
A obj1( AIL<int, 5>( 10, 20, 30, 40, 50 ) ); // <- こんな感じで引数をグループ化します
for( int i = 0; i < 10; i++ ) cout << obj1.array[i] << endl;

A obj2( AIL<int, 10>( 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 ) );
for( int i = 0; i < 10; i++ ) cout << obj2.array[i] << endl;
return 0;
}

147 名前:106 :2001/02/18(日) 19:20
>>141
ひょっとして,1回目の読み込みでios_base::eofbit
が立ってませんか?

シーク前にclear()を呼んでみて下さい。

ifstream ifs("filename");
<-- 読みこみ処理 -->
ifs.clear(); // <-ここ
ifs.seekg(0, ios_base::beg); // <- ポインタを先頭に
<-- 読みこみ処理 -->



148 名前:141 :2001/02/18(日) 22:04
ifs.clear()を使用することでうまくいきました。
どうもありがとうございます。
処理系はVisualC++6.0 SP4 on NT4.0です。

ios_base を使おうとしたら、シンボルエラーで使えなかったので
ios::begのままです。
調べてみると、インクルードファイル(.h)にはios_baseクラスは
見つからなかったのですが、どうしてでしょうか?


149 名前:106 :2001/02/18(日) 22:45
>>148
うまくいって良かったですね。

>ios_base を使おうとしたら、シンボルエラーで使えなかったので
ios::begのままです。
調べてみると、インクルードファイル(.h)にはios_baseクラスは
見つからなかったのですが、どうしてでしょうか?

拡張子のつくC++用の標準ヘッダファイルは,規格化以前の古い
仕様です。その古い仕様のライブラリでは,ストリームクラスの
最も基底なクラスはiosでした。

というわけで,VisualC++6.0 SP4 on NT4.0がC++の標準規格に
準拠していて,事情が許すのなら,<iostream.h>ではなく,
<iostream>を使って,標準規格にそったライブラリを使うことを
すすめます。

150 名前:保田圭 :2001/02/20(火) 02:43
私の悩みを聞いてください。このようなコード(もちろん簡略化したもの)

char input_buffer = new char[1000];
char output_buffer = new char[1000];

strcpy(input__buffer,"ABCDEFG");
strcpy(output__buffer,input_buffer);

delete input_buffer;
delete output_buffer;

を実行し、input_bufferとoutput_bufferをウォッチリストにいれて観察
するとoutput_bufferの中身が消されずリークができてしまいます。どうして
でしょうか?わたしは初心者以下だからでしょうか?ハロプロのコンサートに
向けていち早くこのコードを完成させなくてはなりません。教えてくれた方に
は私の処女上げます。辞退なさっても結構ですけど。

151 名前:デフォルトの名無しさん :2001/02/20(火) 04:07
とりあえず delete [] input_buffer; delete [] output_buffer;
としてみよう。

152 名前:デフォルトの名無しさん :2001/02/20(火) 04:49
inline 関数を C++ ファイルに extern でなく
static リンケージで定義する方法がわからなくて悩んでいます。
よろしければどうか教えて下さい。

--- header
class Hage {
private:
 inline void f();
}
--- c++ file
inline Hage::f() { ... };
---
と定義すると friend のために .global なやつも
コンパイルしてしまうのでサイズが膨れて勿体無いです。

こういうのも考えたのですが
static inline Hage::f( class * phage, ... )
{
 phage->.. = ;
}
もっと綺麗に書けないでしょうか?

153 名前:保田圭 :2001/02/20(火) 13:07
>>151
試したわよもう。でも不思議と何も起こらない。よかったら
試していただけないでしょうか?

154 名前:IE :2001/02/20(火) 14:21
>>150 >>153
突然ですが、
char input_buffer = new char[1000];
char output_buffer = new char[1000];


char *input_buffer = new char[1000];
char *output_buffer = new char[1000];

こうしてみたらどうです?


155 名前:IE :2001/02/20(火) 14:22
教えてください。
C++、またはWinAPIで、
IEのバージョン取得をしたいのですが。。。

156 名前:デフォルトの名無しさん :2001/02/20(火) 14:24
>保田圭
>>151>>154この両方を追加すれば解決

157 名前:106 :2001/02/20(火) 14:53
>>152
うーん,いってる意味がよくわかりません。
「friend のために .global なやつも
コンパイルしてしまうのでサイズが膨れて勿体無いです。」
という部分が不鮮明で。friendが登場するなら,それも示して
いただけますか? あと,「global なやつ」ということですが,
これは,「クラスの外で定義されたメンバ関数」という意味でしょうか?
(「クラスの外で定義されたメンバ関数」はスコープ的にはグローバル
ではないので)


158 名前:デフォルトの名無しさん :2001/02/20(火) 15:25
これで上手くいかないなら、俺にはわからん。
ちなみに delete は確保したメモリの中を 0 で埋めてから
開放したり、ポインタを NULL にしない。

char * input_buffer = (char *)new char [1000];
char * output_buffer = (char *)new char [1000];

assert( input_buffer != NULL );
assert( output_buffer != NULL );

strcpy( input_buffer, "ABCDEFG");
strcpy( output_buffer, input_buffer);

delete [] input_buffer;
delete [] output_buffer;

// input_buffer, output_buffer は NULL にはならない。

159 名前:152 :2001/02/20(火) 16:11
説明不足でした、すみません。(^^;)

152の f() のようにインライン関数の中身をヘッダファイルでなく
C++ ファイルに定義すると、見た目すっきりしますよね。
それに外部から呼び出すことはないので private として
このオブジェクトファイルで f() を完結させたいと思っています。
(外部にリンケージしないようにしたいなぁと・・)

もし他のオブジェクトファイルから f() を呼び出そうとしても
private なので呼び出せません。でも実際にアセンブラリストを
見てみるとインライン展開される一方で、外部からもアクセス
できるように .global な関数も生成されていました。
ここからは私の推測なのですが、ヘッダファイルで定義されていない
関数にアクセスしようとすると "Unresolved External" あたりの
エラーをだしても良い(私としてはここはこれが好ましいのですが)
のですが、コンパイラが friend で他の翻訳単位からこの関数を
使用してくることに備えて、.global で外部から呼び出せる名前の
関数を生成しているのかな・・と思いました。


160 名前:↑のつづき :2001/02/20(火) 16:12
ヘッダファイルのクラス宣言で f() を宣言しているのが問題に
なのでヘッダファイルから削って C++ ファイル側に static inline で
定義したのが下のほうの関数です。でも、こうするとクラスの変数に
触れないんですよね。(^^;;;) それでクラスのポインタを受け取って
アクセスするようにしているのですが、アクセスには private やら
問題山積なような。

こういった問題を上手く書く方法があれば・・どうかご教授して
いただきたく質問させていただきました。長くなってごめんなさい。
処理系は gcc 2.95 です。

161 名前:デフォルトの名無しさん :2001/02/20(火) 16:13
こうやって、HageImpl::f()別に作ったらだめでしょうか。
Proxyパターンですな。

もしHage::f()使わなければ、HageImplはインスタンスも
作られないので、なにかとお得。

class Hage{

HageImpl* impl;

Hage(){impl = null;}
virtual ~Hage(){if(impl)delete impl;}

inline void f(){getImpl()->f();}

HageImpl* getImpl(){
if(!impl)impl = new HageImpl();
return impl;
}
}

162 名前:デフォルトの名無しさん :2001/02/20(火) 16:33
>>160
関数定義をヘッダーファイルに直接書いて、

g++ -O

じゃない?


163 名前:106 :2001/02/20(火) 17:16
>>159
補足説明,ありがとうございました。以下,ヘッダとソースファイル
が次のようだとして話を進めます。

--- header "hage.hpp"
class Hage {
public: // <- アクセス制御はコード生成には根本的に影響を与えないのでpublicとしておく
 inline void f();
};
---

--- c++ file #1 "hage.cpp"
inline void Hage::f() { ... };
---

--- c++ file #2 "main.c" (Hage::f()は使わない)
#include "hage.hpp"
int main() {
 Hage h;
 return 0;
}
---

--- c++ file #3 "g.c"
#include "hage.hpp" (Hage::f()を使う)
void g() {
 Hage h; h.f();
}
---

>152の f() のようにインライン関数の中身をヘッダファイルでなく
C++ ファイルに定義すると、見た目すっきりしますよね。

こうすると,hage.cppの翻訳単位ではインラインになる可能性がありますが,
g.cではインライン展開されず,通常の関数コードとしてhage.cppの翻訳単位に
追加で生成されます。g.cの翻訳単位からは,通常の関数呼び出し手続きを
つかって,このhage.cppの翻訳単位に追加生成された関数コードを呼び出す
だけです。

もしかして,「.global な関数も生成されていました。」というのは,この
通常の関数コードじゃありませんか。

いろいろ状況を見ると,ヘッダファイルにインライン関数の定義を書けば
解決するように思えるのですが....。

--- header "hage.hpp"
class Hage {
public: // <- アクセス制御はコード生成には根本的に影響を与えないのでpublicとしておく
 inline void f(){ /* 定義もここで */ }
};
---


164 名前:106=163 :2001/02/20(火) 17:24
う,ちょっと説明がまずかったですね。

>こうすると,hage.cppの翻訳単位ではインラインになる可能性がありますが,
g.cではインライン展開されず,通常の関数コードとしてhage.cppの翻訳単位に
追加で生成されます。g.cの翻訳単位からは,通常の関数呼び出し手続きを
つかって,このhage.cppの翻訳単位に追加生成された関数コードを呼び出す
だけです。


とはつまり,インライン指定した関数は,必ずインライン展開されるとは
かぎらず,インライン展開できないときのために,通常の関数コードも
生成しておく。ということです。つまり,上の例ではmain.cにf()の通常の
関数コードも追加される,ということです。インライン展開が必ずしも
可能でない状況の例としては,インライン関数のポインタを得るよな場合
なんかがありますね。


165 名前:152=159 :2001/02/21(水) 00:40
皆様ご教授いただきありがとうございます。
ソースリストの見やすさと手間を天秤にかけて考えてみました。
クラスの変数を使う場合は、皆様のおっしゃるとおりヘッダファイルに
定義してしまうほうが一番良さそうですね。
そう書くことにしました。

個人的には表に出したくない関数の定義はその翻訳単位で定義できるほうが
美しいと思うんですが・・(他の人が使わない関数なのに、インライン化
するために他の人も見るヘッダファイルにずらっと書くのは分かりづらい
のではないかと・・)

>>161
関数が必要になったときにインスタンスを生成して呼び出すプロクシ型
なんですね。これならメモリを有効に使ったり、必要以上に多くの
オブジェクトが生成されずにすみそうです。
152は生成コードが大きくなってしまっているのでたぶんこの方法では
生成コード自体は小さくならないかもと思うのですが
(間違ってたらごめんなさい)でも、この方法はとても実践的ですね。


166 名前:152 :2001/02/21(水) 00:52
>>162
はい。たぶん それがただしいと思います。
ただインライン関数が数百行になってくるとなんとかしたくて・・。

>>163=164

解説ありがとうございます。

>もしかして,「.global な関数も生成されていました。」というのは,この
通常の関数コードじゃありませんか。

はい、そうです。うーん、、そういえば inline って「できるなら展開する」
なんですよね。とすると friend のため、っていうのは外れですね。
そういえば for ループがあると展開しないコンパイラもあるとか・・。

高速化するために C++ のファイルからヘッダファイルに移して inline にする
と見づらくなっちゃうので、、良し悪しかもしれないですね。

理解が曖昧なので誤解していた部分が、多々あったみたいです。
ご意見で大変勉強になりました。ありがとうございます。

167 名前:保田圭 :2001/02/21(水) 03:18
>>158さんありがとう
まだそのコード試してないんですが、そのコードの意味を教えていただけないですか?
おそらくCharポインタ1000個のArrayとしているんだと思うんですが
そうすると
strcpy( input_buffer, "ABCDEFG");
の部分で何が起きてるんでしょうか?input_buffer[0]にABCDEFGが入るんですか?
それともinput_buffer「0」にA、input_buffer「1」にB。。。となってくれるん
でしょうか?

168 名前:デフォルトの名無しさん :2001/02/21(水) 14:18
データベースを使用するアプリケーションの場合、(に限らないのですが・・・)
ある特定のデータベースを指すパス+ファイル名などの情報は、どういう構造で
保持するのが、定石なのでしょうか。
ヘッダファイルに記述し、データベースにアクセスするクラスに、読み込ませ、
他のクラスからは、データベースにアクセスするクラスを呼ぶとか、いうのが
いいのでしょうか。
定数の定義する位置がいまひとつ分かりません。理屈的にもすっきりする扱い
方とは、どういったものなのでしょうか

169 名前:>168 :2001/02/21(水) 14:53
URL文字列をキーとしたハッシュテーブルで良いんじゃない?
だめかい?

170 名前:デフォルトの名無しさん :2001/02/21(水) 22:29
>>168
何を言っているのかわからないけど、
クラスを設計するときは、
アクセスだとか処理の単位ではなくて
オブジェクト単位で考えたほうがいいよ。
とりあえずUMLでクラス図を書いてみれ。
考えがまとまるぞ。


171 名前:デフォルトの名無しさん :2001/02/21(水) 23:51
>>168
INIファイルの中身みたいな、初期定数をメモリ上にしまっておく場所
っつう意味でいいのかな?
連想配列が一番楽だけど、サポートしてない言語ではmapを使おう
(連想配列と殆ど同じ)。
(キー=値)のセットをvectorみたいなの(ぜんぜん違うけど外見上
はそんなもん)で持ってて、キーで問い合わせると値が帰ってくるって
いうコレクション構造を言語仕様でサポートしてる言語っておおいと思うぞ。

Perlの連想配列、C++のSTLのmap、Javaのjava.util.Mapとか。
(VC++のgetPrivateProfile云々あたりをいちいち呼ぶとかはアホっぽい
ので使わんで欲しい。会社のソースにそう書いてあってゲンナリした…
んなもんデータモデルにキャッシュしろよ。)

そんなのを、OOP言語ならSingletonクラスにしとくとか、
そうでないならしょうがないからグローバルにおいとくとか。

Unix関係でマルチプロセスなら共有メモリっつうのもあるかも。

172 名前:デフォルトの名無しさん :2001/02/22(木) 09:39
>>170
オブジェクト単位で設計するところと、処理単位でまとめるところの
バランスが(言葉は適切でないと思いますが、オブジェクト指向設計と、
3層構造のバランスが)、アプリのミソだと思っているのですが
(まぁ、今までそれだけ改修,改造の多いプロジェクトにかかわってきた
のが問題なのかもしれませんが。)、理解できるように、もっと頑張ってみます。

>>171
ありがとうございます。
C++だと、その配列はどういうところに記述して、各ソースから
参照できるようにするのが、定石か・・・あたりも教えて欲しいのですが。


173 名前:171 :2001/02/22(木) 10:51
>172
STLのmapの使い方はSTL本とかいっぱいあるから
そこで良いよね。

それを置いておくところだけど、
初期データクラスを作る、つうのが一般的でしょ。
mapをクラスのprivate staticのメンバにして、mapへの
問い合わせ関数と、初期化(ファイル読み込んでmapへデータ
を登録する)関数はpublic staticにしておく。

class Property{
private:
static std::map<string,string>* datamap;//最近C++触ってないのでうろ覚え
public:
static void init(string filename){}
static string get(string key){}
}

初期化時
Property::init(なんかファイル名);
使うとき
string value = Property::get(キー文字列);

mapがプログラム内に1個しかいらんのなら、これでええんちゃう?
2個以上の固定数なら、Singletonパターン拡張してヒープに
固定数インスタンス作るよう変更するほうが良いかな。
(やり方はデザインパターン本読んでください。)

174 名前:VC++勉強中 :2001/02/23(金) 09:00
VC++で、MDIアプリを作ろうと思っています。
まだまだ初心者の身ですので、AppWizardを使って
MDIの大枠を作った後、子ウィンドウとして、数種類のフォームを
使いたいので、CFormViewを追加しました。
ただ、追加できただけで、この追加したフォームの表示の仕方が
さっぱり分かりません。
どうすれば、この追加したフォームと、元のフォームを表示することが
できるのでしょうか。
メニューAを選べば1つ目のフォームを、メニューのBが選択されたら
B2つめのフォームが・・・としたいのです。

175 名前:VC++勉強中 :2001/02/23(金) 16:09
うう・・・みなさん、MDIアプリは作られてないのでしょうか・・・
助けて下さい・・・

176 名前:デフォルトの名無しさん :2001/02/23(金) 16:33
>>175
VBやっとけ。
WinAPI覚える前にMFC使うな。

177 名前:名無し :2001/02/23(金) 22:06
>>176
あんたもできねーんだろ(藁
俺もできないから、設計で逃げてるよ

>>175
あきらめなよ

178 名前:デフォルトの名無しさん :2001/02/24(土) 14:33
delete this みたいに、自分自身をdeleteするのってどうなんでしょうか?
なんか気持ち悪い気がするんですが。こういう書き方ってよく使われるんですか?

179 名前:デフォルトの名無しさん :2001/02/24(土) 14:45
>>178
モードレスダイアログを消す時とかのMS推奨方式ですね。
でも、やっぱ気持ち悪い、グェ〜。

180 名前:デフォルトの名無しさん :2001/02/24(土) 14:46
C++じゃないんだが、スレ立てるほどでもないので、、、
#include "stdio.h"
って、
#include <stdio.h>
と何か違うの?

181 名前:デフォルトの名無しさん :2001/02/24(土) 15:04
>>178
Ore* Ore::2ちゃんに書き込む()
 {
  発言を書く;
  return ( 逝っていい ? this : NULL );
 }

として
delete pOre->2ちゃんに書き込む();
とやる手が紹介されていたよ。

>>180
#include でヘルプ検索しろ。
どのディレクトリから stdio.h というファイルを探すか、がちがうのだ。

182 名前:デフォルトの名無しさん :2001/02/24(土) 15:06
ソースを検索するパスが違う。
"" だと作業ディレクトリ、<> だとシステムのディレクトリ。
という理解でだいたい問題ないと思うけど
仕様者のフォロー望ム

183 名前:デフォルトの名無しさん :2001/02/24(土) 15:15
:@

184 名前:( ´_ゝ`) :2001/03/02(金) 01:34
( ´_ゝ`)ageとこう・・・

185 名前:>>174 :2001/03/02(金) 02:23
なんてタイムリーな。自分もちょうどそこで躓いてます。
解決策は見つかりましたか?
その後どうなったか教えてください。

186 名前:デフォルトの名無しさん :2001/03/03(土) 15:55
ANSI C++に完全準拠しているコンパイラってありますか?
C++ Builderが良いところいっているらしいけれど。

187 名前:174 :2001/03/06(火) 23:43
>>185
残念ながら、その後は日常業務が忙しくて解決してません。
(日常業務でPGを開発することが無いもので・・・)
185さんは解決しましたか?
どなたか、アドバイス下さい。よろしくお願いします。

188 名前:デフォルトの名無しさん :2001/03/06(火) 23:56
#pragmaって何に使うんですか?

189 名前:デフォルトの名無しさん :2001/03/07(水) 00:11
>>188
規格で定義されていない、処理系固有の機能を
指定するためだぴょん。

190 名前:デフォルトの名無しさん :2001/03/07(水) 00:13
コンパイラのマニュアル読め>188

191 名前:185 :2001/03/07(水) 00:34
>>174
同じく行き詰まって他の仕事やっちゃってます。
AddDocTemplate()使うと、追加したテンプレートが、
ファイル新規作成時にMFCがデフォルトで出すしょぼいダイアログから
選択できるようになることはなったのですが、
あれを出さずに185さんがおっしゃるようにメニューから
選びたいんですけどね。
どなたかHELP願います。

192 名前:185 :2001/03/07(水) 00:38
185さんって俺のことじゃないか。失礼

193 名前:デフォルトの名無しさん :2001/03/07(水) 00:39
>>186

>C++ コンパイラ:現在のANSI/ISO C++ 標準に準拠した仕様(C++テンプレート、例外処理、多重継承、RTTIをサポート)
http://www.metrowerks.co.jp/Products/Desktop/Pro4.html

「現在の」?

>業界標準に完全準拠した高効率なC++言語クロスコンパイラ
http://www.aicp.co.jp/product/dc.html

「業界」の標準?

>ISO/ANSI C++ Standard に合致しています。
http://www.adac.co.jp/japanese/products/pdf/c++.pdf

「合致」(笑)

>ANSI X3J11/ISO WG21に準拠した業界最高水準のC++コンパイラ
http://www.microsoft.com/japan/developer/vstudio/vs6/pages/page05.htm

「最高水準」ねぇ

>最新のANSI C++によるビジュアル開発
http://www.borland.co.jp/cppbuilder/prodinfo/

「最新」とは曖昧な…


194 名前:デフォルトの名無しさん :2001/03/07(水) 09:46
>>191
C***App::OnNewFileをオーバーライドすれ。

195 名前:186 :2001/03/07(水) 11:15
>193
サンクス。Visual C++はnewしたときに例外を投げないとか、なんとか。
つーわけで完全準拠じゃないみたいですね。

196 名前:191 :2001/03/07(水) 13:52
追加したテンプレートへのポインタをメンバ関数に出しといて
メニューで呼ばれたときのコマンドハンドラで
そのポインタ->OpenDocumentFile(NULL);
ってやればできました。有り難うございます。


197 名前:七市 :2001/03/08(木) 23:47
MDIの事を書かれている人に質問!
新規作成を選んだ時に出てくるダイアログに書かれている名前は
どうしたら変更できるのでしょうか?
っていうか、あそこに出てくる名前ってなに?

198 名前:196 :2001/03/09(金) 00:16
>>197
CDocManager::OnFileNew()見たら
CNewTypeDlgと言う名前でダイアログ出してて、
そいつのシンボルはAFX_IDD_NEWTYPEDLGで、実体は
:\Program Files\Microsoft Visual Studio\VC98\MFC\INCLUDE\l.jpn\AFXRES.RC(173)
に切ってあった。
結局194さんの言う通りオーバーライドするしかないんじゃない?

199 名前:七市 :2001/03/09(金) 09:19
POSITION curTemplatePos = GetFirstDocTemplatePosition();

while(curTemplatePos != NULL)
{
CDocTemplate* curTemplate =
GetNextDocTemplate(curTemplatePos);
CString str;
curTemplate->GetDocString(str, CDocTemplate::docName);
if(str == _T("Hello"))
{
curTemplate->OpenDocumentFile(NULL);
return;
}
}

VCのサンプルを見たら、これでテンプレートに登録したウィンドウを
表示できるようです。

curTemplate->GetDocString(str, CDocTemplate::docName);
if(str == _T("Hello"))

の、CDocTemplate::docNameが、新規作成の時にどのテンプレートを使用するか
選択するダイアログに出てくる名前と等しいような気がします。
とはいっても、このdocNameを変更する方法は判らない。
これがわかれば、何とかなる?

200 名前:七市 :2001/03/09(金) 14:30
AddDocTemplate()の一つ目の引数にあるIDR_MDI_xxxxxxという文字列の
(\nから始まっているので、1つめは無いとして)2つめがdocName、
3つめが新規作成を選択した時にでてくるダイアログに表示される名前(文字列)だね

MSDNのCDocTemplate::GetDocString に書かれてた。
このStringTableに新しく文字列を追加してAddDocTemplate()するときに
使えば、色々なテンプレートに色々な名前を付けれるのでは?

201 名前:198 :2001/03/09(金) 23:33
>>197,199,200
>新規作成を選んだ時に出てくるダイアログに書かれている名前
というのはダイアログ自体のことじゃなくて、選択するテンプレートのタイトル文字列
のことを言ってるんですね?(ちょっと勘違いしてました)

っていうかもう答え出てるんでしょ。


202 名前:七市 :2001/03/10(土) 01:01
>新規作成を選んだ時に出てくるダイアログに書かれている名前
>というのはダイアログ自体のことじゃなくて、選択するテンプレートのタイトル文字列
>のことを言ってるんですね?(ちょっと勘違いしてました)
そうです。
これについてはもう答えが出たけど、
よくよく画面をみると、ウィザードで作ったIDR_XXXXXXTYPEを
使ったテンプレートを開くとメニューバーに「ウィンドウ」とかが追加されるのに
自分で追加したIDR_XXXXTYPEを使ったテンプレートを開くと
メニューバーが変化しないのです
どして!?

203 名前:七市 :2001/03/10(土) 11:34
またしても自己レス
IDR_XXXXTYPEのストリングだけでなく、メニューも必要なのですね
VC++の事なので板違いですね
自粛します

204 名前:デフォルトの名無しさん :2001/03/13(火) 05:04
かなり初心者な質問ですがよろしくお願いします。
LAMEのソースファイルをbolandC++Compiler(無料のやつ)でコンパイルしたいのですが
どうしていいか全く分かりません。
1から教えて下さい。

205 名前:デフォルトの名無しさん :2001/03/13(火) 05:14
C++というかCの質問なのですが、

テキストファイルから文字列読みこむときって
scanf("%s", s);
みたいにやりますよね。このとき配列sには、リターンか
スペースかタブまでの文字列が入ります。そこをなんとかして、
スペースやタブは無視してリターンまで(1行全部)をsに
読みこむ方法ってありますか?


206 名前:デフォルトの名無しさん :2001/03/13(火) 06:17
>205
バイナリで開いて自分で分割する
'\r''\n' の2文字が改行コード。
通常は2文字続いてるが改行コードの違うマシン(UNIX、MAC)
で作られたファイルはどっちか一方のみ。

207 名前:205 :2001/03/13(火) 06:24
>>206

やっぱそれしかないんでしょうか・・・

208 名前:>207 :2001/03/13(火) 07:54
fgets()ではだめか?

209 名前:デフォルトの名無しさん :2001/03/13(火) 12:27
本を見て学習しているのですが
下のコードはdynamic_castの実験を行うものなのですが
#include <iostream>
#include <typeinfo>
using namespace std;

class B
{
virtual void f() {}
};

class D1 : public B
{
void f() {}
};

class D2 : public B
{
void f() {}
};

int main( void )
{
B *p;
D1 ob_1;//今回は使用しません
D2 ob_2;

p = dynamic_cast< D2 *> ( &ob_2 ); //ここが問題のようです
if( p ) cout << "成功しました。\n";
else cout << "失敗しました。\n";

return 0;
}

--------------------構成: test_01 - Win32 Release--------------------
コンパイル中...
test_01.cpp
C:\Windows\デスクトップ\プログラミング\プログラム\test_01.cpp(26) : warning C4541: 'dynamic_cast' が /GR- を使用したポリモーフィック型 'class D2' で使用されています; 動作結果は保証されません。

このような警告が出てきてしまい、実行すると
何らかのメッセージが出てきて止まってしまいます。
何が原因なのでしょう、誰か教えて下さい。

210 名前:ミトコンドリ子 :2001/03/13(火) 12:31
MSDNでC4541を調べてごらんなさい。ちゃんと書いてあるから。


211 名前:209 :2001/03/13(火) 12:41
>>ミトコンドリ子さん
ホントだ書いてありました。
そこに書いてある通りに設定を変えたら
出来るようになりました。
それにしてもC4541って普通解らないですよね
どうやって知ったのですか?
エラーメッセージには書いていないようだし..


212 名前:ミトコンドリ子 :2001/03/13(火) 12:55
あら、アナタの書き込みに「warning C4541」って書いてあるじゃない。
もっと注意力を養ってちょうだい。

213 名前:209 :2001/03/13(火) 14:19
ええさっき気がついたんです。
これは便利です、さっきも有効利用しました。

214 名前:デフォルトの名無しさん :2001/03/13(火) 19:13
ミトコンドリ子さんもしかして
貴方はネカマですか?

215 名前:デフォルトの名無しさん :2001/03/13(火) 20:51
>>205

string buff;
getline(cin, buff, '\n');

C++なら素直にこうしろや。


216 名前:215 :2001/03/13(火) 20:52
cinは適当なストリームに書き換えてくれ。


217 名前:デフォルトの名無しさん :2001/03/19(月) 03:53
えーと、質問させてください。
入力ストリームから一定のバイト数(10Kバイト程度)のデータを読み込んで、
それをstringオブジェクトに格納したいのですが、その場合、

char buf[10000];
ifstream file("hoge.dat");
file.read(buf, sizeof(buf));
string str(buf, sizeof(buf));

のように、いったんchar配列に読み込んでからコピーする方法しか
わかりません。なんか無駄なことをやってるようで気持ち悪いです。
データをstringに直接readするとか、char buf[]をそのまま使って
stringオブジェクトを構築することはできないでしょうか。

218 名前:デフォルトの名無しさん :2001/03/19(月) 13:40
>>217
stringstream

219 名前:217 :2001/03/19(月) 17:23
うう。。すいません。いまちょっと検索したら
stringstreamっていうと数値<=>文字列変換の例しか出てこないんで
よろしければもう少しヒントをくだせえ。。。

220 名前:218 :2001/03/19(月) 21:27
>>219=217
あ、わり、stringstreamかんけーないや。
何勘違いしたんだろう・・・鬱だ・・・。

221 名前:217 :2001/03/20(火) 00:28
>>220
いえいえどーも。レスありがとうございました。

222 名前:218=220 :2001/03/20(火) 04:39
引用厨房モード(プログラミング言語C++ 第3版 p.685)

template<class Ch, class Tr, class A>
basic_istream<Ch, Tr>& operator >> (basic_istream<Ch, Tr>&, basic_string<Ch, Tr, A>&);

template<class Ch, class Tr, class A>
basic_ostream<Ch, Tr>& operator << (basic_istream<Ch, Tr>&, const basic_string<Ch, Tr, A>&);

template<class Ch, class Tr, class A>
basic_istream<Ch, Tr>& getline (basic_istream<Ch, Tr>&, basic_string<Ch, Tr, A>&, Ch eol);

template<class Ch, class Tr, class A>
basic_istream<Ch, Tr>& getline (basic_istream<Ch, Tr>&, basic_string<Ch, Tr, A>&);

<<演算子は、ostreamに文字列を書き込む。>>演算子は、空白文字を終了子とする単語を文字列に読み込み、単語を保持するために必要なサイズに文字列を拡張する。冒頭の空白は読み飛ばされ、末尾の空白文字は文字列の中にはセットされない。

getline()関数は、eolを終了子とする行を文字列に読み込み、行を保持するために必要なサイズに文字列を拡張する。行終了子はストリームから取り除かれるが、文字列の中にはセットされない。stringは入力にあわせて拡張できるので、ストリームの中に終了子を残しておいたり、文字配列用のget()やgetline()のように読み込む文字数を指定したりする必要はない。


223 名前:デフォルトの名無しさん :2001/03/20(火) 10:39
もともとJava使いで、最近C++のSTLに
手を出し始めたのですが、
stlのvector = java.util.Vector
stlのmap = java.util.Hashtable
このような認識でいいのでしょうか?
mapってのが聞きなれないので、
いまは、ラッパークラスで包んで
Hashtableって名前にして使ってます。


224 名前:通りすがり :2001/03/20(火) 11:06
>>223
mapというのは抽象的なデータコンテナを表す名前なのに対して、Hashtableというのはその実装方法を表す名称です。
mapテンプレートクラスは二分木で実装されているようです。一般的にはハッシュ表の方が二分木より高速に検索できますが、それぞれの型ごとにハッシュ関数を用意する必要があります。mapテンプレートクラスでは <演算子さえ定義されていればどんな型でも使えますし、仮に<演算子がなくてもハッシュ関数より簡単なless関数だけ用意してやれば済みます。


225 名前:デフォルトの名無しさん :2001/03/20(火) 11:27
>>224
そうそう。
C++のmapのほうが概念的にスマートだよね。


226 名前:デフォルトの名無しさん :2001/03/20(火) 11:55
>225
インタフェースとしてはテンプレートがあるぶん良さげだけれど、
(mapの)実装まで決まってるのはやーねー。
インタフェースと実装が分離されているほうがスマートじゃない?

227 名前:デフォルトの名無しさん :2001/03/20(火) 11:56
>223
つーか、MapはJavaにあるぞ。
インタフェースだけれど。

228 名前:223 :2001/03/20(火) 12:27
>>224さん
詳しい説明ありがとうございました。
大体理解できました。
STLのコンテナの概念がわかってないことが
バレバレで恥ずかしいです。

JavaのHashtableが、ハッシュ関数(Objectクラスの
hashCode)をオーバーライトしたものにしか有効で
無いのに比べ。
mapは、どんな型にでも適応できるということですね。
<演算子というのがいままで使ったことが無いのですが、
小なり演算子ですよね…
==演算子で無いのには何か理由が?
operator <()にてこれを再定義しておけば、良いと

>>227さん
開発をずっと1.1.6ベースでやっていたのでMapって
使ったことが無かったんですよ。
(1.2からサポートでしたよね?)


229 名前:223 :2001/03/20(火) 12:32
自己レスですが、
よく考えたら、2分木だから <演算子を定義しなければ
ならないってことですかー
アホだ…<自分


230 名前:デフォルトの名無しさん :2001/03/20(火) 13:14
>>228
そかそか。collection API は Java 2 からだからね。
でも、一応は collection API は単体で配布してる。

231 名前:デフォルトの名無しさん :2001/03/24(土) 05:36
C++初めて半年以上になるけどいまだに ostringstream のバッファのクリアの仕方知らない・・・
string::eraseに値するようなメソッドって無いっすか?

232 名前:デフォルトの名無しさん :2001/03/24(土) 18:54
みんなストリーム入出力って使ってるんだろうか・・・。

>>231
stringstream strstr;
strstr.str("");

233 名前:デフォルトの名無しさん :2001/04/11(水) 10:34
newをオーバーロードして、メモリが確保された場所を
デバッグ表示させたいのですがいい方法はないでしょうか?

// こんな感じにオーバーロード出来ると嬉しい。が、無理だし。
void *operator new(size_t size, char *file, int line)
{
printf("%s:%d: %d byte allocate\n", file, line, size)
return malloc(size);
}

234 名前:デフォルトの名無しさん :2001/04/11(水) 10:46
>>228
JavaのMapの実装はHashtable方式だけじゃないぞ。
SortedMapの実装でTreeMap(2分木Map)もコアにあるぞ。
Map継承して自分で実装かくのも良いかもね。B*ツリーMapとか。

235 名前:デフォルトの名無しさん :2001/04/11(水) 12:26
ところで、クラス名の頭には「C」ってつけるけど、構造体にはどうしてますか?


236 名前:デフォルトの名無しさん :2001/04/11(水) 12:54
クラス名の頭に「C」なんて付けるか?

237 名前:デフォルトの名無しさん :2001/04/11(水) 13:12
頭にCついているのはMFCのクラスじゃない?
僕はつけたくないけれど。

238 名前:デフォルトの名無しさん :2001/04/11(水) 14:00
>>235
僕は、
class CMusic
とか
typedef TMouse
とかしてます。



239 名前:デフォルトの那梨さん :2001/04/11(水) 14:54
>>232
結構未サポートなんだ。それ欲しいんだが。


240 名前:デフォルトの名無しさん :2001/04/11(水) 22:19
インラン関数って何?

241 名前:デフォルトの名無しさん :2001/04/11(水) 22:24
sexy()

242 名前:デフォルトの名無しさん :2001/04/11(水) 22:32
>>235
MFC汚染済みか・・・哀れな。

>>238
>typedef TMouse
パスカル人が見たら、こんらんして仲間を攻撃しだすかもな・・。

つーか、そもそもクラスと構造体でプレフィクス分ける意味あんのか?

243 名前:シロート :2001/04/11(水) 22:36
クラス名の頭にC、メンバ変数の頭にm_て
付けなさいって林せんせえが言ってたんですが。

これは違うのですか?

244 名前:デフォルトの名無しさん :2001/04/11(水) 22:43
Windowsで普通のウインドウやエディットコントロール等Window系
の物をいじる基底クラスなんか作ってます。

そのクラスの中のメンバ変数でHWNDをもたせて
SetWindowTextとかをメンバ関数内で呼び出したりしています。
ようはAPIにかぶせたりしているだけです。
主にこのクラスから派生させて各種コントロール用のクラスとかを
作ろうと思っているのですが・・・

このような(に限った話ではないんですが)基底クラスのメンバ関数って
全部virtualにしちゃまずいんでしょうか?

「virtualにしない理由」があんまり思いつかないんで
全部virtualにしているのですが。
常套手段はどうなんでしょうか?

どのようなときに困るか等も一言教えていただけると助かります。

245 名前:デフォルトの名無しさん :2001/04/11(水) 22:51
>>244

virtualメソッドの機能理解してればおのずと分かるだろ。
多態されると困るメソッドはvirtualにはせんわな。
あと、なんでもかんでもvirtualにすると、VMTが巨大化して重くなる(藁

なんつったりしてな。別に全部virtualでいいと思うよ。

246 名前:デフォルトの名無しさん :2001/04/11(水) 22:56
>>244
Effective C++が詳しいかと。
「継承した非仮想関数を再定義してはならない」
とあります。理由も書いてあるんで読んでみては。

逆にいえば、派生クラスで再定義して欲しくないものは
非仮想関数にする、って感じかな。

あとは実行時の効率の問題。

247 名前:デフォルトの名無しさん :2001/04/11(水) 23:09
>VMTが巨大化して重くなる(藁

別にインスタンス毎にVMTが作られるわけじゃないでしょ
VMTへのポインタを持つだけだからサイズは関係ないんじゃ?

248 名前:デフォルトの名無しさん :2001/04/11(水) 23:27
>>233
なんで無理なの?
そんな感じでいいんじゃ?

249 名前:デフォルトの名無しさん :2001/04/11(水) 23:28
C++で構造体が"デフォルトパブリッククラス"になっていると
聞いたのですが、これって意味のあること?
クラス使うならクラスでいいじゃん。
おれにはよく分からん。

250 名前:デフォルトの名無しさん :2001/04/12(木) 00:18
>>249
だからクラスなんだよ。
で、デフォルトパブリックにすることで、セマンティクス上では
struct と同じになってる。もう構造体は使わないってこと。


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