C++相談室 Part4

このエントリーをはてなブックマークに追加
1デフォルトの名無しさん
v(^・^)v

Boost C++ Libraries
http://www.boost.org/
C++ Final Draft International Standard
http://www.kuzbass.ru/docs/isocpp/
GotW.ca Home Page
http://www.gotw.ca/
STLport
http://www.stlport.org/

C++相談室
http://piza.2ch.net/tech/kako/980/980175292.html
C++相談室 Part3
http://pc.2ch.net/test/read.cgi/tech/1003832761/l50
終了。
3デフォルトの名無しさん:01/12/23 11:00
なんでやねん (笑
v(^・^)v
v(^・^)v
6デフォルトの名無しさん:01/12/23 13:43
v(^・^)v
v(^・^)v
v(^・^)v 
9デフォルトの名無しさん:01/12/23 14:55
v(^・^)v
いい加減にしてくれ
(More )?(Effective|Exceptional) C++ は結構話題にのぼるけど,
(Essential|Efficient) C++ ってどーよ?
書評キボンヌ
>>11
推薦図書スレへ行け
13 v(^・^)v :01/12/23 16:28
>>10-11
v(^・^)v
v(^・^)v
1511:01/12/23 18:01
>>12
あそこはすぐ荒れるから嫌.
C++ ネタならこっちでいーじゃんという話に過去スレでなったはずだし.
結局、多重継承のあいまいさを解消する手段として
どれが一般的&エレガント?

class Base1 { void foo() {...} };
class Base2 { void foo() {...} };

class Hoge : public Base1, public Base2{
public:
 void bar(){Base1::foo();} //bar()の名はfoo()でいい
 using Base1::foo;
};
int main(){
 Hoge hoge;
 hoge.bar();  //1
 hoge.Base1::foo();  //2
 hoge.foo();  //3
 return 0;
}
17デフォルトの名無しさん:01/12/23 19:39
>>11
図書スレへ行け宣言はビギナーの参照なのでほうっておけ。
あとv(^・^)vに食いつくのも。わらい
>(Essential|Efficient) C++ ってどーよ?
私もちょっぴり気になっています。パラパラ見た感じは
Essentialは普通そうだけどもEfficientは面白そうだ。
結局このシリーズは全部よんどけってことになるんだろうか。
このシリーズは購入に悩むにはそれほど高くないし
なんか騙されている気もする。
18デフォルトの名無しさん:01/12/23 19:57
>>16
そんなもの答えがあるわけがない。
void bar(){Base1::foo();} ならきっとfooになにか
別名を付ける特別の操作を意識しているのだろう。
using Base1::foo;ならこちらの関数こそHogeに相応しい
ということなのだろう。
hoge.Base1::foo();なら何も決定できなかったということだ。
だがそれでも答えはきっとこうだ。
君のクライアントは君と同様スコープ解決演算子が大好きだ。
1911:01/12/23 21:26
>17
>このシリーズは購入に悩むにはそれほど高くないし
マヂで!?3600円 はヲレにとっては悩む程高いんだよね.
いや,このテの本にしてはまぁ普通なのは分かるんだけど,金額の絶対値が
ヲレにとって高い(苦笑).

んで,
> なんか騙されている気もする。
の意味が良く分からないのでマジレスキボンヌ.
一応購入を検討中なんで・・・
void Hoge::foo()
{
 Base1::foo();
 Base2::foo();
}
21デフォルトの名無しさん:01/12/23 22:58
オブジェクト指向初心者なのですが、教えて下さい。
スレッドAで、あるクラスオブジェクトを作成したとして
スレッドBからそのオブジェクトのメンバ関数を呼び出したとき
そのメンバ関数はどっちのスレッドで実行されるのでしょうか?

なんかもー・・・・脳味噌バーン
>>21
「どっち」って、何と何??
スレッドBから、そのあるクラスオブジェクトのメンバ関数を
どうやって呼ぶ場合のことをいっている?
24デフォルトの名無しさん:01/12/23 23:44
>>21
オブジェクト指向関係ねぇだろ。マルチスレッドの理解が足りない。
まさかJavaの話じゃないだろね?
2521:01/12/23 23:47
あ、ボケてました・・・・基本的に呼び出せないですよね
この質問は無しでよろ〜(;´Д`)
でも、おれもオブジェクト指向を始めたばっかりの時って、各オブジェクトが
それぞれ独立したスレッドで走っていて、いろいろメッセージのやりとり
しながら動いている、すげープログラム、ってな妄想があったよ。
もう20年近くも昔のことだが。
(あのころはスレッドなんて言葉、無かったかな?)
>>26
そういうOSってあっても良さそうだよね
詳しくないけどMacOS XとかのMachなOSってそういう事なの?
>>26
それはきっとCSPだ。
29デフォルトの名無しさん:01/12/24 00:27

バイナリのバイト列をできるだけ標準に近い形で、
しかも簡単に扱う一般な方法って何でしょうか?

使い方を限定すれば、
typedef std::basic_string<unsigned char> bytes;
でもいいんだけど、

バイナリなので、
struct char_traits<E>::length( const E *x );
が呼ばれたとき困るしね。

なんかいい方法ってないんでしょうか?
30デフォルトの名無しさん:01/12/24 00:54
>>29
vector<unsigned char>
31デフォルトの名無しさん:01/12/24 01:12
vectorは遅すぎんけ?
32デフォルトの名無しさん:01/12/24 01:15
ならvalarrayは?
>>31
適度にreserve呼び出すかアロケータ書くかすればstringに比べて
遅いなんてこともないだろ。

バイト列なんか標準も何も用途に応じて適当なクラス作ればいいと
個人的には思うんだがね。プラットフォームに依存した物にもなり
やすいし。
34質問:01/12/24 01:45
STLのstringって、シフトJISみたいなマルチバイト文字列を扱えます?
35デフォルトの名無しさん:01/12/24 01:54
>>34
basic_string<wchar_t>
3634:01/12/24 02:09
>>35
wstringじゃなくて、1バイトコードと2バイトコードの混在する文字列を扱えるかどうかが知りたいのですが・・・。
というか、多分扱えないとは思うので、stringでマルチバイト文字列を扱うとき
みなさんはどうやっているのか聞きたいのです。

stringの内容を書き換えない場合は、operator const char*()があるから
そのままCライブラリに投げればいいとして、
stringの内容を書き換える場合、たとえば部分文字列の置き換えなんかはどうしたら良いのでしょうか?
37デフォルトの名無しさん:01/12/24 02:28
>>36
std::stringもマルチバイト文字は扱える。
ただし、文字単位でなくバイト単位の操作になる。
(size()とかはバイト数を返す)
>>36
そこが文字の区切りかどうか判別するアルゴリズムかけば? その場合
常に文字列先頭から走査することになって面倒だけど。

自分はどうしているかというと、UTF-16しか使わないので問題ない。
39デフォルトの名無しさん:01/12/24 02:33
>>36
std::stringをメンバに持つmulti-byte stringクラスを作ってそれを使うようにしてる。
std::stringのメンバをpublicにしとけば、それに対するアクセスもできるしな。
で、そのクラスもchar_traitsみたいな、multi-byte string用の操作情報を与えれるようにすれば
複数の文字コードにも対応できるしな。

折れはそうしてる。
40デフォルトの名無しさん:01/12/24 02:40
> 自分はどうしているかというと、UTF-16しか使わないので問題ない。
うらやましい。。
UTF-16だと、JISとかに変換する場合に一意な変換ができんから使えんことが多い。
41デフォルトの名無しさん:01/12/24 02:44
> 自分はどうしているかというと、UTF-16しか使わないので問題ない。
そうか?
結局サロゲートの処理が必要になるから、
マルチバイトの処理と変わらんだろ。
42デフォルトの名無しさん:01/12/24 02:57
まともな相談なんだが、
ソース中の関数を列挙しようと思う。
...(){}..のパターンを捕まえてひとつに数えるんだが、
判定として()と{}の間が空白であるという条件を使いたい。
そうしないと変なEnum{}とかa={{},{}};とか関数で
ないのが引っかかってしまう。

ってことで、空白の種類なんだけど、スペースとタブと改行、
それ以外にコンパイラが空白と認識する文字ってあるのかな。
それと、スペースは0x20,改行はテキスト形式で\r\n,タブがわからない・・・
です。
4334:01/12/24 03:04
レスどうもです。
やはり有りものでは無理で、
>>36 の方がおっしゃるように、
独自クラスを派生させるのが一番確実のようですね。
>>42
コメントも空白のはず。
タブは '\t'。
テキストしかツールに渡さないのなら、0x20 以下は一律に空白と見なしても問題無いと思う。
45デフォルトの名無しさん:01/12/24 03:32
>>42
関数を列挙するツールを使った方がはやいぞ。
freewareでその辺にある。
>>42
そういうのって正規表現ライブラリとか使った方が楽ちんじゃない?
関数名列挙なら /^\w+.*\)$/ だけでも十分抽出できるし。
>>42
isspace でいいんじゃないの
48デフォルトの名無しさん:01/12/24 09:40
>>19
元々web連載をまとめたものなんだから
まとめて一万くらいで十分と思うんだが5,6冊に分けていて姑息だと。
4919:01/12/24 11:35
>48
> 元々web連載をまとめたもの
えっ!?そーなんだ.知らなかった・・・
でもまぁそーゆー事なら僕にとっては日本語訳してあるだけでも価値があるからいいや.
お答えサンクスコ
50初心者:01/12/24 12:10
日本語処理がわかりません…。
例えばフルパスからファイル名とか取るとき、
『\』を検索して切り取ると最後のファイル名に
『ソ』とかあるとき変なところで切れてしまします。
VC++のヘルプを見てもいまいちよくわかりません…。
Windowsでファイルパス扱うなら素直に_splitpath()。
一般論だと、SJISの場合文字列先頭からみていくしかない。
isleadbyte()参照。
オススメは一旦Unicodeに変換。サロゲートペアなんざ無視。
最悪を絵に描いたような質問法ですね。
あと「一週間位まえから必死で頑張ってるんです!!」
とかあれば100点だと思います :-)
53初心者:01/12/24 12:27
どうもありがとうございます。
54デフォルトの名無しさん:01/12/24 12:28
オススメは一旦UTF-8に変換。サロゲートペアなんざない!
55初心者:01/12/24 12:29
>>52
すみません…気をつけます。
56デフォルトの名無しさん:01/12/24 12:35
Efficient C++は、ボトルネックになっている所をチューンアップする必要がある
プログラマは参考になると思うよ。ライブラリ開発者とか。

アホアホプログラマに読ませると害が大きいと思うな。
大局に影響のない不必要チュウニング馬鹿はどこにでも出没するので。
>>51
UNICODE というか wchar_t にしてしまえば良いと思うが。

wchar_t はあくまでワイド文字 1 文字であって、サロゲートペアなぞ気にしなくていいはず。そもそも wchar_t
の符号化方式が UTF-8, UTF-16 あるいは ISO 2022 ベースの何かとかも規定されていないし、Win32 だと
wchar_t はサロゲートペアなしのサブセット版 UTF-16 (16 ビット固定長) じゃない?
>>57
VC++でWindows前提ならMultiByteToWideChar/WideCharToMultiByte
使ことになるだろうから、まぁUnicodeだろうと。ってこのAPI、変換が怪しいし、
サロゲートペアに対応してたかどうか知らないけど。
いずれにせよstring<->wstring変換関数は適当に自前で用意だろうな。
内部的にどういうコード使っててもそれを外部にださなきゃいいんだし。
>>57 エンコーディングと、文字セットは分けて議論してくれい
6034:01/12/25 01:36
めりくり(´Д`)

マルチバイト文字列操作に対応するように、std::stringを拡張しようと考え、
委譲ではなく実装継承にしたかったので
class mbstring : public std::string {}; // 試しに継承してみる
としてみました。
が、"operator=()"が定義されてないとかコンパイラに怒られてしまいました。
サンタさん助けてください。
>サンタさん助けてください。
彼らは今、納期に間に合わせるべく死に物狂いで奔走しているところです。
無茶言わないように。
62デフォルトの名無しさん:01/12/25 01:49
サロゲートペアなんて必要なんだろうか。
文字オタのために頻度1/1,000,000の文字をサロゲートにしてまで
実装する価値があるのだろうか。
それと中国。文字が多すぎるんだすこしは我慢しやがれっつーの。
というわけで、私が自前で作ったユニコードライブラリは
サロゲートをボツにしました。
個人的にはサロゲートなんぞ提案した阿呆には首括って貰いたい。
6434:01/12/25 03:33
>>61
サンタさん、ごめんなさい。
きっと恥ずかしい勘違いでエラーを出してると思うので、
一人で勉強することにします。(・∀・)
65デフォルトの名無しさん:01/12/25 20:55
g++ で wprintf を使っている人はいませんか。

#include <stdio.h>
#include <wchar.h>

int main()
{
wprintf(L"foo");
}

をコンパイルすると、wprintf が undefined になっちゃうんですが。

gcc だと、コンパイルはできるけど、リンクでエラーになります。
何かライブラリを陽に指定しないといけないんだろうか。
66デフォルトの名無しさん:01/12/25 21:56
厨房質問ですみません.
wchar とか,wprintf とかって皆さん何で勉強したんですか?
僕の持ってる本にはどれにも載っていなくって,このスレで初めて存在自体を
知りました.一応 web を検索して
http://www.linux.or.jp/JF/JFdocs/Unicode-HOWTO-6.html
こんなのとか見つけたんですが,正直サパーリ分かりませぬ.
どなたか良書 or 良いサイトがあったらご紹介して頂けませんでしょうか.
6765:01/12/25 22:34
>>66
あう。この HOWTO に、見事に

> GNU glibc-2.0.x, glibc-2.1.x
> ・wcs/mbs 関数がありますが、fgetwc/fputwc/wprintf はありません

と書いてありますな。というわけで私の疑問は解決。

で、書籍 or サイトについては私も知りたいです。国際化にかんして
私が持っている本だと、

・「C++ 標準ライブラリ チュートリアル&リファレンス」(ASCII) の
「第14章 国際化」
・「Unicode 標準入門」(翔泳社)

くらいです。C のライブラリということだと、

・「標準C言語辞典」(ピアソン)

という本があるようです。
typedef int32_t ucs4char;
typedef basic_string<ucs4char> ucs4string;
って、どう。サロゲート気にしなくて良いよ。
自分のUnicode関係のライブラリは、
文字コード変換用のやつ以外、全部これ。
69デフォルトの名無しさん:01/12/25 23:31
ucs4ならサロゲートいらないけどさ…
4バイト食っちゃうのがなぁ。うーん。
あとUTF8<->UCS4を行き来しなきゃなんないよねー。
初めの理想を徹してUCS2で我慢できないもんなのかなぁ…。
すべてはやたら多い文字の国が悪いのだ…。
UCS2を捨てるなら3バイトでcxx(c=言語地域,xx=区となんとか)に
すると体系として割とすっきりする。拡張もできるし。
unix系のどこかのグループが作業していたような。
必要なタグは贅沢を言えばキリがないんだけど。
71無名λ式:01/12/25 23:46
>>67
wcs/mbsだったら、JIS規格表が出てるから買いなよ。
JISは追加された所だけ別の規格表にしたから安いぞ。
日本規格協会から買える。http://www.jsa.or.jp/
http://www.jsa.or.jp/catalog/catalog09.asp
確かこれ。http://www.jsa.or.jp/catalog/catalog_bumon_a.asp?fn=D007927.HTML

正直、この辺はいい加減な本が多いから、規格読んだ方が早い。
>>69
日本がそんなに悪いのか!
日本だけじゃないけどね(w >>72
>>72
>>73
日本は悪くないよ。
>>71
日本規格協会も C の規格書を出していたんだ。さすがに最新ISOに
則ったやつはまだないみたいだけど、現行のやつでも持っててそんはないね。
おすすめにしたがって、買っておきます。
76重大なエラー名無しさん:01/12/26 02:19
MUTEXロックについて教えて下さい。

ある共用データを書き込む処理をする、スレッドAと、
共用データを読むだけの処理をするスレッドBがあるとします。
スレッドAでは共用データを書き込む際、MUTEXロックをかけておきます。
スレッドBでは共用データを読むだけなので、MUTEXロックは必要ないのでしょうか?
スレッドBでロックが必要な場合、待ち状態になると思うのですが、待たないよう
にする方法はありますか?
rwlockを使う。
>>76
読むだけといっても、書いている最中のわけのわからないデータに
アクセスしてしまうとおかしくなるということがあると思うけど。
特に、アクセス先が複雑なデータ構造なら。
79重大なエラー名無しさん:01/12/26 02:58
>>78
そうなんですよね!
つまり、書き込んでいる最中に、ロックもかけないで読むのはいけないということですね。
(読むだけといっても、マシンコードのレベルでは複数行だったりするらしいので。)
で、そこで問題なんですが、普通にロックをかけて読むのであれば、共用データ書き込み中
の場合は、待ち状態(タイムロス)になってしまいます。
では、タイムロス無しに共用データを読むにはどうすればいいんでしょうか?
5秒後に実行するようにプログラムしたいのですができますか?

例えば、入力した文字の画数を調べるプログラムで時間が経つと
かってに、結果に移るようにしたいのです。
コントロール+Dしなくていいように
selectで待つとか、alarmでタイムアウトを検出するとか。
>>79
77 も書いてるが reader/write lock を使う。簡単化して説明すると

読める条件
 writer がいないこと
 (reader は何人いても OK)

書き込める条件
 write がいないこと
 reader がいないこと

でロックをかける。google で検索すれば、山のように説明が出てくると思われ。
>82
>79は、書き込み中にロックしてしまうのを避けたいみたいだが。
確かに、ある種の書き込み方式(たとえば、リストに足していくだけとか)なら、
十分な検討を行い、読み込みをロックフリーにできる場合もあるかもしれない。
たとえば、書き込み前に現在のリスト最終位置を保存しておくとか。
write : Lock(); @last = @list.size(); @list.push( func() ); unLock()
read : last = @last; @list.each( to last ){|i|; process i }
個人的には、ハマり道なので、あまりお勧めできない。
>>83
読み込みの待ち時間を最小にしたいなら

1. 書き込みの単位を小さくする。たとえばキューなら一気にデータ挿入を行わず、1 つキューに入れる
 操作をしたら、すぐにロックを離して、読み込み要求があるか調べる。

2. データをコピーして二つ用意しておき、書き込みはコピー側に対して行う。書込み操作が完了したら、
 以後のリーダーは新データを参照するように挿げ替え(古いデータは参照しているリーダーがいなく
 なるまで残しておいて、後でガベージコレクションかける)

あたりじゃないのか。
>>84
2.でもコピーと挿げ替えのときにロックが必要だから、
やっぱりまったく無しというのは無理だな。
86デフォルトの名無しさん:01/12/26 04:58
2は参照カウンタをクリティカルセクションで保護する必要があるな(笑)
87無名λ式:01/12/26 09:23
>>75
挙げたのはwcs/mbsだけしか載ってないから注意してね。
書籍は、共立から出ていた「国際化プログラミングハンドブック」(たしかこんなタイトル)、
どこだかわすれたけど「マルチリンガル〜」がいいと思う。(UNIX only)

>>76 マルチスレッドプログラミングスレの方が適当じゃないかな?
>>84
おまえのプログラム原因不明のバグとか多いだろ。
>>88
未解決のバグは全部原因不明
原因は明らかなんだが仕様上直せないバグと、どっちがいい?
>>85
データ構造によるけど、たぶんロック無しはきついだろうなぁ。x86 ならポインタ一つだけとか
整数一つだけの操作なら割り込みが入らないけど、それで済むような簡単なデータ構造なら
そもそも問題になってないだろうし(SMP だとロックプリフィックスをつけてバスをロックするの
は必要か)。

>>88
たしかに FreeBSD 5.0-CURRENT には、まだ怪しい挙動する部分あるな。
>>91
一般的にいえば、sig_atomic_t以下のサイズの読み込み以外は必ずロックが必要。
93デフォルトの名無しさん:01/12/29 01:00
構造体でもクラスでもいいです。
クラスの1番最初のメンバに関数ポインタ(void func(CGOBJ *obj)系のポインタ)
がある様々なクラスを作り(つまり、ヘッダみたいなのを統一して作るの)、
クラス(どのクラスかは不明。)の、ポインタだけわかる状態で
その、関数ポインタに飛ぶにはどういう風にすればいいですか?
関数型キャストしようとすると、ANSI Cじゃ出来ないわよ。
って言われます。
C++このようなこと出来そうな機能ってありますか?
それとも、アセンブラやるしかないのでしょうか?
何をどうしたいのかがいまいち不明だが、以下のような感じ?

class Foo {
private:
 void (*func)(CGOBJ *obj);

public:
 void operator()(CGOBJ *obj) {
  (*func)( obj );
 }
};

int main()
{
 Foo *foo = new Foo;

 // foo->func を初期化する処理をして

CGOBJ *obj = new CGOBJ;

 (*foo)( obj );
}
1番最初のメンバ名を統一する。
96デフォルトの名無しさん:01/12/29 02:16
>>93
#include <iostream>
typedef void (*func)(int obj);
void test(int obj) {cout << obj << endl;}
class Foo {public: func test;};
int main() {
Foo *foo = new Foo;
foo->test = test;
//(reinterpret_cast<func>(foo))(0);
(*(reinterpret_cast<func *>(foo)))(0);
return 0;
}

g++では通ったぞ
コメントアウトしてる方の行はだめだったけど
>>93
> 関数型キャストしようとすると、ANSI Cじゃ出来ないわよ。
> って言われます。
Cなのか
> C++このようなこと出来そうな機能ってありますか?
C++なのか
はっきりしる。

あと処理系とエラーメッセージも書け。
98デフォルトの名無しさん:01/12/29 02:17
>>94-95 は読解力 0
9995:01/12/29 02:22
>>98

お前はどう読解したんだよ?
100ロックしないで〜:01/12/29 04:49
データがでかくてもダブルバッファにして、データへのポインタをかえればいいじゃん。
>>84の話か? >>85-86は読んだか?
102デフォルトの名無しさん:01/12/29 06:07
つか>>95はネタだとおもったんだが…
関数へのポインタをメンバに持つ構造体を1つ定義して、
それへのポインタにキャストすればええんでないか?
103100>101:01/12/29 06:11
読んだからダブルバッファとポインタって言ってるんじゃん。
>>102
構造体を定義せずとも、関数へのポインタへのポインタにキャストすりゃえー
んでは、っつーのが>>92では。
105デフォルトの名無しさん:01/12/29 06:35
>>104
それがANSI Cじゃできないからっていうんでは?
106デフォルトの名無しさん:01/12/29 06:37
>>76はスレッドの同期の問題が片付かないと結論でなさそうだけど、ど?
>>105
できるはずだが、>>93がちゃんと情報を出さんので、
ほんとにそういう問題なのかわからん。
10893:01/12/29 12:46
どうも。いろいろ意見ありがとうございます。
>>102さんの言うとおり、ヘッダを構造体にしたらいけました。
やろうとしたことは、CGOBJを中心にCOMみたいなことして
いろんな機能を使用、追加できるクラスを作ろうと思ったのです(DirectShowに近い)。
3Dとかになると、同じ座標使っても、
さまざまなポリゴン表示(トーンとかキューブとか)や
ビルボード等、いろいろな表示方法があったり、
他にも、いろんなあたり判定、ライティング座標、etc…
それを初期化の時に、設定しやすく(素材の共有もできる)、そして
使用方法はCGOBJのメンバを呼ぶだけ。
という。そんなものを作ろうとしているのです。
ソースは94さんみたいなものです。で、
(void *)キャストしたmat(94のソースで言うとFoo)を
(void *(CGOBJ))mat(this);//
D:\[Development]\testCOBJ\main.cpp(35) : error C2066: 関数型へのキャストは不正です。
MSDNで見ると
コンパイラ エラー C2066
関数型へのキャストは不正です。
オブジェクトが関数型にキャストされましたが、このキャストは許されていません。
ANSI C では、関数へのポインタとデータへのポインタの間でキャストを行うことは許されていません。

あばば。
今見ると、キャスト方法間違ってたかも。
でも、ヘッダを構造体にすることにより、わかりやすくなったので、
それがいいです。
長文かつ、読みにくい文章ですいません。
いろいろありがとうございました。
109デフォルトの名無しさん:01/12/29 12:58
while (cin.get(c)) {
if (c >= '0' && c <= '9')
cnt[c - '0']++;
}

for (int i = 0; i < 10; i++)
cout << i << "の出現回数:" << cnt[i] << '\n';

 cout << i << "の出現回数:" << cnt[i] << '\n';
のcnt[i] の部分はfor文とwhile文のどちらの結果が入ってるんでしょうか?
                    
>>108
> (void *)キャストしたmat(94のソースで言うとFoo)を
>>96か?
> (void *(CGOBJ))mat(this);//
(*(void (**)(CGOBJ))&mat)(this);
直接キャストするならこうだろ。たぶん。
inline のメンバ関数定義して、それ経由で func を呼び出せばそれで
終わりじゃないの? なんでわざわざキャストする必要がある?
それともみんなネタ?
>>109
cout の << 演算子は、引数を書き換えたりしないよ。
>>111
inlineだとクラスが分かってないと使えないじゃん。
>>93はgenericな関数を作りたいんだろ。
>>113
111はネタだから
>>113
>>93 は、
> クラスの1番最初のメンバに関数ポインタ(void func(CGOBJ *obj)系のポインタ)
> がある様々なクラスを作り(つまり、ヘッダみたいなのを統一して作るの)、

と言っているので、「ヘッダみたいなの」を基底クラスとして、そこから派生した
クラスを扱うのかと思った。

また、generic な扱いをするのに template を使えば、あらかじめクラスが
分かっている必要はない。関数オブジェクトでやるのが一番スマートかな。
>>108
仮想関数じゃ、どのへんがダメなん?
>>115
> と言っているので、「ヘッダみたいなの」を基底クラスとして、そこから派生した
> クラスを扱うのかと思った。
C++で普通に考えたらそうなんだが。

> また、generic な扱いをするのに template を使えば、あらかじめクラスが
> 分かっている必要はない。関数オブジェクトでやるのが一番スマートかな。
関数自体は一つにしたいということなんでは。
あるいは実行時まで実際のクラスは分からないとか。
>>116
あえて当り前の手を封じてこそのネタ。
119名無しさん@Vim%Chalice:01/12/30 00:29
120116:01/12/30 09:19
・・・ネタだったの? ごみん。
121デフォルトの名無しさん:01/12/30 18:35
while (cin.get(c)) {
switch (c) {
case '0'; cnt[0]++; break;
case '0'; cnt[0]++; break;
}
}

for (i=o; i<10; i++)
cout << i << "の出現回数:" << cnt[i] <<'\n';←この行のcnt[i]は
switch文のカウントから、きているものなのでしょうか?

122121訂正:01/12/30 18:37
case '0'; cnt[0]++; break;
case '0'; cnt[0]++; break;
    ↓
case '0'; cnt[0]++; break;
case '1'; cnt[0]++; break;
>この行のcnt[i]は switch文のカウントから、きているものなのでしょうか?
だからもーちっとマシな日本語使えって.
何が言いたいのか分からんぞ.
だいたい
i=o
の時点でヲィヲィ・・・
>>121
>この行のcnt[i]は switch文のカウントから、きているものなのでしょうか?
cntはどんなクラスの、オブジェクトなのでしょうか?
よく分からんけど cnt[i]とは*(cnt + i)のことだすよ。
operator [](int i)の立場はどうなるのでしょう?
127121訂正:01/12/31 05:49
>>123-125
/*
入力に出現する数字をカウントする
*/

#include <iostream.h>

int main(void)
{
char c;
int cnt[10] = {0}; // 配列cntの全要素を0で初期化

while (cin.get(c)) {
if (c >= '0' && c <= '9')
cnt[c - '0']++;
}

for (int i = 0; i < 10; i++)
cout << i << "の出現回数:" << cnt[i] << '\n';

return (0);
}

for文のcnt[i]がどこから来てるのか知りたいんです。
>>127
aとかbとか入れた場合は?
128 すまそ、良く見てなかった
>>127
人をからかってるのか?
131123:01/12/31 10:35
>>127
だーかーらー
> for文のcnt[i]がどこから来てるのか知りたいんです。
この一文が意味不明なの.

せめてオマエの考えてる
「こーなの?それともこーなの?どっち?」
とかって質問の仕方をしてみろ.
132121訂正:01/12/31 11:20
>>130-131
cnt[i]に出る数値は、

while (cin.get(c)) {
if (c >= '0' && c <= '9')
cnt[c - '0']++;

cnt[c - '0']++;から来ているものなのか、
それとも、
for (int i = 0; i < 10; i++)
から、来ているものなのか?です。
あなたは、「変数」という概念を理解していますか?
「来ているもの」の意味を教えてください。
そうしないと多分、誰も答えられません。
これだけ意味というか意図が不明な質問も珍しい。
136ここで一句:01/12/31 11:45
サポートの
 苦労がいたく
  身にしみる
2001年
 暮れのひととき
言葉を少し変えれば
ここのみなさんも簡単にわかる質問だとは思うが
俺も質問の意味がわからん
深すぎて理解出来んぞ  (^-^;;
やはりこの場は、この板の伝説となっている意味不明質問スレを出すしかあるまい。
エクセルの計算式
http://piza.2ch.net/tech/kako/970/970031167.html
しかし、これは意図を読み取れる人がいた。
121を、「あなたむいてません、おきらめなさい」って小一時間説得したい
141123:01/12/31 12:15

質問の意図がまだ良く分かんねーんだけど,配列の中の値と,配列の添字の区
別が分かってねーんじゃねーか?
それともインクリメントが分かってねーのか?
なんか前者の可能性が高い気がするんだが・・・.

ちょっと簡単な例を出してみよう

> for (int j = 0;j<10;++j)
>  cnt[j] = j;
>
> for (int i = 0; i < 10; i++)
>  cout << i << "の出現回数:" << cnt[i] << '\n';

これだったら何やってるか分かるか? >> 121
142123:01/12/31 12:18
>139
激しくワロタ
腹痛ぇー
143121訂正:01/12/31 14:09
>>141
> for (int j = 0;j<10;++j)
>  cnt[j] = j;

jに0を格納、jに1ずつ足していきjが9になるまで繰り返す。
cnt[0] =j;
cnt[1] =j;
 :
cnt[9] =j;
---------
> for (int i = 0; i < 10; i++)
>  cout << i << "の出現回数:" << cnt[i] << '\n';
ここのcout << iのiには0から9までの数が入り。

cnt[i]はjの値が挿入されてるでしょうか?

僕としては、cnt[i]の[i]になぜjの値が入るのか?解らないんです。
144121訂正:01/12/31 14:17
>while (cin.get(c)) {
>if (c >= '0' && c <= '9')
>cnt[c - '0']++;
ここは0から9の添え字の出力を行い、なおかつ、入力された
数値もカウントされてるんですよね?
>>143
>jに0を格納、jに1ずつ足していきjが9になるまで繰り返す。
> cnt[0] =j;
> cnt[1] =j;
>  :
> cnt[9] =j;
は、
> cnt[0] =0;
> cnt[1] =1;
>  :
> cnt[9] =9;
が正解。

ちなみに、

for (int i = 0; i < 10; i++)
cout << i << "の出現回数:" << cnt[i] << '\n';

というのは、媒介変数iを使って以下を簡潔に書いたものです。

cout << 0 << "の出現回数:" << cnt[0] << '\n';
cout << 1 << "の出現回数:" << cnt[1] << '\n';
cout << 2 << "の出現回数:" << cnt[2] << '\n';
cout << 3 << "の出現回数:" << cnt[3] << '\n';
cout << 4 << "の出現回数:" << cnt[4] << '\n';
cout << 5 << "の出現回数:" << cnt[5] << '\n';
cout << 6 << "の出現回数:" << cnt[6] << '\n';
cout << 7 << "の出現回数:" << cnt[7] << '\n';
cout << 8 << "の出現回数:" << cnt[8] << '\n';
cout << 9 << "の出現回数:" << cnt[9] << '\n';

iの代わりにjを使っても、本質的な違いはありません。
146デフォルトの名無しさん:01/12/31 14:29
はじめまして。
アプリ定義の構造体をファイルに出力したいんですけど
struct _data{char *szdata;
int i;}data;

struct _data{char szdata[256];
int i;}data;
激しく違うよね?
147121訂正:01/12/31 14:43
>>145
//入力に出現する数字をカウントする

例えば122と入力されたとします。

while (cin.get(c)) {
if (c >= '0' && c <= '9')
cnt[c - '0']++;  //ここがjだとしたら
}

for (int i = 0; i < 10; i++)
cout << i << "の出現回数:" << cnt[i] << '\n';

jがcnt[i]に挿入される?のですか?
------------------
入力された122は
cnt[c - '0']++;でカウントされているんですか?それとも
for (int i = 0; i < 10; i++)でカウントされれいるんでしょうか?
>jがcnt[i]に挿入される
勝手に自分用語を作るな
>>146
激しく違う。
150123=141:01/12/31 15:09
>121
> cnt[c - '0']++;でカウントされている
が正解.
for (int i = 0; i < 10; i++)
では cnt の値は何一つとして変えてないだろ.

cnt[c-'0']++;
ってのは
cnt[c-'0'] = cnt[c-'0'] +1;
と同じ意味なのは分かってるか?
これは "=" を使ってるから「cntの値を変更してる」のはいいよな?
その点 for (int i = 0; i < 10; i++) の中では
"<<" という演算子しか使ってなくって,これは cnt の値は変更しねぇぞ.n
だから「カウントしてる」=「cntの値を変更してる」のは前者なわけ.

でもなぁ,きっとお主は配列の概念良く分かってないんじゃないかなぁと思うわけよ.
ちゃんと配列勉強した?
ついにナゾが解明されました
そう、ここは++。とにかく++。
なんて読むんだ++。
>152
チョメチョメ に一票

シーチョメチョメマンセー
154名無しさん@お腹いっぱい。:02/01/01 00:11
g++の標準入出力ストリームについて質問です.
ifstreamを用いて,同じファイルから2回データを読み込みたいとき,
例えば1回読み込んだあと,
seekgを用いてカレントポジションを先頭に戻し,再び読み込む,即ち
#include <iostream>
#include <fstream>
using namespace std;
int main ()
{
char tmp;
ifstream ifs ("hoge.txt");
// 1回目読み込み
while (!ifs.eof ()) {
ifs.get(tmp);
cout << tmp; // 例えば,表示.
}
ifs.seekg (0, ios::beg); // 開始点にシーク
ifs.clear (); // フラグを初期化
// 2回目読み込み
while (!ifs.eof ()) {
ifs.get(tmp);
cout << tmp; // 例えば,表示.
}
return 0;
}
のように書けますよね.
同様に,標準入力(catとパイプでつなぎたい)から2回データを読みたいと思いまして,
#include <iostream>
using namespace std;
int main ()
{
char tmp;
// 1回目読み込み
while (!cin.eof ()) {
cin.get(tmp);
cout << tmp; // 例えば,表示.
}
cin.seekg (0, ios::beg); // 開始点にシーク
cin.clear (); // フラグを初期化
// 2回目読み込み
while (!cin.eof ()) {
cin.get(tmp);
cout << tmp; // 例えば,表示.
}
return 0;
}
としたところ,うまくいきません.
で,cin.tellg ()を使いましてseekg (0, ios::beg)でカレントがどこに移ったか調べましたところ,
どうやらifstreamの場合と挙動が違うことが分かりました.
つまり,ifstreamではseekg (0, ios::beg)によりカレントポジションが最初の位置に戻りますが,
istream (この場合cin)では戻らないようです.
これは,こういう仕様なのでしょうか? それとも,使用しているライブラリの不備なのでしょうか?
(派生関係にあるのだから,同じように動いて欲しいものです.) 私が使用している環境は,
$ g++ -v
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/2.95.3/specs
gcc version 2.95.3 20010315 (release)
です.
155デフォルトの名無しさん:02/01/01 00:42
>>152
マジレスしちゃいかんのかな?
「++」はインクリメントじゃ。
それではこれから「C++」は「Cインクリメント」ということで。
>>154
pipeの仕様。
158デフォルトの名無しさん:02/01/01 02:24
>>152
マジレスしちゃいかんのかな?
(++)は困ったときの顔文字じゃ。
(+π+)とする人もいる。
C++ ← しぃぷるぷる
160名無しさん@お腹いっぱい。:02/01/01 17:45
>>157
>pipeの仕様。

どうやら,最終点まで読み込む前だったら,
seekg (0, ios::beg)は効くみたいです.

例えば,1バイトだけ読み込み,seekg (0, ios::beg)で
先頭に戻したあと,再び読み直す以下のようなプログラム
#include <iostream>
using namespace std;
int main ()
{
char tmp;
// 1バイト読み込んで表示
cin.get(tmp); cout << tmp;
cin.seekg (0, ios::beg); // 開始点にシーク
cin.clear (); // フラグを初期化
// 最初から読み直し
while (!cin.eof ()) {
cin.get(tmp);
cout << tmp; // 例えば,表示.
}
return 0;
}
で,1バイトより大きなデータを標準入力に与えると,
ちゃんと先頭の1バイトも表示し直してくれました.

最終点まで読み込むと標準入力ってバッファを消去してしまうってことなのかな?
>>160
iostreamが管理しているバッファにおさまる限りはseekできるってことでは?
1MBくらい読んでからseekgしてみれば失敗するはず。
seekgが下請けに使ってるlseek(2)はpipeには使えないのよ。
162名無しさん@お腹いっぱい。:02/01/01 21:37
>>161
>1MBくらい読んでからseekgしてみれば失敗するはず。
>seekgが下請けに使ってるlseek(2)はpipeには使えないのよ。

試してみたら,おっしゃる通りでした.
4096バイトまでは遡れるけど,4097バイトでは失敗しました.
どうもっ!
163名無しさん@お腹いっぱい。:02/01/01 21:57
162です.

ついでに,
たとえ4096バイト以内でも,
最終地点に到達したら,seekgは失敗してしまうようです.

まぁ,いずれにしても標準入力に対してはseekgは使えないみたいですね.
164ロリオタ殺す:02/01/01 22:16
Reported by WPNP
Tuesday, January 01, 2002 20:11:46

User Name: TenTen_DWP2f3e793d1a2b
Access Level: user
Time Online: 5:55:17
In Channels:
Status: 11 in queue (-2 of 0 available)
Shared Files: 120
Active Downloads: 2
Active Uploads: 2
Connection Type: DSL
Client Version: WinMX v2.6j


ロリと盗撮と援交・・・・・・・・

web pageはこちら。
ttp://www.tokyo-nazo.net/~tenten/

キーワード
援助交際白書
ディズニーランドトイレ
ロリータ写真集
誤爆か?
166_:02/01/02 00:27
テンプレート関係が1番完璧に処理できるコンパイラはどれですか?
今VC使ってるけどBC++Builderとかg++とかどうですか?
>>166
VC6 << Borland C++ Compiler < g++

ただ GCC は細かいところでバグがある感じ。ネームスペースとテンプレートを絡めて使うと、
たまに挙動が変。
168_:02/01/03 00:10
>>167
ありがとうございます。
Vine Linuxいれたからg++でもやろうかな。
VCでSTLを深くやろうとしたり、テンプレート関係の本のサンプルを打ち込んでも
変な場合があってやる気がなえてたところだから。
Borland C++ Compiler はC++Builderの純粋なコンパイラ部分なんだよね。
GUIのプログラム作るのが楽そうだからこっちもよさそうだな。
169167:02/01/03 00:58
>>168
template らぶらぶ で GUI のプログラムを組むのなら VC6 + ATL/WTL を推しときますが。
VC6 の template は「完璧」からは程遠いですが、実用的なフレームワークを作れる程度に
は機能します。
170デフォルトの名無しさん:02/01/03 01:27
ゲイツ社のC++と、ボーランドのC++ビルダーはどう違うのですか?
171デフォルトの名無しさん:02/01/03 01:34
>>170

ゲイツ社のC++ってVC++のことか?
ソフトが違うじゃん。
C++BuilderのコンパイラよりもVC++のコンパイラの方が最適化が優れている気がするけどどうなんだろう。
173デフォルトの名無しさん:02/01/03 18:30
>>172 その通り、最適化コードの質はVCの圧勝。でも言語規格準拠度はVCのボロ負け。
>>173
VS.NETで改善されてるみたい。
175173:02/01/03 19:47
VS.NET(VC7)で規格準拠もOKとの噂は聞くけど実際のところ、どう?
どこかに比較記事とかあったら紹介希望。
# RCなしでbeta2からいきりなりリリースとは勇気あるなぁ>VS.NET
176デフォルトの名無しさん:02/01/03 20:21
なんつーんだろ。
for文の初期
>>175
英語版はRC出てたはずでは?
VS.NET日本語版の正式な発売日・価格ってまだでないの?
>>177 おや英語版のRCって出てたっけ?ちゃんと届けろよ>MSDN
180デフォルトの名無しさん:02/01/04 01:49
ちょっと質問良いですか?

string型の変数をchar型の配列に変換するにはどうしたら良いんでしょうか?
>180
c_str()
182デフォルトの名無しさん :02/01/04 05:20
すいません教えてください。
ウインドウの作成と初期化、さらにダイレクトXの初期化をするクラスを
作ろうとしているのですが、WindowProc()関数をそのクラスのメンバ関数に
するにはどうすればいいのでしょうか?
WM_DESTROYメッセージの後にダイレクトX関連のオブジェクトをリリースする
必要があるのでどうしてもWindowProc()関数内部からそのリリースする
メンバ関数にアクセスしたいのです。
よろしくお願いします。
・static/global変数でthisを設定しておく
・hWnd -> thisの連想配列で処理する(MFC式)
・hWndをthisにすげ替えるWindProcを自動生成する(ATL式)
お好きなのをどうぞ。
184182:02/01/04 05:59
うーむ。正直サッパリです。どこか参考になるWEBとか
ありませんか?もしくはウインドウ作成と初期化を一つにまとめた
クラスのソース公開しているところとか。
>もしくはウインドウ作成と初期化を一つにまとめた
>クラスのソース公開しているところとか。

なぜATLのソースを読まないのでしょう?
186182:02/01/04 06:45
うーん。ひよっこどころか卵状態なのでATL自体よく分かってないです。
>>183
CreateWindow 直後に SetWindowLong() で this ポインタを HWND に関連付け、ウィンドウプロシージャでは
GetWindowLong() で this ポインタを引き出してきてメンバ関数を呼び出す、ってのもアリかな。

>>186
MSDN Library に「ATL 3.0 ウィンドウクラス入門」という文書があったはず。あれ読んで CWindowImpl 使うの
が楽だと思うぞ。
189182:02/01/04 08:59
とりあえず187のページのSDKダウンロードして
目的のソース見つけました。あとそのページでかなりプログラム技術が
アップしそうな気がします。どうもありがとうございました。
ATLは適当に調べたかんじではまだよく分からなかったので
後回しにします。
190デフォルトの名無しさん:02/01/04 12:02
>>189 その >>187のページって「やねうらお」だね。
内容見てないけど大丈夫かいな。ATLのソースみた方が安心だと思うぞ。
>>190
技術そのものは、あちこちからパクってきたものだから問題ないんじゃない?
(変にオリジナリティを出そうとしてがんばって改悪してるかもしれないけど)
192デフォルトの名無しさん:02/01/04 12:24
>182
この板には>>190-191みたいなアンチやねうら粘着厨房がいるみたい、
気にしない方がいいYO!
>192
レス早いですね
粘着厨房さんですか?p
やねうらって誰?
やねうらおがだれだかのコードをパクって、自分の掲示板で指摘されて
ハジかいたってのは見たことある。
それ以外はよく知らないけど。
>>189
やね氏の能力は否定しないが、
文章を読んで賛美者になったりしてはいけない。
自分で技術的真偽の判別がつかない初心者は気をつけるように。
>>195
タスクコンテクストスイッチに関して、かなりボケたことを言ってて叩かれてたのはリアルタイムで
見てた。最近はどうか知らないけど、当時は「計算機論理設計の基礎が分かっちゃいねぇ、ヘネ
シー&パターソン読んで出直せ」というレベルではあった。

C++ と関係ないから、これ以上、やねうらおを語りたければプログラマー板行きましょう。
198190:02/01/04 14:41
>>197 賛成〜。やねうらお語るほどヒマじゃないけど、
Webの技術情報を安易に信用するなってことで。
199デフォルトの名無しさん:02/01/04 23:31
STLのvector(or その他)について質問。

まず<やりたいこと>

・配列をvectorに置き換えたい。
・でも、配列先頭へのポインタによるアクセスは同じようにしたい

よーするに、T Array[5];をvector<T> Array;にしたいんだけど、 (void*)Arrayって
アクセスもしたい、っつーことなんです。

これ、const_pointer使えばOKなん? それとも、クラス書かないとダメ?
大抵の実装では、vector<T>::iteratorがT *になるはず‥‥
ポインタの方で、要素を追加したりしないなら、こういう手もあり。
まぁ、それを想定するのが卑怯だというなら、クラスを実装
するしかないね。
201199:02/01/04 23:42
うを、素早い(^^;

ということで早速のお返事、ありがとうございます。

>大抵の実装では、vector<T>::iteratorがT *になるはず‥‥
つーコトは、そのまんま(void*)ArrayでOK?(^^;
ちなみに、
>ポインタの方で、要素を追加したりしないなら、こういう手もあり。
なんてことは露ほども考えておりません(^^;
ぶっちゃけて話しちゃうと、DirectX8のDrawPrimitiveで使う頂点配列を、何とかして整理したかったのココロ(^^;
>>199
std::vector<T> v;
T* p = &v[0];

vector は C の配列と同様のメモリ配置になることが規格上保証されてるから、これで OK。C で書かれた
関数と C++ 混ぜて使う場合 vector は重宝します。

>>197
そういや、以前の yaneSDK には std::vector に auto_ptr っぽいセマンティクスを持つ型を格納するという
おおぼけなコードがあった。最近のは見てないから知らんけど。
>>202
> vector は C の配列と同様のメモリ配置になることが規格上保証されてる
これって、規格になったんだっけ。まあ、そういう方向で標準化作業は
すすんでいたと思うので、そうでない実装というのは存在しないだろうけど。
>>200
g++ 付属の stl だと、vector<T>::iterator から T * への暗黙の変換は
定義されていなかったと思う。
>>204
vector<T>::iterator から T* への変換とかいう問題以前にさ、
typedef T* iterator
ってなってるはずなんだが。

今、g++ の vector のヘッダ見てみたけどさ、ちゃんと

typedef _Tp value_type;
typedef value_type* iterator;

ってなってるぞ。
206199:02/01/05 01:58
っと、ごめんなさい。テンプレート付きのクラスでメソッドを記述するには
どうしたらいいのでしょう?

#include <vector>
using namespace std;

template <class T> class apexVector
{
public:
//頂点データのベクタ
vector<T> apex;

void apexVector::method1();

};

vectorは(void*)apexが出来るっつーのでpublicにして横着しようと思ったなり(^^;

が、それは置いておいて、method1でコンパイルエラーになります。apexVector::を
取っ払えばとりあえずコンパイルは通りますが、ここは本来はどーゆー風に書くのでしょう?
ふむ。君はvectorのソースも見ないんだな‥‥ まぁそれはいい。
template <class T> class apexVector {
 void method1() { // 実装
 }
 void apexVector<T>::method2(){//実装
 }
};
ということをやればよい。ああ、テンプレートのメソッドが、テンプレート外に
記述できない、というのは知っているだろうな。(.cppと.hに分離できねーとか
泣きついてくるなよ)
>>203>>205
VC7は違うらしいYO
>>207
template <class T> class apexVector {
 void method1() { // 実装
 }
 void method2();
}
void apexVector<T>::method2(){//実装
}
こうじゃないの?
あ、method2()の実装のまえにtemplate<class T>が必要。
211199:02/01/05 02:36
>>207

>ふむ。君はvectorのソースも見ないんだな‥‥ まぁそれはいい。
厨房で申し訳ないっす(^^;

>template <class T> class apexVector {
〜中略〜
>ということをやればよい。ああ、テンプレートのメソッドが、テンプレート外に
>記述できない、というのは知っているだろうな。(.cppと.hに分離できねーとか
>泣きついてくるなよ)

……知りませんでした、申し訳ない(^^; 「.hと.cppに分離」はC++の作法だと思っておりましたので(^^;
早速やってみます。アドバイス多謝(拝)
>>205
gccのvectorのiteratorはT*との互換性はない、と書いた文書を
俺もどこかで見たぞ。公式の文書で。

古いの見てるんじゃないのか? libc++-v3じゃないやつとか。

それと、O(1)のオーダーでアクセスできることと
C の配列と同様のメモリ配置になることとは違うぞ。
少なくともg++-2/stl_vector.hとg++-3/stl_vector.hでは
typedef value_type* iterator;
となってる。
どうでもいーことだけど、みんな
template<class T>
て書く?
template<typename T>
て書かない?
面倒っちいから template<class T> って書くよ
217デフォルトの名無しさん:02/01/05 10:04
>>202
>std::vector<T> v;
> T* p = &v[0];
> vector は C の配列と同様のメモリ配置になることが規格上保証されてるから、これで
> OK。C で書かれた関数と C++ 混ぜて使う場合 vector は重宝します。

std::vector<T> v;
T& r = v[0];
でなんか問題あるのか? ここでポインタわざわざ使う必要性が見えないんだが。
>>217
「C で書かれた関数と C++ 混ぜて使う場合」があるからなんでは?
>>213
gcc-3.0.2/include/g++-v3/bits/stl_vector.h だと、
typedef __normal_iterator<pointer, vector_type> iterator;
になってるね。__normal_iterator は別のファイルでクラステンプレート
で定義されてる。
220217:02/01/05 11:15
>>218
その「Cで書かれた関数」というのが、「ポインタを引数に取る関数」の
ことならまあ納得するけど、「CとC++を混ぜる」場合、C++上でしかありえ
ないのにC的にする意味は無いと思うが。CにもC++にも適用したいアルゴリズム
はポインタよりイテレータの文脈で処理すべきだ。
221デフォルトの名無しさん:02/01/05 11:15
>>211
>……知りませんでした、申し訳ない(^^; 「.hと.cppに分離」はC++の作法だと
つーか、それは MS の作法なんじゃねーの? 不必要に情報をタレ流さない
ためには、やたらと .h を作らないほうがいいと思うんだが。

あと、テンプレートクラスを .h で定義しておいて、そのメソッドを
.cpp で実装する、ということは可能だよ。export が使えれば一発だが、
これが使えなくても、必要に応じて明示的なインスタンス生成というのを
やればよい。
>>220
DirectX みたいな「与えられた API」を使ってプログラムを組む場合には、C++ を使っていてもポインタに
縮退させること必須でしょうが。文脈読めよ。
>>222
どして? その元の話がvectorを使おうとしてる以上DirectX云々は
副次的な文脈だろ。ちなみに俺の回答は「そんなとこでvector
使うんじゃねえヴォケ!」
>>223
> 「そんなとこでvector 使うんじゃねえヴォケ!」
なんで?
>>223
STL は C との相互運用にも十分に配慮されたライブラリだから、使わない手はないと思うが。もし英語が
苦手でなければ Scott Mayers の Effective STL を買ってきて Item 16 "Know how to pass vector and
string data to legacy APIs." を読むことを薦めとく。
>>215
Modern C++ Design で、
クラス(ユーザー定義型)しか使わないなら class
組み込み型も使う可能性があるなら typename
っていうふうに使い分けてた。

>>219
いわゆる type traits ってやつかな。
__normal_iterator<pointer, vector_type> を展開すると結局ただの valuetype* になりそうな気がするんだけど。
227デフォルトの名無しさん:02/01/05 14:38
>>223 なんでかなー、vector 使って良いじゃん。
extern "C" の既存関数やAPIに対して、
std::string の持つデータを .c_ptr() や .data() で渡すのと同じでしょ。

それとも、vector<T> のかわりに basic_string<T> を使えという
主張ですか?それなら納得するけど。
228無名λ式:02/01/05 14:54
>>168
g++は、version3以上じゃないと、VC++6よりtemplateはへぼい。そこに注意。
>>219
gcc の STL は読んでないので知りませんが、他の有名どころだと STLport の vector<T>::iterator がデバッグ
モード限定で T* ではないですね。

話がそれるけど STLport のデバッグモードは無効な iterator 参照などを簡単に発見できて便利です。T* な
iterator だと、元の vector に push_back しても iterator が正しい領域を指しつづけることが多いから、バグを
埋め込んだときに再現率が低くて泣ける。
>>225
>>223
>STL は C との相互運用にも十分に配慮されたライブラリだから、使わない手はないと思う
>が。もし英語が苦手でなければ Scott Mayers の Effective STL を買ってきて Item 16
>"Know how to pass vector and string data to legacy APIs." を読むことを薦めとく。

やむをえない時にやるべきことと、率先してやるべきことを混同していないか?
スタック上とか任意の場所にメモリを置いていたいときにvectorだと簡単に管理
できないし、相手先のC関数の挙動とvectorの実装が完全に見えている(=カプセル化
されていない)状況でしか使えないというのはバグの温床以外の何物でもない。
せめて間にラッパ入れてやらないと。
>>230
スタック(というか自動変数)として vector とるのはまったく問題ないけど。その場合でもデータそのものは
allocator 経由で(一般には)ヒープ上に取られた領域に置かれるけど、その違いが問題になるケースって
あるなぁ。

考えられるのは API 内部で渡されたデータに対して free() したり realloc() するケースだけど、それは

 生成 破棄 利用

いずれも専用の API 群で行う設計で、そもそも vector 使う余地がないし。

> 相手先のC関数の挙動とvectorの実装が完全に見えている(=カプセル化されていない)状況でしか使え
> ないというのはバグの温床以外の何物でもない。
問題になるような関数の例を希望。

あと vector の実装に関して仮定していることは「データが連続領域にとられること」だけで、特に問題ない
と思う。

> やむをえない時にやるべきことと、率先してやるべきことを混同していないか?
C++ だと malloc() で確保した生のメモリ領域を自前で管理せず vector を使うのは「率先して」やるべきこと
でしょう。例外中立/安全な可変長のストレージを作ろうとすると、結局 vector と同じような実装にいきつく
ことになるし。
>あと vector の実装に関して仮定していることは「データが連続領域にとられること」だけ

これ、
C++ Final Draft International Standard
http://www.kuzbass.ru/docs/isocpp/
に載っていますか? ちいさいデータなら並んでるかもしれませんが大きな
データは簡単に確保できず断片化されるとかあるんじゃ、と思ったんで。
233デフォルトの名無しさん:02/01/05 17:34
vectorの意図しているのは可変長配列であって、
バッファではないよ。バッファとして使いたいなら本来は
それ用のクラスを作って使うべき。もしくはget_temporary_bufferを使うか。
理念でなく実利で言うなら、要素のコンストラクトがおこるとかもある。

>問題になるような関数の例を希望。

について言えば、明らかにカプセル化の理念を無視してるわけだから、
例なんかなくても一見してだめ。

もっとも、俺自身は「わかってやってるならよし」という立場だけど。
234227:02/01/05 18:06
あっさり無視されたんでもう一度書くけど
>>233 バッファとして使うなら basic_string<T> ではだめかね
stringのc_str()とかdata()って、新しい領域を内部でnewしてるんじゃないかと
怖いんだけどそんなことってない?
>>235 コピーした直後とか、部分文字列として取りだした直後は、
内部で new してる可能性があるね。でもなぜそれが怖いの?
>>232
それだと vector と deque を分ける意味がないと思うけど。

規格にざっと目を通してみたけど、vector のデータが連続領域にとられることを明記してる文章は
見当たらんね。Effective STL には p.74 に

 The elements in a vector are constrained by the C++ Standard to be stored in
 contiguous memory, just like an array, ...

と書いてあるけど。

>>234
名前が basic_string だから文字列にしか使えん、と思ってる人多数に一票。わりと使いでのある
クラスなんだけどね。
>>233
> 明らかにカプセル化の理念を無視してる
どこが? vector の内部データ形式を仮定してるところかな。

basic_string は値の「共有」を可能にするために参照カウンタが入ってることが多いよね。書き換えが少ない
(でも書き換えないわけじゃない)小規模なデータを値として渡していく場合には便利だけど、DirectGraphics
の頂点リストを管理するには不適切と思うな。

っつかバッファでもサイズが大きくなったら basic_string 捨てて rope だと思われ。標準じゃないけど。
ropeって、その安直なネーミングが萌え
>>236

Cスタイル関数に渡すのにc_str()して、それが何万回も呼び出されると考えると、
newされるのは勘弁して欲しい
>>240
性能に関しては、プロファイラにかけてボトルネックになってることを特定してから考えれば良いと思う
けど。

ちなみに VC6 添付の STL や STLport, あたりだと、内部で C 形式の文字列データを使ってるので、
c_str() は

  return this->internal_buf_ptr;

みたいなコードになってる。コストは this 経由の間接参照が一つ入るだけ。gcc 2.95.3 の STL だと

const charT* c_str () const
{ if (length () == 0) return ""; terminate (); return data (); }
charT* data () { return reinterpret_cast<charT *>(this + 1); }

と末尾を eos で埋める terminate() 呼び出しが入るけど、それを除くとコストはやっぱり間接参照ひとつ分。
242236:02/01/05 23:55
>>240 c_str() 呼出毎に毎回 new は無いから安心しな。必要に応じて new するだけだよ。
言語規格上は毎回 new しても構わないが、まともな実装ならそんなことはしない。
memcpy( const_cast<char*>(stringVar.data()), ***, ***)
みたいなことをよくするので(他にはfreadとか)、いちいちnewされたら困る。あと、こういう実相依存なプログラムしてるといつか困るとは思う。
244236:02/01/06 01:57
>>243 はぁ〜、const外したらマズイしょ。しかも memcpy …
stringの保持データ操作には
string::assign(const charT*, size_type) や
string::replace(size_type, size_type, const charT*) を使っておくれ
fread に渡すのは auto 変数のバッファにし、後で assign/append しておくれ
245199:02/01/06 02:18
ううっ、ついていけないほどの高度な議論になってる……(^^;

とりあえず、
std::vector<T> array;
void* p = &(array.at(0));

で、

T array[5];
void* p = array;

と同じ動作になりました。アドバイスしていただいた皆さんに感謝(拝)
ちなみにクラス定義はメソッド実装も含めて全部.hに集約したナリ。
軟弱でソマソ(^^;

ちなみに、VC++ Ver.6のSTLには、メモリ不足時にかなり致命的なバグが
あるとゆー話を聞いたのですが本当?
なんでも、メモリ確保に失敗したら例外出さずにreturn 0;するとか……(^^;
>>245
STL に限らず、VC++6.0 の new はメモリ確保に失敗しても例外投げないよ。
set_new_handler の仕様も標準のものと全然違う。
>>245
バグというか、仕様ですね。operator ::new(size_t) 失敗時に呼び出すハンドラを _set_new_handler() で指定
できるので、そこで対処してください。
int型の値ををChar型に投げたいんですが

int i = 3;char c;
c = i;

としたとき、
cの値が'\003'ってなるのですが、原因がわからず妙な所で苦戦しています。
だれか助けてください・・・
今日は盛況だねー
>>243
>memcpy( const_cast<char*>(stringVar.data()), ***, ***)

それっぽいのは俺もよくやる。WindowsだとconstになってるべきAPIが
constじゃない場合があるからその場合は仕方なく...とか思ったら
コピー元じゃなくコピー先かよ。氏ね
250248:02/01/06 03:46
う・・・もしや文字コードが3になってるだけか・・・
>>250 その通り。きみのやりたいことは c = i + '0'; で実現できるね。
>250
正解!!オメデトウ!

まぁお主のやりたい事は sprintf を使うのがてっとり早いかな.
# フレーム合戦はヤめような(藁 > all

>>249
激しく同意
>>243
data()で返される領域は、複数の string で共有してる可能性があるので、書き換えると大変なことに(だから const なんだよ、無闇に const 外すな)。
>>252
> # フレーム合戦はヤめような(藁 > all
当事者その一だけど、それなりに実のある話になってるから良いじゃない。コピペ荒らしとか単調なレスの
繰り返しとかは不快なだけだが、この程度のフレームはネットの華ってことで見逃してくれ。

(もう、だいたい話は出尽くしたと思うけど)
256252:02/01/06 11:19
>255
悪ぃ悪ぃ.そーゆー意味じゃなかったんだ.
sprintf 厨房逝って良し!
とか言い出されるとメンド臭ぇなぁって思っただけ.
257243:02/01/06 12:34
2ch来て1.5年くらいになるが、こんなに罵倒されたのは初めてだ(w
ファイルサイズ取得して、resizeして、freadにconst_castして放り込む・・・とかやってる奴は密かに多いと思うのだが。真似しちゃ駄目よ。移植性0よ。でも面倒だよなー。

他の逝ってよしテクとしては、setでのconst_castがあるなぁ。
setVal.find()の返り値はconstのiteratorなのだけど、これはコンテナの値を書き換えるとコンテナの順番が
入れ替わってしまうので、それを阻止するためのconst。
しかし、述語関数オブジェクトでは評価されていないコンテナのフィールドを書き換えたいときがある (こ
の場合コンテナの順番は変更されない)ので、こういうときにconst_castでiteratorの constを除
去してみる。
ちなみにVCのSTLはconst_iteratorではなく普通のiteratorを返してくるのでこの逝ってよし技は
不要。というかVCユーザは無意識のうちにこの技を使っていることが多いと思われ。
>2ch来て1.5年くらいになるが、
だったら適当に改行入れることを覚えろ。

>ファイルサイズ取得して、resizeして、freadにconst_castして放り込む・・・とかやってる奴は密かに多いと思うのだが。真似しちゃ駄目よ。移植性0よ。でも面倒だよなー。
勝手に思いこんでるだけだろ。
2chに来て1.5年以上になるが、basic_stringに対して
こんなふざけた扱い方をしている人間は初めて見たよ。

やるなら、vector<char>でreserve()してbegin()か&v[0]を放りこむ。
それなら(保証されていなくても)密かにやってる人間はたくさんいる。
参照カウンタの考え方を理解していれば、
basic_string::c_str()の書き換えなんか絶対やらない。
作業バッファとして用いるなら、basic_stringは効率が悪い。
set.find()がconst_iteratorを返す実装ってどれ?
>>259
SGI STL
261259:02/01/06 15:33
SGIやRogueWaveは確かめたんだけど。

俺の持ってるのが古いのかと思って、http://www.sgi.com/tech/stl/download.htmlから
Ver3.3を落としてみたけど、stl_set.hでは
iterator find(const key_type& __x) const { return _M_t.find(__x); }
となっている。
262259:02/01/06 15:35
それとも、見るべきファイルが違うかな?
手元にある範囲では VC++6 のと BCC5.5 のと gcc3 のと SGI のは、
constじゃないiteratorを返すなぁ…。
「243、問答無用で逝ってよし」状態
>>261
それ、上のほうで

typedef typename _Rep_type::const_iterator iterator;

とか定義されてない? 俺が見てるのは gcc 2.95.3 についてくる SGI STL なんだけど、これは
find でとってきたイテレータ経由で値を書き込もうとすると、

set.cpp:9: assignment of read-only location

と怒られる。
266259:02/01/06 16:23
確かになってた。なんでだろ?
setだと、
typedef typename _Rep_type::const_iterator iterator;
typedef typename _Rep_type::const_iterator const_iterator;
mapだと、
typedef typename _Rep_type::iterator iterator;
typedef typename _Rep_type::const_iterator const_iterator;
267259:02/01/06 16:53
ver2.03も落としてみたけど、この頃('97.9)から
typedef rep_type::const_iterator iterator;
になってるね。
gccだと、プリミティブ型でなければコンパイルは出来るみたい(警告あり)。
もちろん、Compareに直結する要素を書きかえると順序が狂う。
268:02/01/06 17:39
残念!>>243君は、まるきり逆で、「const_castすること」
がポータビリティのある書き方である。
詳しくはEffective STL Item22を見よバカチンども(゚Д゚)!
const_castを使わない方法も載ってるよ。
>>268
はいはい、逝っちゃってる人はMeyersのケツの毛でも煎じて飲んでいて下さい
270:02/01/06 18:13
cout<<
で出力する値の、整数部、小数部の桁数を指定するのはどうするのでしょう。

Cの
printf("%4.9lf",1234.123456789); みたいなの。
>>270
マニピュレータ使え
正直、そういう時はすぐにsprintfを使ってしまう・・・
>>272
微妙に同意。私も strstream は使わずに snprintf してしまう方だ。

stream 使えば

1. 型安全で
2. 入出力先に依存しない汎用的な記述ができる

のは分かってるんだが、書式指定が読みにくすぎて辛いんだよなぁ。

double d;
int n;
printf("%5.1f / %d\n", d, n);
cout << setw(5) << setprecision(1) << setiosflags(ios::fixed) << d << " / " << n << '\n';
昔、こんな感じの
cout << formatFix(5, 1) << d;
マニピュレータを作ろうとしたこともあったが、
sprintf 系の手軽さの前に挫折した。堕落のついでに
ostream に sprintf メソッドが欲しい今日この頃。
275:02/01/06 23:54
助言ありがとうございました。無事、望んでいた動作をするプログラムができました。

I/Oストリームを使ったファイル出力法しか今は理解していないので、
ストリームを使った桁処理が知りたかったのですが、
持ってる参考書のマニピュレータの項には、setw(int x)は載ってたけど、
setprecision(int x) が未掲載で、小数部の桁を操作する関数名が分からず困ってたのです。
軽量ストリームとか汎用ストリームとか、次のC++標準には入れて欲しいな。
でも何年かかることやら...
>>274
cout << format(d, 5, 1);
みたいのじゃないのか。
278デフォルトの名無しさん:02/01/07 05:57
class hoge{
 private:
 foo f;
};

class foo{
...
};

こうすると型名が必要、宣言に;がないとコンパイルエラーが出てしまうの
ですが、クラスfooをクラスhogeの前に書く方法以外でできる方法はあるの
でしょうか。教えて下さいませ
>>278
ない。
foo fをfoo* fにしてもよいなら
hogeの前にclass foo;と書けばよい。
>>279
「前」に書かなくても

class hoge
{
  class foo* pFoo;
...
};

で OK。あと

class hoge
{
  class foo;
  foo* pFoo;
};

だと nested class である hoge::foo を宣言したことになるので注意。
281278:02/01/07 08:05
>>279
>>280
勉強になりました。ありがとうございました
>>280
わざわざ実務的に有用な方を教えてるのに、
よけいなフォロー入れないで頂戴。
実務的に有用?
スタイルの問題だとおもうけど?
a = b+++c; って、色々解釈できると思うんだけど、どう解釈すべきか、規格かなんかで決まってます?それかエラー?
>>284
ふつー
a = b++ + c
だと思うけど、人に聞く前にとりあえずコンパイラ通せ
286284:02/01/07 23:08
>>285
う。そうでした。
a=b+++c; は a = b++ + c; でした。
ついでに試してみると a=b++++c; とか a=b+++++c; はエラーでした。
C++Builder 5 にて。
>>284
演算子の優先順位というのがあって、例にあるものだと、
「後置++」>「前置++」=「単項+」>「加算+」>「代入=」という順になる。
よって、「a=b+++c;」は「a=((b++)+c);」と評価される。

「a=b++++c;」とか「a=b+++++」だと、
「a=((b++)++)」の段階でアウトになる。
# 「b++」の結果、つまり整数はインクリメントできない
VC++6.0 だと DLL の中で std::map の代入演算子が利かないってマジですか?
というか利かなかったんですけど、それってどこが悪いんですか?
ここに書いてあるようにマイクロソフトですか? それとも僕の脳ですか?

ttp://www.nantekotta.com/stl.html
289デフォルトの名無しさん:02/01/08 01:18
>>288 アプリとDLLの両方を MSVCRT.LIB リンクで統一しているか? SP5 を当ててるか?
290デフォルトの名無しさん:02/01/08 02:18
b+++c が (b++)+c になるのは、オペレータを出来るだけ長いものからマッチングする字句解析の規則から。
b の後のオペレータは + と ++ とどっちにもマッチングするけど、 ++ のほうが長いから、そう解釈される。
優先順位できまるなら b+++++c は 加算+より優先順位の高い前置++が優先されて、 b++ + ++c と解釈されるはず。
実際はそうでない。

優先順というのは a + b * c のような時 * のほうが + より優先順位が高いから a + (b * c) になるときの規則。
字句解析が終わった後の構文解析の規則。
291278:02/01/08 13:42
class hoge{
 private:
 int h_size;
 class foo *h_foo;
 public:
 hoge(){ h_size=0; }
 void setFoo(class foo *f){ h_foo=f; }
 int get_h_size(){ return h_size; }
 void h_print(){ cout<<h_foo->get_f_size()<<endl; }
};

class foo{
 private:
 int f_size;
 class hoge *f_hoge;
 public:
 foo(){ f_size=1; }
 void setHoge(class hoge *h){ f_hoge=h; }
 int get_f_size(){ return f_size; }
 void f_print(){ cout<<f_hoge->get_h_size()<<endl; }
};

二つのクラスの関連を双方向にしたいのですが、上記だと
型が宣言されていないため 'get_f_size' は 'foo' のメンバーではない(関数 hoge::h_print() )
という、コンパイルエラーが出てしまいます。これは関連の実装が間違って
いるのでしょうか?それともアクセスの仕方が間違っているのでしょうか?
教えて下さいませ
>>291
void hoge::h_print() と void foo::f_print() の実装を
書く場所がまずい。クラスの外に書け。
293デフォルトの名無しさん:02/01/08 14:17
名前と年齢を入力し、ハッシュ(チェイン法)に登録する。'-'が入力
されると登録を入力し、次に入力された年齢を、ハッシュ法で検索
し、あればその人の名前を出力するプログラムを作成せよ。ただし
ハッシュ表の大きさは9とする。

学校でこの問題を出されましたが、さっぱり分かりません。おまえら
教えてくださらないでしょうか。
294278:02/01/08 14:18
>>291
クラスの外に書くとは
class hoge{
...
void h_print();
};
void hoge::h_print(){ ... }
という事でしょうか?これでも同じエラーが出るのですが
>>293

宿題みてあげるっ
http://pc.2ch.net/test/read.cgi/tech/1007902384/

で怜のご機嫌を伺うか

[[ハッシュ法統合スレッド]] vol.1
http://pc.2ch.net/test/read.cgi/tech/1005461137/
296291:02/01/08 15:53
>>278 クラスの外に書くとはこういうことだよ

#include <iostream>
using namespace std;

class hoge{
  private:
  int h_size;
  class foo *h_foo;
  public:
  hoge(){ h_size=0; }
  void setFoo(class foo *f){ h_foo=f; }
  int get_h_size(){ return h_size; }
  void h_print(); //{ cout<<h_foo->get_f_size()<<endl; }
};
class foo{
  private:
  int f_size;
  class hoge *f_hoge;
  public:
  foo(){ f_size=1; }
  void setHoge(class hoge *h){ f_hoge=h; }
  int get_f_size(){ return f_size; }
  void f_print(); //{ cout<<f_hoge->get_h_size()<<endl; }
};
inline void hoge::h_print(){ cout<<h_foo->get_f_size()<<endl; }
inline void foo::f_print(){ cout<<f_hoge->get_h_size()<<endl; }
297278:02/01/08 16:32
>>291
で、できました!ありがとうございました
今やっとコンパイルエラーの意味が分かりました(汗)
298296:02/01/08 17:21
>>297 おめでとう。
ちなみに、2chにソースを書き込む際にはインデントを、
全角スペースじゃなくて、&nbsp; に置き換え希望〜。
299284:02/01/08 21:17
>>290
よく解る説明を有り難う。参考になります(Javaも同じなのかな?スレ違いだけど)
>>298
ええーっ、面倒い〜・・・
いや言いたいことは解るけど
かちゅーしゃにそういう機能付かないかなと密かに祈りを
301デフォルトの名無しさん:02/01/08 22:14
>>300 かちゅーしゃ は使ったことがないから知らんけど、
        ここの板にスレのある 「2chブラウザ」 は、
        スペースやタブを &nbsp;に 変換する機能あるよ。
302デフォルトの名無しさん:02/01/08 22:22
同じディレクトリにある全ての.hファイルを
1度にincludeする方法ってありませんか
ありません。
304デフォルトの名無しさん:02/01/08 22:43
VC6.0 だが fstream の tellp, tellg が機能しない!
>>302
Makefile に、次のようなターゲットを仕込んでおけば?

all.h:
 ls -1 *.h | perl -lne 'print qq(#include "$_")' > all.h

distclean:
  rm -f all.h
306293:02/01/08 23:13
>>295

ありがとうございます。
とりあえず統合スレの方見てみます。
>>300-301
:%s/\t/&nbsp;&nbsp;&nbsp;&nbsp;/g
308304:02/01/09 19:05
スマソ
キャストしないで printf してた。
309:02/01/09 19:31
ofstream File[2];
File[0]("abc01.txt");
File[1]("abc02.txt");

↑これでエラーでたのですけど、不正な書式なのでしょうか。
310デフォルトの名無しさん:02/01/09 19:39
>>309 こうするのダ
ofstream File[2];
File[0].open("abc01.txt");
File[1].open("abc02.txt");
placement newが云々、という話は関係ないかね?
312:02/01/09 19:45
>>310
どうも。解決できました。
313デフォルトの名無しさん:02/01/10 00:07
質問です。
例えばclass Addressというものがあるとして、

Address a;
struct in_addr addr = a;

というのをどうしても成立させたいのですが、
class A : public in_addr {
  ...
}
というような、in_addrを直接継承する以外の方法では
可能でしょうか。

http://forums.belution.com/ja/vc/000/006/08s.shtml
のURLに同じような質問があったのを発見し、そこでは
解決策がいくつか出ているみたいですが、具体的に
どうオペレータオーバーロードすれば良いのか分からないです。
void operator =(in_addr &left, const Address &right )
addr = *(struct in_addr *)&a
毎回やるのが面倒だったら、operator in_addr& () でも作っとけば?
>315
上のは、aがin_addrを直接継承してないと無理な気が‥‥
やってみた?
C形式のキャストが嫌なら、アドレスをreinterpret_castでどーぞ
>>313
>>314 が正解だろうね。でも generic programming で必要、とかいう理由がないのなら、
単純に class Address に copyAddr( in_addr& addr ) というようなメソッドを定義して
それを使ったほうがプログラムは分かりやすくなると思うな。
319315:02/01/10 01:07
in_addrを要求するsocetAPIにAddressを渡すという話だと思ってた。違ったか。
320315:02/01/10 01:36
言い訳すると、実際にsocket関係は、共用体じゃないのに
struct sockaddr_inで値を設定して
struct sockaddrにキャストして渡したり、ってことをするわけさ。
だから、Addressもその一種だと思ってしまったのさ。
こんな感じ。(WinSock2.0プログラミングのgethttp.cppより)
 saServer.sin_family = AF_INET;
 saServer.sin_addr = *((LPIN_ADDR)*lpHostEntry->h_addr_list);

つまり、サイズ等は一緒でそのままキャストで渡せるものが入っていると
勝手に想像してしまったわけ。
ごめんね。
321313です:02/01/10 01:36
みなさんありがとうございます。

class Address {
  public:
    operator in_addr() const;
}

Address::operator in_addr() const {
  struct in_addr addr;
  ...
  return addr;
}
のようなものを用意したらできちゃいました。なぜか。
コンパイラ(gcc-2.96)も文句を言わないし、出来た実行ファイルの
動作も期待通りになりました。

でまた質問なんですけど、なんでこれ返り値が必要無いんでしょうか。
322デフォルトの名無しさん:02/01/10 01:43
 メンバ関数をヘッダファイル外でインライン指定したときの
コードについて質問です。

// HOGE.h
class HOGE{
public:
  HOGE(){}
  virtual ~HOGE(){}
  int Boo(int);
private:
  int foo(int);
}

// HOGE.cpp
inline int HOGE::foo(int n){
  return n + 5;
}
int HOGE::Boo(int n){
  return foo(n);
}

 こう書いたとき、HOGE.hをインクルードしたソースファイルが
HOGEオブジェクトを創るときは、どうなるんでしょう?
HOGEオブジェクトは、fooを呼び出すための関数ポインタを
持っちゃうんですかね? fooがpublicだったら結果は
違ってきますかね?
 fooが有るときと無いときで、sizeof(HOGE)は違う値を
返しますか?
 どなたか、ご教授ください。m(__)m

 「コンパイラに通して調べろよ」ってのはナシで。
マシンの不都合で、1ヶ月ぐらいはコンパイルできないんす。(T_T)
あ、もしコンパイラ依存の問題なら、VC++の場合でお願いします。
>>322
どこに関数ポインタを宣言してる?
>>321
キミのコードは正しいよ。自信がないみたいだから、「なぜ」正しいかを
勉強しておいたほうがよいと思うけど。

ただ、型変換オペレータは、思わぬところで暗黙のうちに働いてしまう
ことがあるので注意したほうがよい。

あと、型変換オペレータに戻値の指定がないのは、まあコンストラクタと
似たようなものだから、かな。
>>323
仮想関数へのポインタと思われ。

>  fooが有るときと無いときで、sizeof(HOGE)は違う値を返しますか?
仮想関数が有るか無いかで、オブジェクトのサイズは変わってくる。C++ の実装に関して詳しく知りたい
なら Inside the C++ Object Model という書籍を買ってきて読みましょう。
>>314
ん? クラスのメンバーじゃない operator= って定義できたっけ?
できねーな。
328デフォルトの名無しさん:02/01/10 16:58
>>278さんに便乗して質問です。

>>296のソースだと、新しいクラス(aaa)をもうひとつ追加してそれらが
相互に通信しあうとすると、各クラスにそれぞれ、
1.メンバ変数の追加
class aaa* m_aaa;
2.ポインタ登録用のメソッドを追加
void setAaa(class aaa* aaa) { m_aaa = aaa;}
3.Aaaを使用するメソッドを追加。
void aaa_print();

の3工程必要になりますよね。

もうひとつの方法として、すべてのクラス(のポインタ)をグローバルに
宣言して、共通ヘッダに押し込めてしまうという手法が考えられます。

上記の例だと
extern class foo* g_foo;
extern class hoge* g_hoge;
extern class aaa* g_aaa;

そうすると、上記工程の1、2は省略できて3の工程のみにできます。
実際はclass aaaの定義ファイルのインクルードが必要ですが。

というように、この方法は大変便利なんですが、インスタンスの変数名g_aaaが、
決めうちになってしまう辺りが、どうにも気持ち悪いと自分では思ってます。

で、双方向関連を表現するのに、上記の2つの方法以外に
何かいい方法ご存じないでしょうか?
329デフォルトの名無しさん:02/01/10 17:56
>>325

322のどこに仮想関数が?
>>329
あえて言えばデストラクタ?

っつか、たぶん求めてる答えは

 仮想関数があると仮想関数へのポインタを格納した vtbl が作られ、各インスタンスには vtbl を指す
 vptr が格納される。よって仮想関数なしの場合に比べると、インスタンスのサイズは増える。

 仮想関数が無い場合には、メソッドはリンク時に静的に解決され、関数ポインタを介さずに直接呼び
 出される。

という話のような気がする。>>322 のコードに限って言えば、デストラクタが仮想なので、すでに HOGE
のインスタンスには vptr が含まれることは確定。したがって foo() があってもなくても、仮想でも非仮想
でも HOGE のサイズには影響しない。
331観筒:02/01/10 21:47
>>325
>Inside the C++ Object Model
 amazonで探したら、洋書しか出てこなかったんですが…。和訳されてないんですかね?
へたれアマグラマなんで、「英語で読め」は勘弁してください。(T_T)

>>330
 あー、俺が勘違いしていた部分まで踏まえて、完璧な回答ありがとうございます。
 なるほどー、virtualでないメンバ関数は、インスタンスのサイズに影響はないんですね。
てっきりインスタンスがメンバ関数まで丸ごと抱えているのかと思ってました。
 あ、もしかして、メンバ関数を呼び出すときって、インスタンスのアドレスをスタックに
積んでから呼び出してるんですか? それで、メンバ関数内では、渡されたインスタンスの
アドレスをthisとして扱う…と。そういう仕組みですか?

 と。そこで、生まれてきた疑問を。

class HOGE{
public:
    int Boo(int){cout << foo();}
private:
    virtual const char* foo(void){return "ほげ";}
}

class HOGE_EX : public HOGE{
private:
    virtual const char* foo(void){return "ほげEX";}
}

int main(void){
    HOGE_EX HE;
    HE.Boo();
    return 0;
}

 この場合、表示されるのは「ほげEX」ですか? こういう風に基底クラスの
内部で仮想関数が呼ばれる場合のオーバーライドの例って、見たことがないんです
けど、上の俺の考えが合ってるなら、「ほげEX」と表示されるはずだと思うんですが…。
>>331
>アドレスをthisとして扱う…と。そういう仕組みですか?

そういう仕組みです。

>この場合、表示されるのは「ほげEX」ですか? こういう風に基底クラスの

そーです。ちゃんと派生クラスのが呼ばれます。
333観筒:02/01/10 22:50
>>332
 ありがとうございました! おかげで、クラスの実装の詳細に関する疑問が
すっきり解決しました。
334デフォルトの名無しさん:02/01/11 00:07
インスタンス生成関数内で、その戻り値と同じ型の変数に自分自身
のインスタンス生成関数を引数NULLで呼ぶとその変数の中身は
どうなるの?
>>328 グローバル変数に持つ(全インスタンスで共有)のと、
メンバに持つ(各インスタンスが持つ)のではクラスとして機能が異なる。
コーディングの手間を省くために機能変更しちゃダメだよ。
>>334
日本語がよくわからん。コードを書いたほうが早いかも。

C++ のコンストラクタには返り値ないよ、念のため。
>>336
すまん。書いてからそう思った。
中身忘れたんで明日またソース見てくる。
338超初心者:02/01/11 10:53
Solaris8,forteC++を使っていらっしゃるかたいらっしゃいますか?
stringを使って作ったソースでオブジェクトを作って、そのオブジェクトを
dlopen で開こうとするとエラーになってしまうのですが・・・
なにが悪いのか分かりません・・・
ご指摘お願いいたします。

意味を持たないソースだけど例えばこれのオブジェクトをdlopenで開けないということです。
#include<stdio.h>
#include<string>
using namespace std;
int main()
{
string k("test");
return 0;

}
>>338
一応指摘しておくけどこういう場合はオブジェクトって
言わないでライブラリって呼ぶんじゃないかな

まずmain()はダイナミックロード出来ないと思う
あとはコンパイルオプションを確認しよう
>>339
C++ と dlopen を一緒につかうなんてオトコのコです.
extern "C" について調べましょう.
341超初心者:02/01/11 14:38
返信有り難うございます。
もうちょっと具体的にエラーの原因を書きますので
よろしかったら再びアドバイスいただけると助かります。

1 いくつかのオブジェクトファイルを使って一つの動的共有ライブラリ(仮にtest.soとしておきます)を作成します。
2 C版APIを使ったソースでtest.oを使用する。
3 2の過程でdlopen()が使われている。
4 dlopen()が失敗する原因はtest.soのなかで使用している
「std::basic_string<char,std::char_traits<char>,std::allocator<char> >::__nullref」
というシンボルが参照できないため再配置エラーとなって失敗している。

というような状態です。
で、>338で作ったものでもまったく同じエラーが出ました。
ちなみに他のOSの他のコンパイラではエラーはおきていません。

というわけでこのコンパイラ特有の何かだと思うのですが・・・
まず、(3)、(4)の条件からどのあたりに目をつけていけば良いか
アドバイスいただけたらよろしくお願いいたします。
>>339
> 一応指摘しておくけどこういう場合はオブジェクトって
> 言わないでライブラリって呼ぶんじゃないかな
個人的には、ライブラリと言うと複数のオブジェクトをまとめたファイルって感じがするなぁ。単一モジュールだけ
ファイルに切り出してダイナミックローディングするというのは割と良くある。(デバイスドライバとか)

>>341
std::basic_string<char, std::char_traits<char>, std::allocator<char> >::__nullref が、処理系付属の C++ ライブラリ
かどこかで定義されてるんだと思う。

ELF オブジェクトだと依存関係を書き込むセクションがあったと思うので test.o に

 このファイルは C++ 標準ライブラリ (libc++.so とか?) に依存する

旨を書けば良いんじゃない。とりあえずリンカのコマンドラインオプションをチェック。
343デフォルトの名無しさん:02/01/11 22:23
VCでinlineをつけるとエラーがでるよー
定義の方だけつければいいんだよね?
リンクでエラーが・・・
>>343
> 定義の方だけつければいいんだよね?
定義をヘッダではなく実装 (*.cpp) に書いてないか?
345343:02/01/12 00:36
>定義をヘッダではなく実装 (*.cpp) に書いてないか?
あれ、それじゃダメ?
inline void class::method(){
return;
}
って感じじゃダメだっけ?
>>345
Class hoge{
public:
&nsbp;&nsbp;inline hoge & foo (const hoge & foo) {}
}
nsbpじゃなかった…nbsp
348デフォルトの名無しさん:02/01/12 00:57
inline関数って使える??
つーか、どうやら使えない奴がいる。
>>348
「使える?」って、どういう意味だ。
>>348
そりゃ、使えるだろ。
>>345
そもそも *.cpp に書いたら、どうやって

 「インライン化」

するんだよ。インライン関数利用側をコンパイルする時点で定義が見えないとインライン展開しようがないから、
インライン関数はヘッダに書く。

ヘッダで関数を定義すると、複数のオブジェクトファイルにコンパイルされた関数が含まれる可能性がある。そ
こでリンカのシンボル重複定義エラーを避けるために、inline 関数は自動的に static リンケージになる。同一
翻訳単位外からは、inline 関数は見えない。

>>346
class 定義の中にメソッドを書く場合、暗黙のうちに inline 扱いされなかったっけ? あとクラス間で相互参照
が入る場合には、どうしても宣言と定義を分ける必要があるから、class 定義の中にインラインメソッドを書け
ないケースもある。

それ以前に、本当にインライン展開する必要があるのか、プロファイラにかけて調べてみろと言いたいけど。
353観筒:02/01/12 12:05
>>345
 その書き方がOKなのは、inline関数の展開先が同じソースファイル内の
場合だけです。しかも、展開先は、定義の後にないといけません(だったはず)。
 つまり、定義時の(.cppファイルでの)inline指定は、クラス内でしか
呼び出さない関数(private関数です)だけで有効、と覚えておけば
いいのではないかと思います。
 クラス外部から呼び出される関数(public,protected関数です)を
inline展開したい場合は、ヘッダファイル内で関数本体を記述しないといけません。
コンパイラがinline展開をしようがないからです。
 >>322で定義時のinline指定を書いてるから参考にしてください。
354デフォルトの名無しさん:02/01/12 14:49
352,353
どうもです。
わかりました。
>>353
>つまり、定義時の(.cppファイルでの)inline指定は、クラス内でしか
>呼び出さない関数(private関数です)だけで有効、と覚えておけば
>いいのではないかと思います。

弊害が大きすぎるような。
VC++7(VC.NETやね)ではリンク時にコード生成(?)をすることができるらしい。
これを利用して、.cppに書いたコードのインライン展開ができるんだそうな。
357観筒:02/01/12 21:36
>>355
 どんな弊害があるんですか?
>>357
その説明だと private メソッドをインライン定義された public メソッドから呼び出す場合や、friend について
考慮してない。

それより、

「inline 関数は、それを利用する各々の翻訳単位に対して定義を与える必要がある」

と規格書っぽく言っておくのが正確かつ簡潔だと思う。ま、ヘッダに書いておけば確実ではある。
インラインの、のけぞるくらいステキな例。

ttp://www.geocities.co.jp/SiliconValley-Cupertino/7774/c/sub/chap12.html

calculator.h
>>359
ダメダメじゃん……。

top() で return NULL は間違いだし、スタックの overflow, underflow のチェックをカプセル化してないし、
pop() インターフェースは例外安全にしようがないし。
361観筒:02/01/12 23:32
>>358
 ああ。「語弊が大きい」と言いたかったのですね。「弊害が大きい」なんて
いわれるから、なんかとんでもない副作用が出るのかと心配しました。(^^;
 「語弊が大きい」ことに関しては、確かにおっしゃるとおりです。
362358 != 355:02/01/13 00:48
>>361
全然本題と関係ないが

 語弊=言葉の使い方が正しくないために生じる弊害

だぞ。弊害が大きいで何ら問題ないと思われ。
363デフォルトの名無しさん:02/01/13 17:56
>>331
> >Inside the C++ Object Model0
>  amazonで探したら、洋書しか出てこなかったんですが…。和訳されてないんですかね?
邦訳はトッパンから出ている「C++オブジェクトモデル」だと思うんだが、トッパン出版部門活動停止に伴い
入手できなくなってる。cbook24.com で調べたら「絶版」だそうだ。

私は原書で読んだけど英語自体は平易だったよ。C, C++, アセンブラに関してある程度の技術的背景があ
る人間なら、楽に読めると思われ。
364デフォルトの名無しさん:02/01/13 18:31
>>560

> top() で return NULL は間違いだし

正解は、例外を投げるって事ですか?
>>364
それ以前に

DATA_t top();

で return NULL はまずいんじゃ。

そもそも DATA_t の型によっては NULL からの暗黙の型変換ができないし、DATA_t が int としても「スタックトップ
に 0 が入っていたのか、それともスタックアンダーフローなのか」見分けがつかんよ。
366デフォルトの名無しさん:02/01/13 19:33
>>360>>365が言うように
push(),pop()のチェックになんでfull(),empty()を使わないの?とか、
pop()はスタックトップをもらえないの?
とか、なんでstackpos() がpublicなの?
とか、top()がNULL返すなよ、とか、いろいろツッコミ所あるけど、
CALCULATOR::Calculate(char *)みたら、そんなのふっとんじゃうよ、っていうのが俺の感覚。
>>366
pop() でスタックトップを持ってこないのは正しい設計だけど (STL の stack もそうなってる)、Calculate() が
そんなに珍しい? スタックを使って LL(1) の構文解析を行うのはコンパイラ理論の書籍を紐解けば必ず載っ
ている常套手段だし。
369デフォルトの名無しさん:02/01/14 05:19
>>367
そのCalculate()がヘッダに展開されてるの見て、なにも思わんか??
中身以前の問題だ。
370デフォルトの名無しさん:02/01/14 07:22
>>369
「ヘッダに展開」って、何? 結構長い関数だから、コンパイラがインライン化しない
可能性大だと思うんだが。こんな単にクラス宣言内に関数定義を書いただけの
何の変哲もない例をもってきて何がいいたいのかサパーリわからんが。
371デフォルトの名無しさん:02/01/14 07:27
>>370
いや、「何の変哲も無い」って思うなら、べつにいい。
あんたを説得するのが目的じゃないから。
>>370はJavaモノだろうな、クラス宣言内しか書けないのだ体に染みてるから、しかたあるまいって。
373デフォルトの名無しさん:02/01/14 07:42
>>371
おれも何を問題としてるのかさぱーりわからん。
ちゃんと説明すべし。
374  :02/01/14 07:45

VC++6.0とBorland C++Builder 5 どっちがおすすめですか?
宣言と定義を分離する意味がわからないやつには、サパーリわからんだろう。
わからんやつはヘッダに定義を全部押しこんどけ。
376デフォルトの名無しさん:02/01/14 08:59
>>359
stackクラス、サイズの違うのを作るとクラスが増えるのも、すごいかも。
まさか、最近のコンパイラは、こういうの最適化してくれるってこと、無いよね?
>>375
なんだそんなことか(プ
そんなに大騒ぎする程の事でもないよお。
378376:02/01/14 10:02
>>377
そんなに大騒ぎしたかな?
それよか、>>371の方が気になる…
379376:02/01/14 10:10
>>371
ヘッダに何でも押しこんじゃったら、実行ファイルでかくなるわ、
実装を書きなおしたら呼んでるファイル全部コンパイルだわ、
インライン展開してくれるのかどうか、処理系依存になるわ、
お互いに呼び合ってるクラス同士は定義できなくなるわで、
いいところ全然無いって思うけど、そういうのは最近、問題にはならんのか?
つか、そういう書き方推奨していいもんなのか?
少なくとも、「なんの変哲も無い」は、センス無さ杉だろうな。

まあ、やっちゃだめだろうな、こういうでかい関数を宣言にいれるの。

宿題見てあげるスレにも出てきたサイトだけど、大学の授業でこういうの教えてるのが、やっぱ、一番の問題かし。
>379はtemplateによるGenericProgrammingが耐えられないタイプ。
たとえば、donutのソースみて卒倒するタイプ。
381376:02/01/14 12:17
>>380
どんなソースだって、それが必要であれば納得するよ。
チミは、必要でなくても、何かのマネをして満足するタイプかに?
ハァ?
>いいところ全然無いって思うけど、そういうのは最近、問題にはならんのか?
>つか、そういう書き方推奨していいもんなのか?
への答えのつもりだが。
>>382
それは「ヘッダになんでも押しこんじゃったら」で始まる文なんだが…
もちろん、その文脈で書いてるが。
それ以外の文脈で評価できる、とでもいうのか?
>>384
「ヘッダになんでも押しこんじゃったら」で始まる文である以上、
無計画にそうする奴の話なんじゃないの?
>>379
ライブラリなんかだと template だと「使わない関数はそもそもコンパイルされない」から、逆にコンパクトに
なるかも。そうでなくとも、逐一 bridge パターンを使って実装を隠蔽したコードよりはコンパクトになるし、実
行時ではなくコンパイル時に実装を固定して良いのなら、インターフェースとして使う抽象クラスの数を減ら
すこともできる。

前に10000 行ぐらいのコードをお遊びで可能な限り template 化して、不要になった抽象クラスを削ってみ
たことがあるんだけど、VC6 のコンパイラオプション /O1 (ファイルサイズ優先) でコンパイルしてみたが

1) 6% ぐらい実行ファイルのサイズが小さくなった
2) 20% ぐらいソースコードの行数が減った
3) 実行速度は有意な差は得られず
4) エディット&コンティニューのプログラムデータベースが使えなくなり
5) 実質ひとつの .cpp から、実装込みのすべてのヘッダを include したので、一行書き直すとフルビルド
  が必要になった

ってな感じ。最近のマシンだと 10000 行ぐらいならフルビルドしても問題にならんから、中小規模のプロ
グラムなら、まぁ良いのかも。

> お互いに呼び合ってるクラス同士は定義できなくなるわで
これだけど「template 関数は実際に呼ばれるまで実体化されない」規則がある都合か、確か書き方に
よっては出来た気がする。こんな感じだったかな。

template <typename TController>
class CTaskKeyboard
{
public:
  CTaskKeyboard(const TController& con)
  {}
};

class CController
{
  typedef CTaskKeyboard<CContoller> TTaskKeyboard;
  boost::scoped_ptr<TTaskKeyboard> m_spTaskKeyboard;
  ...
};
387デフォルトの名無しさん:02/01/14 15:27
 今、各種画像フォーマットから、ベタ画像に展開したデータを保持する
クラスCGraphicを作ってます。で、その中で、画像をロードする関数は
下のような実装になってます。

bool CGraphic::Load(const string& FileName)
{
    if(LoadBMP(FileName) != ERROR) return OK;
    if(LoadPNG(FileName) != ERROR) return OK;
    if(LoadJPG(FileName) != ERROR) return OK;
    (中略)
    return ERROR;
}
 こんな感じで処理してたんですが、だんだんと各種ロード関数が
増えてきて手におえなくなってきました。加えて、動的にロード関数を
増減させたくもなりました。そこで、この各種ロード関数を
なんとか外部クラスにしたいのですが、下のようなダサい実装しか
思い付きません。

bool CGraphic::Load(const string& FileName)
{
    if(CBMP::Load(this,FileName) != ERROR) return OK;
    if(CJPG::Load(this,FileName) != ERROR) return OK;
    if(CPNG::Load(this,FileName) != ERROR) return OK;
    (中略)
    return ERROR;
}

 ロード関数にCGraphicのthisを渡さなくちゃならないところが、
すごくダサい気がします。しかも、ロード関数が増えるたびに
CGraphic::Loadも書き直してるから動的な増減は達成できてないし。
 「CGraphicクラス自体は変更しない」「CGraphicのthisはどこにも
渡さない」と言う条件で、ロード関数を自由に増やすための手段は
ないものでしょうか?(Strategyパターンでなんかいけそうな
気がしたんですけど、結局thisを渡す以外は思い付かなかった…)
388367:02/01/14 15:42
>>371
俺も分からん。解説頼む。
>>387
struct GraphicLoader
{
  virtual bool LoagGraphic(const string& FileName, GraphicBuf& buf) = 0;
};

みたいなインターフェースを用意してやって、

1. GraphicLoader を継承した JpegLoader, BitmapLoader, etc.. を用意する
2. CGraphic を構築
3. 1 で作ったクラスをインスタンス化して CGraphic に登録
4. CGraphic::Load は、登録された GraphicLoader を順次実行するだけ

とでもしておけば。これなら Loader 部分だけ DLL に切り出すとかも可能になるし。
390387:02/01/15 09:24
>>389
 StrategyパターンとIteratorパターンを合わせたやり方ですよね。
俺もそこまでは考え付いたんですよ。けど、それだと「thisを渡す」という
記述をしているのと、変わらないんですよね。
 何が言いたいのかって言うと、ロード関数がf(A,B)になるのを避けたいのです。
f(A,B)じゃなくて、A.f(B)にしたいな〜、と。
391387:02/01/15 12:24
 解決しましたっ!

http://www1.odn.ne.jp/synsyr/prog_cpp0.html

 に、いい方法が載ってました。

 CGpraphicから派生したクラスにロード関数を作らせて、
CGpraphicのstaticな登録リストに、そのロード関数ポインタを
登録する。CGpraphicのLoadは、

for(list<LOADFUNC>::iterator p=s_Func.begin();
    p != s_Func.end();++p){
        if((this->*p)(FileName) != ERROR) return OK;
}

って感じで、登録されたロード関数を順次使っていく。
 こうすれば、「CGraphicを変更しない」「CGraphicのthisをどこにも渡さない」
「ロード関数を動的に増減可能」を達成できます。
392デフォルトの名無しさん:02/01/15 18:18
PSエミュで音を鳴らす方法を教えてください。
ヒントだけでもいいです。
お願いします。
393デフォルトの名無しさん:02/01/15 18:36
学校の課題なんですが、、、
A,B,Cの行列が与えられていて、2A-3B+Cを計算するプログラムをつくれっていう問題なんですが。
サッパリわかりません。
どなたか教えてください。
>>391
>CGraphicのthisをどこにも渡さない
そっか、よかったね。
395デフォルトの名無しさん:02/01/15 19:26
>>366
> pop()はスタックトップをもらえないの?

例外安全って勉強しろよ。Exceptional C++でな。

>>360は、int pop();をスタックトップのデータ返すと勘違いしたな。
(まあ、今時アンダーフロー例外投げるだろうから無理もないが)
396デフォルトの名無しさん:02/01/15 19:39
>>395
>>366がどこまで考えてるかわからんが、俺はそもそもpop()って名前使うなって気がする。
>スタックトップのデータ返すと勘違いしたな。
な勘違いもわからないでもない。
inlineの話がこういうことになるのか、掲示板っておもしろいのお
398デフォルトの名無しさん:02/01/15 22:32
>>396
> 俺はそもそもpop()って名前使うなって気がする。

つーか、例外安全を勉強しろって。
STLがなんでvoid pop(void);なのかさ。
399デフォルトの名無しさん:02/01/15 22:56
>>398
スタックポインタずらすのとスタックトップを返すのを両方やると例外セーフを保証できないのは知ってるよ。
pop()がスタックトップをくれないならtop()とremoveTop()とかにすればええやんって話だ。
つーか「勉強しろ」だけ言ってないで、さわりだけでも説明すればいいのに…
> >>360は、int pop();をスタックトップのデータ返すと勘違いしたな
そのとおり。

> つーか「勉強しろ」だけ言ってないで、さわりだけでも説明すればいいのに…
じゃあ、俺が責任を持って。

T pop();

と pop() で値を返すと、T の型によっては「コピーコンストラクタの実行に失敗」して、例外が飛んでくる
可能性がある。その場合に、

 スタック内部のインデックス値は更新したのに
 pop したインスタンスをどこでも受け取れない

ということで、例外安全じゃなくなるわけだ。Exceptional C++ とか GotW で検索すると詳しい記事が見つかる
と思われ。
402デフォルトの名無しさん:02/01/15 23:28
すみません。教えてください。(ガイシュツならすみません。)
次のような簡単プログラムなんですが、

#include <iostream>
#include <string>
using namespace std;

int main()
{
string s;
getline(cin, s);
cout << s << endl;
}

getlineで何か文字列を入力してエンターを1度押すと、それが出力されると
思うのですが、VC++ではエンターを2回押さなければ出力になりません。
BorlandC++では、1回で出力になります。
これだけはっきりしているとバグレポートでもあるかとも思うのですが、どうも
わかりません。VCとBCどちらが正しいのでしょうか?
それとも私が何か勘違いしてるでしょうか?

よろしくお願いいたします。
>>399
そんな議論は10年近く前に終って、void pop(void);になった。
404デフォルトの名無しさん:02/01/15 23:51
>>402
ほんとだ。どうなってんだ?
399>>403
10年? まぁいい。
STLがvoid pop(void);を採用したことと、ワタシがスタックトップを返さないpop()がきらいなのは、どう関係が?
>>405
どうでもいい。もうその話題は終わってくれ。
407デフォルトの名無しさん:02/01/16 00:05
例外安全の話は、もっと聞きたいage
408デフォルトの名無しさん:02/01/16 00:05
for (wp = start; wp->next != NULL; wp = wp-> next)

(wpは変数)
どういう意味ですかね?
409デフォルトの名無しさん:02/01/16 00:08
>>402
Boarland C++が正しいです。cygwin/g++でももちろん一回。
>>408
連結リストで検索
411デフォルトの名無しさん:02/01/16 00:09
>>408 リンクリストを末端直前までたどるってことだろ?
何が聞きたいの?
>>402
VC+STLPortでは1回。
VCのライブラリが腐ってるに100まんこ。
413デフォルトの名無しさん:02/01/16 00:12
リンクリストって何ですか?今、勉強中の厨房ですみません。
>>413
google いけ
415デフォルトの名無しさん:02/01/16 00:16
>>413
1回、調べたんですけど良くわかりません。教えてください。
>>415
連結リストで検索すると、詳しいサイトがいくつか出てくるだろ? それを見ても分からないなら、
ここで聞いても分かるとは思えないので、諦めてください。
そうか、リンクって連結って意味もあるんだったな・・・

どうりで、リンカエラーを連結エラーでいってる奴がいるわけだ
連結エラーなんて始めて聞いた。そんな言葉聞いてもわからん。
スタティックリンク→性的連結
>>407

何でもかんでも例外安全がどうのと書かれてるとまた誤解を生むな。
再利用しないアプリケーションコードまでジェネリックにするこたあない。
ジェネリックにこだわるなら例外投げないオブジェクトの場合だけテンプレート
を特殊化したり特性ヒントを与えたりしてパフォーマンスを改善するとか
その辺まで言及しないと今時な感じがしない。
421デフォルトの名無しさん :02/01/16 02:00
C見習い中のものです。
ある関数の中で求めた値を
別のファイルの別の関数に渡すにはどうすればいいんでしょうか?
returnだと値は一つしか渡せないみたいだし、で息詰まっております。
>>421
スレ違い
C 言語スレで聞きましょう

(C++ だとデザインパターンが、とか言い出すぞ。俺が)
423デフォルトの名無しさん:02/01/16 02:05
構造体を return すれば?
>>420
任せた

Modern C++ Design ネタっぽい気がするが。
425弱気な名無しさん:02/01/16 02:08
あ、C++だったか。だったら
関数にデータをやりとりするんじゃなくて
データをいじる関数を追加するんです。
…違うかも
std::pair<int,int>とかで返すというやつだな。
TypeListがどうこう、って話だが。
>426
おぃおぃ,たしかに TypeList には pair 使ってるけど
ここでは TypeList は関係無いのでは・・・
# pair は確かに「複数 return」には使えるけど
なんでさ?複数returnするなら、typelistは必須やん。

Loki::tuple< TYPELIST_4(int,long,double,float> > somefunc( );
同じファイルの別の関数でも、構造体をreturnしたほうがいいとおもうな。
>>420
> 再利用しないアプリケーションコードまでジェネリックにするこたあない。

「ジェネリック」→「例外安全」という意味か? それなら、この後の文章は冗長では。
人には大げさだと言っておいて、自分はもっと過激な事を同じレスの中で言う。
知識ひけらかし君か?
>「ジェネリック」→「例外安全」という意味
んなわきゃない。
じぇねりっく、ってのは、型に対して汎用性がある、っちゅう意味さね。
誤解を恐れず云えば、templateつかう、ちゅうことさね。
>>431
今、俎上にあがってるのはスタックだから じぇねりっく にするのは妥当と思われ。
そういえば結局 >>371 は何だったんだろう。単なる勘違い?

(それならそうと書いて欲しかったけど。どうせ名無しさんなんだから、恥かくわけでもなし)
>>390
>  何が言いたいのかって言うと、ロード関数がf(A,B)になるのを避けたいのです。
> f(A,B)じゃなくて、A.f(B)にしたいな〜、と。
これって、何が嬉しいの?

個人的には CGraphic と個別の画像フォーマット対応ローダクラスの間に、継承という「むちゃくちゃ強力な」
関係を持ってしまうからイマイチなデザインという気がするんが、見落としてる利点があるなら教えて欲しい。
>>431
じゃあ、なんで「例外安全」から「ジェネリック」に話変わってるのだろう。
>>420の1行目から、2行目で。
435371:02/01/16 05:44
CALCULATOR::Calculate(char *)がヘッダに入ってるのにびっくりしたっていうのが、言いたかったこと。
ヘッダに入れる理由が思いつかない。
でも、これが「なんの変哲も無い」っていわれたら、あとは、言うことないよ。
pop()については、STLがvoid pop()なの知らなかった。俺の感覚が古かったんだね。

こんなんで、いいですか?

っていうか、話があっち行っちゃったのに、なんでいまさら呼ばれるの?
436デフォルトの名無しさん:02/01/16 05:47
>>432

スタックの話というか、わけのわかんないインライン関数のサンプルの
例で皆が混乱したのが発端?

>>434

そこで、>>401の説明が
>T pop();
> と pop() で値を返すと、T の型によっては「コピーコンストラクタの実行に失敗」して、例外
> が飛んでくる
> 可能性がある。その場合に、

という説明だったから、>>420のような話になったのでわ。
>>436
いや、その>>401の説明は、inlineには全く関係ないが、
>>366に対する、pop()が要素を返さない理由としては全く正しい。
438421:02/01/16 08:06
pairとかTypeListって持ってる本に載ってないので
構造体を使うことにしました。
早速試してるんですけど、なぜかエラーが・・・。
構造体の変数をreturnで返す関数の型はstructでいいんですよね?
struct関数のtypeに対してエラーが出てしまいます。
どうすればよいのでしょう?
関数の戻り値の型には、構造体の名前も書いてる?
>>437
http://www.geocities.co.jp/SiliconValley-Cupertino/7774/c/cpphtml/calculator_h.html
のは、確かにテンプレートではあるが、スタックの中身にせいぜい組み込み型か
そのバリエーションしか入れないっぽいので、わざわざ例外安全を持ち出して
くるまでもない気はする。脇が甘いと突っ込まれればそれまでなんだけどね(藁
>>393
大学の課題だとはいえ、計算の内容は高校2年レベルの算数だぜ。
たぶん高校の授業で代数学を選択しなかったから行列を難しいと
思うんだろうけど、いくらなんでも簡単すぎ。

「2a-3b+c」と「2d-3e+f」と…を計算するプログラム、なんて、
どこをどう悩めばいいんだろうか。
442387:02/01/16 11:22
>>433
>>  何が言いたいのかって言うと、ロード関数がf(A,B)になるのを避けたいのです。
>> f(A,B)じゃなくて、A.f(B)にしたいな〜、と。
>これって、何が嬉しいの?
 C++のオブジェクト志向らしい記述が出来るのが嬉しいのです。

>個人的には CGraphic と個別の画像フォーマット対応ローダクラスの間に、
>継承という「むちゃくちゃ強力な」関係を持ってしまうからイマイチなデザイン
>という気がするんが、見落としてる利点があるなら教えて欲しい。
 見落としてる利点は特にないと思います。ただ、A.f(B)なのをf(A,B)にして
「継承ではない」としたところで、CGraphicと一緒に提供せざるを得ない以上、
CGraphicの構成要素であるのは同じですから。「強力な関係」であることに
変わりはありません(この根拠はExceptional C++の項目32)。つまり、
どちらにしても特に利点や欠点はありません。
 ですから、後は記述スタイルの好みで、A.f(B)ができる方法を探してたのです。
>>392
意外にも誰もレスしてやらんので俺が・・・

ゲ製作技術板に逝け。

                            以上
>>442
俺なら

1. 画像データ格納用のバッファクラスを用意して、CGraphic に集約。それを Loader 側に提供する
2. 画像データ操作用の手続きをまとめた抽象クラスを用意し、CGraphic はそれを継承。Loader には
  抽象クラスのインターフェースを提供する。

とするかなぁ。

> CGraphicの構成要素である
こうやって、CGraphic 自身とインターフェースを分離する。一例だけど。
445Ruby厨な人(802):02/01/16 18:37
いまだにC++だってさ。 ヴァカ炸裂(ぷっ
このプログラムをVC++6.0sp5、bcc5.5.1、mingw g++2.95.3-5
でコンパイルして実行すると
VC: ABC4E6G\n
bcc: ABCDEFG4
g++: ABCDEFG\n
となりました。main()4行目のseekpの指定のやり方がいけないのでしょうか。

#include <iostream>
#include <strstream>
#include <Iomanip>
using namespace std;
int main(void)
{
   char ch[130];
   strstream cStrStrm (ch, 128, ios::out);
   cStrStrm << "ABCDEFG" << endl << ends;
   cStrStrm.seekp(-(128 - 7 + 2), ios::end);
   cStrStrm << '6';
   cStrStrm.seekp(-3, ios::cur);
   cStrStrm << '4';
   cout << ch;
   return 0;
}
>>444
CGraphic に仕様変更が入った場合に、個別の画像対応の Loader をコンパイルしなおす必要があるかを
考えれば、どっちが良いかは言うまでもない。

そもそも >>391 の方法だと

 派生クラスは Is-A 関係を満たしてるのか?

という疑問がある。this を渡さないで済むというのは、継承によって暗黙の this が一致しているからだし、
それが OO 的なコードってわけでもない。Exceptional C++ 持ってるみたいだから、項目 24 を読み返すと
得るものがあると思うよ。
>>446自己レス
実験したところ
mingw g++2.95.3-5の場合std::ios::endはstd::ios::curと同じ
bcc5.5.1の場合std::ios::endは終端文字のある場所からの移動
clの場合std::ios::endはstd::strstreamのコンストラクタの第2引数
みたいでした。
もうしかして同じコンパイラでもライブラリのバージョンが違うと
std::ios::endは違う結果になるのでしょうかね。
449デフォルトの名無しさん :02/01/16 20:17
息詰まってますのでよろしくお願いします。

例えば
main(){
function1(a,b);
function2(b,c);
}

main(){
function1(a,b);
}

main(){
function2(b,c);
}
で変数Cの値の結果が違ってくるのはどういう理由なんでしょう?
a,b,cは整数型の二次元配列です。
デバッグすると後の方はきちんとbの値が渡されてるんですけど、
最初のはbがfunction2でおかしな値になってしまって渡されてるみたいなんです。
255が66になってたり。わけわかりません。
わかる方お願いします。
450デフォルトの名無しさん:02/01/16 20:19
>449
a,b,c の型を書いたほうがよいとオモワレ。
>>449
省略しすぎ、せめて各関数のプロトタイプと
呼び出し側の変数宣言&初期化くらい書けよ。
452デフォルトの名無しさん:02/01/16 20:20
プログラムはあまり詳しくないのですが
3ケタの数字をランダムに0.3秒間隔で10回表示させる
プログラムはどう記述したらよいでしょうか?
わかりやすく言うと次々と現れる3ケタの数字を記憶するゲームを
作りたいと思っています。
最後に答えを表示できれば完璧なのですが。
わかる方いらっしゃいましたら、ご教授よろしくお願いします。
>>452
プラットホーム依存。

Win32 なら SetTimer() とか見てみるといいと思われ。
454387:02/01/17 00:11
>>444
>1. 画像データ格納用のバッファクラスを用意して、CGraphic に集約。それを Loader 側に提供する
>2. 画像データ操作用の手続きをまとめた抽象クラスを用意し、CGraphic はそれを継承。Loader には
>  抽象クラスのインターフェースを提供する。
 じっくり、じっくり、じっくり考えました。
 考えに考えて、結局、どこにも異議申立てできる部分がない、と言う結論に達しました。
1.で提案されたデザインにしようと思います。

>>447
 言われたとおり、Exceptional C++ の項目24をじっくり読み返してみます。

 あー、前回「オブジェクト志向」って書いちゃってる…。恥ずかスィ。
455デフォルトの名無しさん:02/01/17 00:46
>>454
447は2.がいいって言ってるんじゃないの。その辺はどうなん?
456デフォルトの名無しさん:02/01/17 00:49
初歩的な質問なのですが
Visual C++
C++
Bacic
などいろいろあり、どれがどう違うのかさっぱりわかりません。
プログラミングを勉強し始めるとしたら、どれから覚えていったほうが
よいのでしょうか?
457デフォルトの名無しさん:02/01/17 00:53
Ruby!
>>456
Visual C++はC++の開発環境、というか商品名。
勉強ならとりあえずCが無難だろうが、スレ的にはC++勧めんと駄目かな。
というか激しくスレ違いだ。
459デフォルトの名無しさん:02/01/17 00:59
>456
VisualC++は、Microsoftが出してるC++っていうだけ。
どの言語から始めたほうがいいかは目的によって違う。
460447:02/01/17 01:16
>>455
私は 1 が良いか 2 が良いかは、もうちょい詳細な設計見てみないと良く分からんです。
>>456
まず英語から覚えましょう。
462デフォルトの名無しさん:02/01/17 03:17
質問があります。
GameProgrammingGemsの自動シングルトンユーティリティ
というところを読んだのですが…。

int offset=(int)(T*)1-(int)(Singleton<T>*)(T*)1;
ってところがよくわかりませんでした…。
Singletonクラスのthisから、
派生したTクラスのthisを求めてるみたいなんですが。
なぜキャストするだけでoffsetが出てくるのか…?

うーん。。いまいち良く分かってないんですけど、
良かったら教えてほしいです。。。
多重継承してるのでは?
とりあえず、ソースくらいはろうや。
http://www.cs.utah.edu/~justino/cs3500/doxygen/Singleton_8h-source.html
で、class Sample , class test2, Singleton<Sample>とか適用するわけやな。
|test2   |
|singleton |
|sample  |
メモリイメージはこんな感じか。sample, test2ではthisは
このメモリの先頭を指してるわけ(sampleはtest2、singleton
両方しっているから、問題にならない)。
test2*からsingleton*にキャストする場合、singletonはtest2
なんかしらへんから、この位置補正が当然あるわけや。
せやから、キャストでポインタがずれる。おわかりか?
>>464
細かいことだけど、 SampleとSingleton<Sample>のあいだに
test2が挟まってるから、そのぶんずれるってことだよね?
>465
class Sample : class test2, Singleton<Sample> {...};
の書き間違いで、その通り。
ところで
これシングルトンになるの?
468467:02/01/17 04:34
すいません、僕がバカでした。
実行時にエラーになるのね。
469469:02/01/17 08:21
C++暦1ヶ月の消防です,よろしくお願いします

template <typename T = double>
class hogehoge
{
---
}

とクラステンプレートにデフォルトの型を定義していますが
このクラスのオブジェクトを作るときに

hogehoge<> hogeobj;

と "<>" をつけなくてはいけないのが非常に面倒です
デフォルトの型でいい場合には "<>" を省略できるように
する方法はないでしょうか?
470469:02/01/17 08:24
例えば別の名前のクラス hoge2 に
hogehoge<> と同等の機能をもたせて

hoge2 hogeobj;

とすることはできませんでしょうか
class hogeDefault : public hogehofe<>{} ;
ってのは、ど?
typedef hogehoge<> hoge2;
じゃいかんのか。
#define hoge2 hogehoge<>
でもええやん。
474473:02/01/17 08:39
あ、おそ、しかもカコワル
475469:02/01/17 08:57
素早いレスありがとうございます^^

ところでどれが一番よさそうですか^^;
typedef が一番
今まで Java と C# で遊んでいたのですが、
漢はやっぱり C++ だろ!と思い立ち、今更ながらに C++ を勉強している者です。

で、ちょっと質問なのですが、いままで
「 共通のスーパークラスを継承しているクラスを多重継承すると、
オーバーライドしないメンバーは、どれが呼び出されるかわからない」
んだと思っていたのですが、これって継承の度合い
(っていうのかな? public 継承とか protected 継承とか)
を使えば実は済む話なのでしょうか?

Java厨でありC#厨でもある私は、
幼少の頃から、多重継承=悪 と教えられて育ったのですが
本当に必要な場合は多重継承もアリなのかなぁ…とか
微妙に思い始めています。どうなんでしょうか?
478387:02/01/17 09:21
>>455
 実は2.の設計はよくわからないのです。(^^;「Loader には抽象クラスのインターフェースを
提供する」って、どういうことなんでしょう? ローダークラスは、抽象クラスを
private継承するってことでしょうか?
 >>444さん、よければ解説お願いします。
479デフォルトの名無しさん:02/01/17 09:25
>>477
仮想継承つかえ

480456:02/01/17 10:29
>>458-459-461
レスありがとうございます。
目的は画像処理などのソフトウェアを作りたいと考えています。
いろいろ種類があるみたいで、どれから手をつけてよいのか
わかりませんでした。兄が「Visual Studio 6」を持っているので
C++から始めてみようとも思っています。やはり参考書は必要でしょうか?
>>480
そのまえに、VisualStudio6のライセンスが必要でしょう。
つか、うそでも自分で買ったって家。
482ぱふーん ◆BEVSNet2 :02/01/17 12:04
>多重継承=悪

メソッド名がかぶるような多重継承は悪というか
頭をかかえるだろうけど、どういう理由で悪とされているか
知っておくべきよ。単なる教条主義に陥るから。
多重継承を上手に活用しているクラスライブラリも
あるけど、それは少数派で、ほとんどは多重継承で
ふりまわされるから、悪としとけ、ってなってると思う
483456:02/01/17 13:04
>>481
「ライセンス必要」というのはどういう意味でしょうか?

>つか、うそでも自分で買ったって家。
スミマセン。そういうものでしたか。
兄の物では駄目ということですね。
>>478
良いクラス名が思いつかなくて鬱なんだけど、たとえばこんな感じ。

struct IGraphicBuffer
{
  virtual void WriteRawData(char *data, size_t size) = 0;
};

struct IGraphicLoader
{
  virtual bool Load(IGraphicBuffer& obj, const string& file) = 0;
};

class CGraphic : public IGraphicBuffer
{
  vector<IGraphicLoader*> m_pLoaders;
  typedef vector<IGraphicLoader*> TLoaderIterator;

  // こいつは public でも private でも、好きなように
  void WriteRawData(char *data, size_t size);

public:
  bool LoadGraphic(const string& file)
  {
    for (TLoaderIterator i = m_pLoaders.begin(); i != m_pLoaders.end(); ++i)
      if (i->Load(*this, file))
        return true;
    return false;
  }
};

class CBitmapLoader : public IGraphicLoader
{
  bool Load(IGraphicBuffer& obj, const string& file);
};

Concrete Loader に対して CGraphicLoader 自身ではなく、CGraphicLoader の内で公開したいメソッド
だけまとめた IGraphicBuffer を渡しておくのがミソ。

IGraphicBuffer, IGraphicLoader はがっちり結びつくけど、実装である CGraphic, CBitmapLoader
の間は公開インターフェースを通してのみの緩い結びつきになる。こうしておけばインターフェース
を変えない限りは CGraphic, CBitmapLoader は独立に拡張できるのが利点。

事例
 XXX という画像フォーマットでは、最終的に必要なデータのサイズがファイルを最後まで読んでみ
 ないと分からない。でも、とりあえず読めた分から CGraphic のバッファに書き込んでしまいたい。
 (たとえばブラウザの画像表示に使うとかの理由で)

 そこで、CXXXLoader にはバッファサイズを最初に確定する IGraphicLoader ではなく、バッファに
 追加書き込みが出来る IGraphicLoader2 という別のインターフェースを提供する必要がある

みたいな要求が出てきたときに、その IGraphicLoader2 を CGraphic に実装して CXXXLoader に公開
すれば、これまでの Loader には一切影響を与えずに済むでしょ。
485デフォルトの名無しさん:02/01/17 19:21
for(int s=0; s<4; s++){
for(int t=s+1; t<5; t++){
if(test[t] > test[s]){
int tmp = test[t];
test[t] = test[s];
test[s] = tmp;
で、
for(int t=s+1; t<5; t++){
のt=s+1; の所をt=1;にするとなぜだめなのでしょうか?
486晒しage:02/01/17 20:49
>>485
> なぜだめなのでしょうか?
シ・ル・カ・ヨ!
“目的”と“求める結果”と“現状”ぐらい書け!
>>485
0-sまでの要素は、すでにソート済みだから。
あと、t==sのときは、並べ替えの必要無いよね。
>>477
> 「 共通のスーパークラスを継承しているクラスを多重継承すると、
> オーバーライドしないメンバーは、どれが呼び出されるかわからない」

具体的にコード書いてくれると理解の助けになるんだけど。
class A{
public:
 f():
};
class B:public A{};
class C:public A{};
class D:public B,public C{};
D d;
d.f();
こんな場合だとエラーです。
d.B::f(); とか書けば良かったかと思いまふ。
それか仮想継承するとか。

仮想継承しても
class A{
public:
 virtual f():
};
class B:virtual public A{
public:
 virtual f();
};
class C:virtual public A{
0public:
 virtual f();
};
class D:public B,public C{};
これはエラーかと。Dの中で改めて f(); を定義すれば良し。

> 幼少の頃から、多重継承=悪 と教えられて育ったのですが
> 本当に必要な場合は多重継承もアリなのかなぁ…とか

本当に必要な場合はね。
489462:02/01/17 22:42
レスどうもです。
ええと、、継承関係のある型同士でのキャストでは、
そのずれを調節してくれる…ということであってますか?

あと、メモリ配置はインスタンス毎ですべて同じなのでしょうか?
コードでは、0x1にある仮想のオブジェクトからoffsetを求めていますよね。
offsetは一定じゃないとうまくいかないかと…。
メモリ配置がインスタンス毎に違ったら、メンバ関数は
うまく機能しないのでは、とかおもいませんかね?
>>489
多重継承じゃないと、ずれないけどね。
それから、0やNULLをキャストしてもだめだじょ。
492デフォルトの名無しさん:02/01/17 23:52
みなさんは無限ループを使うとき
for(;;)とwhile(1)とwhile(true)のどれを使っていますか?
>>492
for (;;)

他の形式だと

 条件文が定数です

とか警告出るのが鬱陶しいから。
494デフォルトの名無しさん:02/01/18 00:01
>>493
どんなコンパイラ使ってんのよ?
うちでは最大レベルの警告でも出ないよ
ふつうはfor(;;)だと思うよ。
whileだといちいちチェックする可能性があるから。
496デフォルトの名無しさん:02/01/18 00:56
while(1)のチェックがパフォーマンスに影響するような場面は、そんなに無いだろうな。
つか、定数との比較がパイプライン乱すようなコード吐くコンパイラつかうな。

おれは自分一人で書いてるならwhile(1)、同じプロジェクトにfor(;;)使う人がいればfor(;;)を使う。
494は紙!
498デフォルトの名無しさん:02/01/18 01:11
なんの為にコピーコンストラクタが
あるのか分かりません。
必要なものですかね?
どなたか、どんな時に必要なのか教えてくださいませんか?
>>498
コピーコンストラクタを private で宣言してみ。どこで使われてるか分かるから。
>>498
一例、コンストラクタでリソースを確保しデストラクタで解放するようなクラス。
コピーコンストラクタが無いと単純なビットコピーとなり、デストラクタで二重解放が起きる。
つーか、本読め。
Giko a;  <-デフォルトコンストラクタ
Giko b = a;  <-コピーコンストラクタ
b = a;  <-代入演算子
>>501 追記
Giko b(a); <-コピーコンストラクタ
Giko b[3]={
 Giko(1),
 Giko(2),
 Giko(3),
} <-デフォルトコンストラクタ
>>502
どうせなら return とか throw の例も書いたほうが。
えっと質問です。
あるクラス Base を継承した Sub クラスを作りました。
また別に、同じく Base を継承した SubKitajima クラスを作りました。

プログラム中で
Base へのポインタを宣言して、
状況によって Sub か SubKitajima のインスタンスを生成するように
しました。

で、このインスタンスを削除しようとしたのですが…。
delete した時に呼び出されるのは Base のデストラクタだけでした。

この場合、Base へのポインタを通して、正しく Sub か SubKitajima の
デストラクタを呼び出すにはどうしたらいいのでしょうか?
よろしくお願いします。
>>504
デストラクタを仮想関数にする。
>>495
可能性はあるだろうが・・・しないだろうな、普通は。
>>493
同意。
>>489
ええと、488の例でCのメソッドを呼ぶときは、必要に応じてアドレスをずらしたthisを渡すはずです。
仮想継承の場合は良く知らんのでパス。
506504:02/01/18 07:19
>>505
うまくいきました。
ありがとうございますー。
507506:02/01/18 07:38
うまくいったと思ったのですが…。
ひとつちょっと疑問が…。

デストラクタは純粋仮想関数にできないのでしょうか?コンパイルは通ったのですが、リンカが「外部シンボルが見つからない」と
言ってくるのですが。
>>506
基底クラスのデストラクタはきちんと実行される必要があるので純粋仮想関数にはできないよ。
509387:02/01/18 09:07
>>484
 うーん。そういう実装なんでしたら、やっぱり1.の方がいいようです。
俺が考えた1.の設計の具体案はこうです。

// IGraphicBuffer.h
class IGraphicBuffer
{
    // グラフィックバッファ(実装は省略)
}

// CBitmapLoader.h
class IGraphicBuffer;// 前方宣言
class CBitmapLoader
{
public:
    static bool Load(IGraphicBuffer&,const string&);
}

// CGraphic.h
class IGraphicBuffer;// 前方宣言
typedef bool (*LOADFUNC)(IGraphicBuffer&,const string&);
class CGraphic
{
public:
    CGraphic();
    static vector<LOADFUNC> m_pLoaders;
    bool Load(cosnt string&);
private:
    auto_ptr<IGraphicBuffer> m_pBuffer;// バッファ本体
}

// CGraphic.cpp
#include "IGraphicBuffer.h"
CGraphic::CGraphic :
    m_pBuffer(new IGraphicBuffer)
{
}
bool CGraphic::Load(cosnt string&)
{
    for (vector<LOADFUNC>::iterator i = m_pLoaders.begin(); i != m_pLoaders.end(); ++i)
        if ((*i)(*m_pBuffer,file))
            return true;
    return false;
}

 関数ポインタの取り扱いだけはちょっと不安がありますが。その問題点を除けば、
仮想関数も継承も不要で、クラス依存性は極めて小さくなります。
 特に、メインルーチンで動的にローダー登録を行うところでは、
CGraphic.hとCBitmapLoader.hをincludeして、

CGraphic::m_pLoaders.push_back(CBitmapLoader::Load);

 と書くことになりますが、この書き方だと、IGraphicBufferを変更しても、
このメインルーチンをコンパイルし直さなくてもすみます(よね?)。
 と、ここまで依存性を減らせるとわかったから、さすがに「thisを渡さないで」
などとワガママいってる場合じゃないなと思って、1.の設計でいこう、と
決めました。これ以上の設計って、なにかあります?
 ところで、>>478ではtypedefをクラス内で行ってますけど、
そう記述すると、そのtypedefはクラス内だけで有効なんですかね?
510デフォルトの名無しさん:02/01/18 10:56
>デストラクタは純粋仮想関数にできないのでしょうか?

できませんよ。ていうか、そうする必然性ってあるの?
511デフォルトの名無しさん:02/01/18 10:58
VC6.0のSTLで質問です。
STLを使うと、MSVCP60.DLL が必要なんですか?
自分の開発マシンでは当然Systemフォルダに入ってるんですが、
入ってない人もいた。
XpとかMeあたりだと初期状態であるんですかね?
512デフォルトの名無しさん:02/01/18 11:24
先生方、教えてください。
テンプレートクラスのメンバ関数ポインタを保持することは可能でしょうか?
「オブジェクトに付随した形式のメンバー関数のポインタを取り出そうとしている」と
エラーが出たのですが、回避する方法は無いものかと。
513日下部圭子 ◆ib749tYo :02/01/18 11:27
In article >>510, デフォルト名無しさん/510 wrote:

> >デストラクタは純粋仮想関数にできないのでしょうか?
> できませんよ。

VC++6では、デストラクタも純粋仮想関数にできるようです。
これはVC++6の仕様がおかしいのでしょうか?

----------------------------------
||//
(@_@) Kusakabe Keiko
----------------------------------
>>511
ランタイムライブラリをスタティックリンクにすれば
MSVC*.DLLは不要です。
ただしヒープが共有できないので、DLL/EXE間でSTL
オブジェクトの受け渡しは事実上不可能になります。
単体のEXEなら問題ない。
515511:02/01/18 12:12
>>511
ということはコード生成で、使用するランタイムライブラリが
マルチスレッド(DLL)だと駄目ってこと?
516ぱふーん ◆BEVSNet2 :02/01/18 12:40
>>510,513
「C++ FAQ」のFAQ21.13を参照すべし

class Base {
public:
virtual ~Base() throw() = 0;
}

inline Base::~Base() throw() { }

とinlineの併用でできるらしい。
なんや、ようわからんけど
517デフォルトの名無しさん:02/01/18 13:01
>>515
マルチスレッドか否かは関係ないです。
/MD ならMSVC*.DLLが必要
/MT や /ML なら不要
ということ。
518462:02/01/18 13:08
ありがとうございました。
もう少し考えてみます。。
>>516
抽象クラスを作りたいんだが、どうしても純粋仮想関数にするメソッドが見当たらない場合に
使うことはある。
>>509
その設計だと CBitmapLoader::Load は static メソッドになるの?
521387:02/01/18 16:13
>>520
 そうです。CBitmapLoader::Load は、ファイルネームを受け取って、
IGraphicBufferのオブジェクトに適切なデータを格納するだけですから。
端的に言うと、strcpy(Dest,Src)みたいな機能ですので、staticです。
>>521
そこで設計のトレードオフが発生してるわけだ。

ローダに柔軟性を求めないなら、それで良いんじゃない。
523C++消防:02/01/18 16:28
こんなこと可能でしょうか?

template <typename T1>
class hoge
{
---
hoge<T1> &operator *= (???);
}

emplate <typename T1, typename T2>
hoge<T1> &hoge<T1>::operator *= (T2 &hogehoge) // 行列×=複素数
{
---
}

用はオーバーロード*=の引数に別のテンプレートを使いたいのですが
この場合???のところ(というかテンプレートクラス全体)を
どのように書けば実装できますか?

あるいは不可能なのでしょうか...
524C++消防:02/01/18 16:29
あ,コメント文消すの忘れた

鬱山車嚢
525C++消防:02/01/18 16:34
しかも
用→要
UTUDASINOU

template <typename T1>
class hoge
{
---
 template<typename T2>
 hoge<T1> &operator *= (T2 &rhs)
 {
  ....
 }
};

ではあきまへんか?
527387:02/01/18 17:42
 CGraphic::Loadではiteratorを使っている以上、関数の柔軟性に
関しては>>484>>521も同じではないんですか? トレードオフには
なってないと思いますけど…。
528C++消防:02/01/18 17:50
>>526
ありがとうございます,やってみます.
いや、staticになっているのがトレードオフじゃねーの?
インスタンスがとれないなら、Cの関数と変わらない、つーか。

>>527
まぁ設計は

 こちらをたてれば
  あちらがただず

で、何を重視するかで選択が違ってくる。後々を考えると >>484>>521 には差が出てくる場合がある
けど、それが重要ではない(少なくとも現時点で利用法を考えたときに差が見えない)なら、キミの用途
にとっては、どちらも OK ってことだと思うよ。

いずれにせよ、事前の設計で 100% 完全なものを見通すのは難しいから、そろそろ実装に移って良いと
思うよ。設計ミスが判明したら、その時点で何が悪かったのか良く考えて設計しなおし、ってことを何度
かやる内に身体にバランス感覚が染み付く。
531387:02/01/18 18:16
>>529
 そうはいっても、>>484のロード関数だって、機能的には
static同然ですよ。やってる内容はstrcpy(Dest,Src)です。
ただ、仮想関数のオーバーライドだからstatic宣言できないだけで。
むしろ、実体のないインスタンスを生成する無駄があるのでは…?

 あれ、いや、俺、なんか勘違いしてますかね?
> そうはいっても、>>484のロード関数だって、機能的には
>static同然ですよ。やってる内容はstrcpy(Dest,Src)です。
 だからといってクラスメソッドにすると、ロードオブジェクトとして、
何か変数/状態を持ちたい、とかに対応でなくなるだろう。
そこがトレードオフなわけよ。
 530が言ってるとおり、その「ロード関数」がstrcpy(Dest,Src)同然
の事しかしないから、387はそれが有利なトレードと判断したんだろう?
533387:02/01/18 19:03
>>532
 な・る・ほ・ど〜。ものすごく納得できました。ありがとうございます。

 とりあえず、>>530さんの忠告どおり、そろそろ実装に入ります。
>>387から、長長とお付き合いありがとうございました。

 お礼と言っては何ですが、マ版のオナペットスレに、俺のお気に入りの
高画質フリーアダルトムービーのアドレスを書いておきますね。
>>533
>  お礼と言っては何ですが
個人的にはその手の画像より、ソースコードの方が萌えます(ぉ
535デフォルトの名無しさん:02/01/18 19:54
>>519
> >>516
> 抽象クラスを作りたいんだが、どうしても純粋仮想関数にするメソッドが見当たらない場合に
> 使うことはある。
純粋仮想関数にする面罵関数は無いけど抽象クラスである必要があるケースってどんなでしょう?
単純に興味本位の質問です。

基底クラスの実体を作らせたくなかったら構築子を protected にすればすむし…
基底クラスのポインタで一元管理し、必要に応じて dynamic_cast したい?
>>513
> > >デストラクタは純粋仮想関数にできないのでしょうか?
> > できませんよ。
>
> VC++6では、デストラクタも純粋仮想関数にできるようです。
> これはVC++6の仕様がおかしいのでしょうか?
おかしいのは“あんたの”VC++6か、あんたの文章読解能力だろ(w

デストラクタが純粋仮想関数のクラスも定義はできる。
それを継承したクラスの実体を生成しようとすると、
リンクエラーとなる、って話を507はしてんだろ?


…513のHNを見ると、刺々しいレスを付けたくなるよう(笑
>>535
仮想関数はあるが、純粋仮想関数にするものが無い場合と思われ。
インタアフエイスには、純粋仮想関数がよく似合ふ
>>537
それは“抽象クラスを作りたい”理由にはならないのでは?
> 抽象クラスを作りたいんだが、どうしても純粋仮想関数に
> するメソッドが見当たらない場合に使うことはある。
邪悪な設計ですね。
541519:02/01/18 21:07
>>535
> 基底クラスの実体を作らせたくなかったら構築子を protected にすればすむし…
そう書く代わりにデストラクタを純粋仮想にする、ってだけ。
542:02/01/18 22:10
諸君あけおめことよろ。なんて。
ようやくMore Exceptional C++を読み始めたわけなのですが
例の、Effective STLでは保証されていると断言されているのに
標準には見あたらないvectorのメモリレイアウトのことですが
This was fixed in 2001 as part of Technical Corrigendum #1
to the C++ standard.だそうです。よかったね。
Schemeに夢中なのでレビューは一ヶ月後かも。
543507:02/01/18 22:16
うわ、日中みないうちにたくさんの方にレスして貰ってる…。
みなさんありがとうございます。

実は Java のコードを C++ に移植していた所で、
Java の interface にあたるクラスを作ろうとしていた所でした。

というわけで、ベースクラスのデストラクタで、特に処理する事は
なかったのです。
こういう場合は、デストラクタが必要なサブクラスの為に
空っぽの仮想デストラクタを定義するといいみたいですね。

みなさんありがとうございました。
>>507
純粋仮想として宣言できますが、しかし実装も書かないとダメです。
>>544
実装があったら純粋仮想関数ではなく仮想関数
=0 が付いてたら純粋仮想だろ?実装があっても。
>>546
試して理解しました
知らんかったのよ
純粋仮想関数として定義しつつ実装もするって手法
許して
548デフォルト:02/01/19 03:03
MFC+VCで質問です。
ダイアログボックスベースのプログラムで
自分で作ったほかのクラスから
一番上のウインドウハンドル
m_hWndを得るにはどうしたら良いでしょう?
CxxDlg::GetSafeHandle
したり
CxxDlg::m_hWnd
したり
よくわからないままいろいろしてるのですが、どれもうまくいきません。
初心者カキコです。すまんです。

>>548
すれ違い。こっちで聞いて。

■ VisualC++(MFC限定)相談室 2■
http://pc.2ch.net/test/read.cgi/tech/1008031675/
550デフォルト:02/01/19 03:21
>549
すみません。そっちにいきます
551C++消防:02/01/19 08:32
任意の型,任意の数の引数を受ける関数を作りたいのですが
va_arg を使うためには予め型を知っている必要がありますよね.

"%d %f" のような型情報を一緒に送れば確かにできますが
これ無しで組むことは可能でしょうか?

typeidを使ってごちゃごちゃやってみたんですが
なかなかうまくいきません...鬱鬱
>551
まず,本当にそういう関数が必要なのか自分自身に問い詰めろ
小一時間問い詰めろ
話はそれからだ
553C++消防:02/01/19 09:13
n次元ベクトルがそれぞれ型の違う複数の要素を持つとします.
その要素をファイル出力する場合に

要素1[1] 要素2[1] 要素3[1] ...
要素1[2] 要素2[2] 要素3[2] ...
要素1[3] 要素2[3] 要素3[3] ...

と表示したいのですが,出力したい要素の並び,内容が
頻繁に変わるので,一々型を指定しなくてもよくなれば
楽になるかと思ったのですが...
554デフォルトの名無しさん:02/01/19 09:27
型情報と格納メモリをさすポインタをいれた構造体をつくれば何とかなるでしょ
わからんな。一個づつ std::cout << vect[k][i] ;
とかすればいいのではないのか?
556C++消防:02/01/19 09:43
>>554
なるほど,そんな手がありますか

>>555
fileout("ファイル名", vector<T1> a, vector<T2> b ...);
(T1, T2, T3は型が違う)

と書けば
a[1] b[1]...
a[2] b[2]...
.
.
.

の内容のファイルが自動的に生成されるような関数を作りたいのです.
557デフォルトの名無しさん:02/01/19 09:48
解決法が無い訳じゃないと思うが(templateを使いまくれば…)
その前に設計を考え直した方がいいと思う。
だから、なんで、
class fileout{
fileout(const string &filename)
operator ()( T hoge )
}
for_each( a.begin(), a.end(), fileout( "filename" ) )
for_each( b.begin(), b.end(), fileout( "filename" ) )
みたいにしないわけ?
560C++消防:02/01/19 10:20
>>558
出力がExcelで見やすいように「列」に並べたいのですが
その場合,同じ型の要素が「行」で並びませんか?
消防なもので意図がうまくつかめなくてすいません.
どーでもいいけど配列インデックスは 0 から書こうぜ
>>560
だったら「列」で並ぶような配置の vector を持てば良いでは無いか.
563C++消防:02/01/19 10:53
>>561
確かに.

>>562
いえ,vector自体には列も行もなくって次元の情報しかありません.
問題はファイル出力のときに

a[1] b[1]...
a[2] b[2]...
...

となるか

a[1] a[2]...
b[1] b[2]...
...

となるかです.

564デフォルトの名無しさん:02/01/19 11:04
>>563
んあ?
> vector自体には列も行もなくって
で,
> 同じ型の要素が「行」で並ぶ
んなら,列で並べるのに何の苦があるんだ?
行と列の区別無いんだろ?
インデックス値をちょっとイヂるだけじゃねーのか?

ちょっとデータ構造をきちんと書いた方がいいと思われ

for( int i=0; i<N; i++ )
{
print_dat( fp,a[i] );
print_dat( fp,b[i] );
print_dat( fp,c[i] );
...
}
と並べていくのは嫌だ、という話か?
566C++消防:02/01/19 11:17
えーと...

>>565
だと

a[1] a[2]...
b[1] b[2]...
...

となってしまいますよね?

a[1] b[1]...
a[2] b[2]...
...
のように表示したいのですが.
ならねーよ。よくかんがえてみろ。
print_datは一回に一つしか表示しない。
print_dat(fp,z[i]);のあとに、
print_dat(fp,"\n");でも入れれば判るか?
>>565 じゃないけど,>>565 のやり方なら後者になると思うが.
569568:02/01/19 11:31
シマッタ、カブッタ・・・ウツシ
>>566
>>565 だと、
a[1] b[1]...
a[2] b[2]...
...
になると思われ。

でもさ、要するに、
a は A 型、 b は B 型、 c は C 型のベクターだとするわな。
そうすると、
a[1] b[1]...
a[2] b[2]...
...
っていう風に並べたいときって普通は、
struct Tuple
{
A a; B b; C c;
};
ostream& operator<< (ostream& os, Tuple tupple)
{
os << tupple.a << " " << tupple.b << " " << tupple.c;
return os;
}
って構造体作って、Tuple 型のベクター使わんか?
571C++消防:02/01/19 11:37
>>567
御手数おかけします.
おそらく言わんとしていることがわかりました.
要は,行が変わる度にファイルポインタを行の最後に
持って来ればいいんですね?
要素が変わった場合はまたポインタを一番前に戻すと.

確かに行の最後の位置をインデックス配列に保存すれば
ポインタをいじる方がよっぽど簡単ですね.
572C++消防:02/01/19 11:41
>>570
ファイルアウトしたい要素が頻繁に変わるので
(又,後々何度も使いそうなので)
struct Tuple を書き直すよりも引数で指定できれば楽かなと思いました.
(また見当違いなことを言っているかもしれないです)

ファイルポインタはいぢっていないよーな・・・
じゃさ。これだったらわかるか?
for( int i=0; i<N; i++ )
{
std::cout
  << a[i] << ", "
  << b[i] << ", "
  << c[i] << "\n";
}
ああ、今回はデリミタはなしだが
575C++消防:02/01/19 12:04
>>574
Fileout関数を一つのソースの中で複数の場所から呼んでいます.
しかも型情報も引数の数もNの値も違います.となるとファイル出力の度に
for(...) {
...
}
を書く必要がありますよね.そこを簡単に
Fileout("ファイル名", vector<T1> v1,vector<T2> v2..);
とすればNの値を N = v1.GetDimension() で取得して
書き出すようにしたかったんです.
template< class T, class U , class V, class W,class X,class Y,class Z >
Fileout( const char *s, T& t, U &u, V &v, W &w, X &x, Y &y, Z&z )
{
}
でもツカットケ。
さすがに576は不親切だった。反省している。
class EmptyClass {};

template< class T, class U=EmptyClass , class V=EmptyClass, class W=EmptyClass,class X=EmptyClass,class Y=EmptyClass,class Z=EmptyClass >
class Fileout{
public:
 Fileout(const char *s){}
 operator ()( T* t, U *u = NULL, V *v = NULL, W *w = NULL, X *x = NULL, Y *y= NULL, Z *z = NULL)
 {   int N = t->dimension(); for(...) }
};

int main()
{
 int a, b ,c;
 Fileout<int,int,int> fo( "tmp" );
 fo( &a, &b, &c );
}

こんなところでどうよ?
578C++消防:02/01/19 12:29
なるほど,ありがとうございます.
引数はせいぜい4〜5個なので十分間に合います.
579デフォルトの名無しさん:02/01/19 18:44
けつが痛い
質問させてください。
下のプログラムで(*2)のようにインスタンスを生成しようとすると
VC++6ではコンパイル時にエラーが出ます。(*1)がなければ大丈夫です。
この例自体にはあんまり意味はないんですが少し気になったので・・・。
どなたか理由判りませんか?

class Foo {
public:
 template<typename T> class HogeBase; // (*1)これがあると駄目らしい
 template<typename T> class HogeBase {}
 typedef HogeBase<int> Hoge;
};

int main()
{
Foo::Hoge hoge; // (*2)
return 0;
}

--
http://pc.2ch.net/test/read.cgi/tech/1010673275/412-
>>580
そりゃ、VC++の template の実装があまいから。
メンバテンプレートの使えないし。
582511:02/01/20 13:16
>>511

MSVCP60.DLLを自分のアプリと一緒に配布してもOK?
インストーラは使わないで、ZIPで配布です。
>>582
redist.txt
584デフォルトの名無しさん:02/01/20 13:35
テンプレートの明示的特別化と
部分特別化の違いがよくわかんないです。
どこがどのように違うのでしょうか?
585デフォルトの名無しさん:02/01/20 20:26
squidのログのように、各エントリが可変長で、なおかつ全体をメモリにロードできない
ぐらい巨大なものをソートするには、どんなアルゴリズムを使えばいいのでしょうか。
データにランダムアクセスできないのでほとんどのソートアルゴリズムは使えませんよね。

586デフォルトの名無しさん:02/01/20 20:37
>>585
なんだかアルゴリズムの教科書に出てきそうな問いだな。

マージソートでいいんじゃないの?
>>585
マージソート

たしか 4.4BSD 系の sort って、必要に応じてテンポラリファイルを作ってマージソート
してたような気がする。
588580:02/01/21 12:35
>>581
どうもありがとう。
VisualC++が悪いということで納得しました。
ちょっとWindows依存な質問なんですが、
勉強がてらに API だけでお手製クラスライブラリを作ろうと思っています。

で、しょっぱなでいきなりつまづいています。
「Windowsクラス」というのを作って、メッセージの処理をこちらで
やろうと思ったのですが、ウィンドウプロシージャで、どの「Windowクラス」に
メッセージがきた事を伝えればいいのかわかりません。
メッセージループの処理をしているクラスに hWnd の管理テーブルを作って
それで判断するしかないでしょうか?
>>589
それを自分で考えるのが勉強ではないの。ATLのソースでも読めば?
591589:02/01/21 15:48
SetWindowLong の GWL_USERDATA に this 入れておけばよかったんですね。
とりあえず自己解決です。ありがとうございました。
592590:02/01/21 15:48
ATL->WTL
593591:02/01/21 15:49
と思ったら直前にヒント貰ってたみたいですね。
ありがとうございました>>590
>>592
いや、そこは ATL で良い。興味があるなら CWindowImpl あたりから読み進めましょう。
>>584
なんらかの形でテンプレート引数が残っているのが
partial specialization ってだけじゃないの?
テンプレート引数が空になったのが完全な (明示的な?)
specialization

596デフォルトの名無しさん:02/01/22 01:51
void printfunc(vector<class elemtype> vec, string str)
{
vector<elemtype>::iterator it = vec.begin(), end_it = vec.end();
cout << str;
for (; it != end_it; ++ it) cout << *it << ' ' << endl;
}
このようにvectorクラスをパラメータに渡す関数を作りたいのですが、
vectorの中身がどのような型か分かっていないとパラメータとしては
渡せないのでしょうか?
今の状態だとエラーが沢山でて何のことか分かりません。
template< class T >
void printfunc(T &vec, string str)
{
T::iterator it = vec.begin(), end_it = vec.end();
cout << str;
for (; it != end_it; ++ it) cout << *it << ' ' << endl;
}
598デフォルトの名無しさん:02/01/22 01:57
>>596

#include <iostream>
#include <vector>
#include <string>
using namespace std;

template<typename T>
void printfunc(const vector<T> &vec, const string &str)
{
vector<T>::const_iterator it = vec.begin(), end_it = vec.end();
cout << str;
for (; it != end_it; ++ it) cout << *it << ' ' << endl;
}

main()
{
vector<int> A;
A.push_back(17);
A.push_back(18);
printfunc(A, "test:\n");
}
>>597-598
めちゃんこありがとうございます。
関数、またはクラスをテンプレートにするんですね。
なんか使い方が少し分かってきました。
見習ってよく勉強したいとおもいます。
ありがとうございました。
600デフォルトの名無しさん:02/01/22 02:38
g++ 2.95.3だと
T::iterator it = vec.begin(), end_it = vec.end();

typename T::iterator it = vec.begin(), end_it = vec.end();
って書かないとだめなんだけど、誰か解説プリーズ
601巨額詐欺:02/01/22 02:48


巨額詐欺の疑いのある、グローバリーについて

掲示板を拝見されてるの皆様、新年あけましておめでとうございます。
掲示板の趣旨とは直接関係ない話で申し訳ないのですが、この世の中では許せない事があります。

http://www.max.hi-ho.ne.jp/sakimono/index.htm

この会社はありもしない儲け話をでっち上げ、巧みに客の財産を聞き出し、全財産を巻き上げます。

2002年になりましたが、一向に改善する気配すらなく、悪質化は進む一方です。
この会社の営業は世間の皆様の迷惑になっています。

それだけではなく、人を騙して破産に追い込み、騙された人が仕方なくグローバリー社員を
殺人する事件も実際に発生し、新聞ザタになっています。

http://www.mainichi.co.jp/news/selection/archive/200001/24/0124e038-400.html

みなさんもこちらの掲示板に投稿し、悪徳会社に騙される不幸な人が増えないようご協力お願いしま
す。


http://messages.yahoo.co.jp/bbs?action=q&board=8745

また、この書き込みを見て賛同頂ける方はこの内容をコピーしていろんな掲示板に書き込みをお願いします。


>>600
そりゃ、例えば、↓みたいに iterator が型でない可能性があるから。
型であるということを明示しないと駄目。

class Type
{
public
int iterator; // iterator が型じゃない
}

template< class T >
void printfunc(T &vec, string str)
{
T::iterator it = vec.begin(), end_it = vec.end();
cout << str;
for (; it != end_it; ++ it) cout << *it << ' ' << endl;
}

int main()
{
Type t;
printfunc(t, "");
return 0;
}
603596:02/01/22 03:27
ちなみにg++-2.95.4を使っているんですが、
typename T::iterator it,end_it;
it = vec.begin();
end_it = vec.end();
このように2行に分けて書かないとエラーが出るのは仕様なんでしょうか?
604596:02/01/22 04:00
あとそれから、
関数テンプレートというのは皆さんあまり使わないのでしょうか?
クラスをテンプレート化するほうがスマートだと言う感じですか?
上のものは標準入出力を使った関数を少しだけ(デバッグ用に)
テンプレート化しただけですが、これにしてもスーパークラスに
おいて持ってしまえば、関数においてテンプレートにしておく
必要もないですよね?

C++が手続き指向のプログラミングも出来るというメリットの
ためにあるんですよね?
605596:02/01/22 04:04
質問バッカですんません。Java房なんてテンプレートに
感動してる最中なもんで(^^;(早くJavaにもテンプレートを!)
606デフォルトの名無しさん:02/01/22 04:31
>>604
<algorithm>
>596
きみのやりたいことは、関数化しなくても、
std::cout << str;
std::copy( vec.begin(), vec.end(), std::ostream_iterator( std::cout, " \n") );
でやれたはず。
608596:02/01/22 04:56
>>606-607
どうもです。
今C++Primerのサンプルコードのみで勉強していますw。
本を持っていないので推測だけで勉強してるのですが、
なかなか思うようには理解が進みません(あたりまえか!?)
今度C++Primerの訳書を買ってちゃんと勉強し直します。

>>606
container type
algorithm type
iterator type
この三つの組み合わせがどうもイメージ出来ないんですよね。難しいです。

>>607
これがSTLですか。
これはC++におけるCの標準関数みたいなものになるのでしょうか?

はやいとこC++覚えてServlet作りまくりの毎日から脱出したいです・・・
609606:02/01/22 05:10
>>608
>これがSTLですか。
それは標準アルゴリズムでSTLじゃないよ
ていうか596のJava風引数渡しが、597の回答でさりげなく参照渡し
へ変更されているのにウケタ
610596:02/01/22 05:27
>>609他、みなさん。
今日はこんな夜中にいろいろとありがとうございました。
これ以上はチョット恥かしいのでもう書きませんw。
スレ汚して済みませんでした。
>>609
<algorithm> は、STL の一部だと思うが
612596:02/01/22 08:01
603の書き込みは嘘でした。
typename T::iterator it=vec.begin(),it_end=vec.end();
としたところ、g++の2.95.4、3.03ともにOK。
何か別のエラーと勘違いしていたようです。
ごめんなさい>g++
613609:02/01/22 10:21
>>611
スマソその通り。
>これはC++におけるCの標準関数みたいなものになるのでしょうか?
に対してC++におけるCの標準関数はCスタイルアルゴリズムなんだ! とボケた方がよかった(w
>>612にならって、>>609書き込み前半は嘘でした。
ごめんなさい>596
614596:02/01/23 01:59
C++Primer原書を4000円でげっとー、あげ
615デフォルトの名無しさん:02/01/23 02:13
あるデータを格納するのに
DWORD *num = new DWORD[100];
として使ってるんですけどデータが1桁だったら勿体ないし
100を越える可能性もあるから問題がありますし、、
こういった場合スマートな方法は何ですか?
>>615
std::vector
617デフォルトの名無しさん:02/01/23 02:46
>>616
ありがとうございます。
これは便利だからといって使いすぎると速度が
低下してしまうかな?
>617
サイズ変更しまくらない限り心配無用だと思われ
# egcs とか古いコンパイラだと遅かったりもするけど
>>617
大量のデータを突っ込むことが事前にわかってるなら reserve() しとくと良いよ。
>>617 色んな型で定義しなければそれほど気にしなくてもいい


しかし >>615 の話なら 単に

入力処理では可能性のある最大桁を取っておいて、
 入力処理の帰り値では そのサイズだけの領域を確保 それにコピー

という手法が適切だろう。 


まあ、最近ならそういうのはデータベースアクセスに置き換えてしまうとか
621デフォルトの名無しさん:02/01/23 11:14
すみません厨な質問だと思いますが
new 演算子でクラスの配列を割り当てるときは
コンストラクタに引数を渡す事はできないんですか?
622デフォルトの名無しさん:02/01/23 11:39
new Cls[10](30);
とかじゃダメ?
>622
それだとコンパイルとおらんよ
624デフォルトの名無しさん:02/01/23 11:56
>>623
g++だとこれでもOKみたいなんです。

勉強始めたバッカなので、
個別にコンストラクタへの
パラメータの設定する方法、
自分も知りたいです。
すまん
VC6だと
とおらんかった
ポインタの配列つくって
いっこずつnewは
627621:02/01/23 12:02
>>621 です
今は VC++6.0 でやってます。MSDNや入門書など
見てるのですがどうにもわからないです。
イメージとしてはまさしく >>622さんの書かれたような事を
したいんです。
基本は >>626 だと思うけどね。
どうしても delete Cls[] したいのであれば、初期化用の関数作るとか?
でもかえって手間になるので氏労徒にはお勧めできない。
629621:02/01/23 12:45
>>628 さん
はい、今までは 初期化用の関数作って間に合わせていました。
しかし、もしもインスタンス作成後に初期化関数を呼びだすのを忘れると
値の割り当てられていない変数への不正なアクセスを許してしまうのは
OOPL的にいかがなものか、と氏労徒なりに思ってしまって。
自分で使う分にはいいんですが。ドキュメントしっかり書いておけばいいと
いうことででしょうか。
でも >>626 さんのやり方が基本なんですね。やってみます。
ありがとうでした。
630デフォルトの名無しさん:02/01/23 13:09
誰かこの本を読んだ方はいらっしゃいますか?
【C++ Network Programming Volume 1】
http://www.amazon.co.jp/exec/obidos/ASIN/0201604647/
631デフォルトの名無しさん:02/01/25 04:46
>>630
読んでないけど目次見る限りACEの解説書だね。ACE使ってクロス
プラットフォーム開発って魅力的な気もするけど実際どの程度
使われてるんだろう。ちなみに俺は乗り気じゃありません。
632デフォルトの名無しさん:02/01/25 05:04
>>631
それかなりでかいライブラリだから気合入れて
調べないとわからなそう。おれも前から
試してみたいとは思ってたけど。。
http://www.cs.wustl.edu/~schmidt/ACE-overview.html

これだけの機能が必要になるケースじゃ
Javaでもつかった方がよさそうな感じかもね。
633HWND:02/01/25 05:37
ハンドルは16進数みたいだけど、ハンドルを文字列として
取得することは可能ですか?
>>633
16進数と10進数の違いは?
635デフォルトの名無しさん:02/01/25 05:57
>>633
forとかで、if(Handoru==総当り)とかするしかないんじゃない?
>>633
文字列って、どういう表現を期待してるんだ? ハンドルの値を取得したいなら
DWORD あたりにキャストして sprintf() で拾えるだろうし、その HWND に関連
付けられたウィンドウのタイトルなら GetWindowText() だろう。

っつか HWND の話なら、ここではなく VC++ スレに行きましょう。
637デフォルトの名無しさん:02/01/25 06:57
>>636
DWORD あたりにキャストして sprintf() では拾えない。
ハンドルを文字列で得るには総当りでしか無理だったはずです。
638HWND:02/01/25 07:19
>>635
総当たりじゃ使いものになりません。要するに無理なんですね。
ありがとうございました。
ハンドルを文字列として取得するという意味がわからん
640デフォルトの名無しさん:02/01/25 08:07
ハァ?
ウィンドウハンドルを指す文字列ったらHWNDをsprintfした奴だよな普通。
ていうかそれ以外ってなに?
>>633=638はネタ|アフォとして、
おれは>>637の考えを聞きたい。
(゚д゚) ハァ?
次逝ってみよう次
>>642
同意。総当たりって何を総当たり? 謎だ。
646教えて君:02/01/26 01:59
カンマで区切られたデータ「TN-620,192,168,1,100」(初期値で与えられる)から文字列を切り出して表示する
項目1:TN-620
項目2:192
項目3:168
項目4:1
項目5:100

言ってる事から何をすんのかもサパーリです。教えてください
ってな質問はここでいいのだろうか
わたしもサパーリです。
648デフォルトの名無しさん:02/01/26 11:12
>>646
で、私たちは何をすればいいんでしょうか。
サパーリです。#宿題なら宿題スレに行ってね。
ミギャアアアアアア!
C++!
C++!
ミギャアアアアアアアアアア!!
教えて欲しいのですが、
二つのクラスがお互いを使っているとき、コンパイルできないのです。

-------- ファイル ClassA.h --------
#ifndef CLASSA_WAS_INCLUDED
#define CLASSA_WAS_INCLUDED
#include "ClassB.h"
class ClassA{
 public:
  ClassB* getClassB();
};
#endif

-------- ファイル ClassB.h --------
#ifndef CLASSB_WAS_INCLUDED
#define CLASSB_WAS_INCLUDED
#include "ClassA.h"
class ClassB{
 public:
  ClassA* getClassA();
};

#endif

こんな場合です。お互い相手の名前が出てきた所でコンパイルエラーです。
こういう時はどうしたらいいのでしょうか?
ちなみに使っているコンパイラは Borland C++ 5.5 です。
(が、できれば汎用的なお返事をいただけるとうれしいです。)
よろしくお願いいたします。
651:02/01/26 17:13
>650
ClassCでも作れよ(w
>>>650
前方宣言
653650:02/01/26 17:44
>>652
クラスにも前方参照って必要なんですね。
C を弄っていた頃はちゃんと(関数の宣言を)書いていたんですが、
最近すっかり Java に慣れてしまったもので忘れていました。
ありがとうございました。

参照
http://black.sakura.ne.jp/~third/cpp23.html
654デフォルトの名無しさん:02/01/27 07:34
std::stringstream のEOFの場所を手前にずらしたいときはどうすればいいですか?
つまり、
std::string s("0123456789");
s.erase(1);
をstringstreamでやりたいのです。
ss.str(ss.str().erase(1));
はどうですか?効率は?
やっとvirtualの使い方がわかった気がした…
C++が楽しくなった瞬間だった(w
657デフォルトの名無しさん:02/01/28 08:53
template<class T> class c
{
private:
static T s;
};

template<class T> T c<T>::s;

の最後の行ってなにをしてるのですか?
vc6の標準ライブラリの iosfwd の class fpos のところにあったのですが。
staticメンバの定義
掘って掘って
ようやく一番下まで掘り進んだとおもったら
さらにその下に巨大な地下帝国があった。
>>658
static T s;
だけではダメナンデスカ?
テンプレートをつかっておろうが
template<class T> class c
{
//private:
public:
static T s;
};

//template<class T> T c<T>::s;

main() {
int i = c<int>::s;
char ch = c<char>::s
}

でコンパイルもリンクもできたのですが、なにかまずい状況が
あるのですか?

663661:02/01/28 09:53
すいませんごめんなさいリンクできてませんでしたテンプレートはあくまで
テンプレートで実体を持っていないので宣言がいるということでしょうかでは逝きます
664662=663:02/01/28 09:54
すいませんごめんなさい名前をまちがえました
sに代入できたか?
sの値を表示できたか?
おそかった
すまぬ
Effective STL 訳本発売 age
くそっ
669 :02/01/28 17:36
>668
ん?洋書買ったばっかとかそーゆーコト?
またよまなきゃいけない本がふえちった。
金ねーっつーの
すいません、ちょっと質問。
メンバー関数として、「関数ポインタ」を返す関数ってどうやって定義したら
いいのでしょうか?
>>671
別の型にキャストしてから渡しちゃう
とか、
構造体に入れて渡しちゃう
とか。
class A{
 (void(*)()) f();
};
こんな感じ?ちなみに「メンバー関数ポインタ」を返す関数のことなら
(void(A::*)()) f();
って感じ。
デストラクタでは例外を投げないよう気を付けませう。
ある一定の期間内だけ有効になる変数の扱いってどうしてますか?
class Class{
int a;
int b;
void A( int _a, int _b ){ a = _a; b = _b; B(); C()}
void B(){ if (a==b) ...; }
void C(){ ...; }
};

↑のa,bみたいな場合。
この例のようにメンバ変数にすると、その変数が有効じゃないときにアクセスしてしまう可能性がありますよね。
BやCの引数に渡してやればOKですけど、数が多くなると問題ですよね。
a,bを格納するインナークラスを作ってそれを引数にして渡してやれば数が多くても大丈夫ですが、
ある一定期間だけのためにクラスを新設するのはなんだかもったいない(謎)気がします。

インナークラスを作るのが一番スマートな気がしますが・・・皆さんはどうでしょう?
age忘れた
>>675
>その変数が有効じゃないときにアクセス

どういう意味? コンストラクタで初期化してないとか? それにしては
インナークラス云々がわかんないんだけど。
678デフォルトの名無しさん:02/01/31 09:25
>変数が有効じゃないときにアクセスしてしまう可能性がありますよね。
あるのか(w

まああんまり使わないなら比較的長い名前にしておけば?
679 :02/01/31 12:58
>675
漏れもそれ意味分かんない
680675:02/01/31 14:24
>>677

> どういう意味? コンストラクタで初期化してないとか?

コンストラクトされた時点では値が不明なときです。
MFCのCDCなどのm_hDCのような物です(ただしもっと一時的です。Perlで言うlocalな変数です)。
m_hDCはどこから参照するかわかりませんからメンバ変数にしてありますが、それを使用するところでは必ずその値をチェックしなければいけません。

で、実際にはそういう変数がまとめて5個くらいあって、
それを使用する関数、というか使用してもよい関数が10個くらいです。
それらの関数すべてにその引数を渡すのは効率的じゃないです。

一つのクラス(構造体といったほうが伝わりやすい?)にまとめて、そのオブジェクトのアドレスを渡すようにするべきかな?

結局トレードオフの問題で、私が決めるべきことですが、皆さんはこういうときどうしているのでしょうか?
あるいはもっとスマートな方法があるのでしょうか。

> >変数が有効じゃないときにアクセスしてしまう可能性がありますよね。
> あるのか(w

一人で使う分にはないです。
>>680
>それを使用するところでは必ずその値をチェックしなければいけません。

ならその変数をメンバ変数に持つかその変数から継承したクラスを作って
そのクラスのオブジェクトにアクセスするときはそのクラスが公開してる
インターフェイスでアクセスするようにすれば。で、そのインターフェイ
スは内部で値のチェックをやってると。要するにラッパ。
つーか例をもっと詳しくしてくれ。
>MFCのCDCなどのm_hDCのような物です(ただしもっと一時的です。Perlで言うlocalな変数です)。
も意味不明だ。
682675:02/01/31 17:51
>>681

特定の関数内からしかアクセスできない変数を考えています。
(↑=特定の関数どうしで変数を共有したい、とも言い換えられます。)
コンパイル時に、できればそれ以外の関数内でその変数を参照していたらはじきたいので、メンバ変数というのはちょっと使いたくありません。

> >MFCのCDCなどのm_hDCのような物です(ただしもっと一時的です。Perlで言うlocalな変数です)。
> も意味不明だ。

Perlのlocal変数はわれながらいいたとえだと思ったのに。(;´Д`)

ま、いいや、やっぱりインナークラス作ることにします。
もし私の説明が解読できてしかももっといい方法を知ってる人がいたらよろしくお願いします。
>>682
> Perlのlocal変数はわれながらいいたとえだと思ったのに。(;´Д`)
もしかして動的変数スコープを使いたいって話? それは C++ では無理だ。

知らない人のために補足しておくと、Perl5 はデフォルトで変数は全てグローバル、my
で宣言するとブロック内有効な静的スコープを持ち、local 宣言すると動的スコープを
持つようになります。(local 宣言したときに値を保存しておいて、スコープを抜けるときに
値を復元する)
> 特定の関数内からしかアクセスできない変数を考えています。
> (↑=特定の関数どうしで変数を共有したい、とも言い換えられます。)

>ま、いいや、やっぱりインナークラス作ることにします。
の関係がよくわからんが、その変数を何かのクラスでくるんで、
関数を friend にしてやれば?

>>683
次のコードで、my と local の違いが分かるね。

$x = 1;
foo();
print $x,"\n";

sub foo() {
# my($x)
local($x);
$x = 2;
print $x,",";
bar();
}
sub bar() {
print $x,",";
}

結果は、local のときが 2,2,1 で、my のときが 2,1,1, になります。

686681:02/02/01 05:23
>>682
>特定の関数内からしかアクセスできない変数を考えています。
>(↑=特定の関数どうしで変数を共有したい、とも言い換えられます。)

それを文字通りに「特定の関数内からしかアクセスできないメモリ =
クラスオブジェクトのprivate宣言されたメンバデータ」
って回答しかない。コンパイル時に弾くにはこれしかないね。
で、それをクラス間にまたがって行うには>>684の言うように
friendしかないと。

>Perlのlocal変数はわれながらいいたとえだと思ったのに。(;´Д`)

Perlのlocalがグローバルシンボルテーブルを一時的に上書きするのと
C++で「特定の関数で値を共有する」というのとでは意味も前提もまる
っきり違う。グローバルな特殊変数に基づいた振る舞いをするサブルー
チンの振る舞いを変更したいときにlocal宣言で特殊変数を一時上書きして
やったりするが、そういうシンボルベースの動的な振る舞いとMFCがラップ
したm_hDCのようなvolatile(システムによって非同期に変更される)な変数
の扱いとは全く別で、だから意味不明と書いた。
C++で同じシンボルで振る舞いを変更するには、参照の参照先を付け替える
かメソッドをオーバーライドするかしかない。
687デフォルトの名無しさん:02/02/01 05:42
More Exceptinal C++読み終わりましたが
絶対買いだとは言えないかも。
例外についてはMoreなしの方で言い終わっていた的な。
文字列クラスの実装の話の方が多いし。
688デフォルトの名無しさん:02/02/01 06:28
継承していないクラスのコンストラクタにおいて
class XXX{
public:
  XXX():yyy(),zzz(){
    return;
}
このような表記があるのですが、
これって何をしているのでしょうか?
自分の理解では親クラスのコンストラクタに
パラメータを渡していると思っていたのですが、
どうも違うみたいです。よく分かりません。
教えてください。
>>688
メンバ変数の初期化デス。
>>689
こういった書き方も出来るんですね。
初めて知りました。どうもです。
691デフォルトの名無しさん:02/02/01 08:12
>>689
一つ思ったんですが、
どうしてこんな書き方が必要なんですか?
クラスのコンストラクタにおいて、
渡されたメンバ変数を使って初期化すれば
いいだけの話に思えるのですが。
もし問題となるケースがあるとするならば
コンストラクタの実行順序ですが、
これだけが上のような表記が必要な理由ですか?
692デフォルトの名無しさん:02/02/01 08:13
×:渡されたメンバ変数を使って初期化
○:渡されたパラメータを使ってメンバ変数を初期化
メンバがconstだったりリファレンスだったり
する場合の初期化
>>693
今見ているソースではconstでもリファレンスでも
ないのに先のような表記になってます。
これは勘違いということになるんでしょうかね?
private:
 ZZZ zzz;
 YYY yyy;
こんなかんじです。意味無しですか?
>>691
> コンストラクタの実行順序
これは初期化リストの書き方によらず、常にメンバ変数の定義順になる。
殺気から色々と教えてくれてありがとうございます。
>>695
メンバの初期化の順序は処理系依存ではなく言語仕様なんですね。
よーく頭に叩き込んでおきます。
>>694

コンストラクタをポインタなどを介さずに直接呼び出すにはその記法が唯一な気がするのだが

たとえば

class hoge {
std::vector<int> vi;
public:
hoge(int n): vi(n) {}
//...
};

とか.

そうしないと

hoge(int n) { vi.resize(n); }

とかにするしかないような.
うぉー、ありがとうございます!!
もう>>697さん大好き!惚れました!!(´ε`)チュッ

確かにそうですね。上のような感じだと、
パラメータを渡してメンバ変数を初期化するには
そのような書き方しかないですね。
resizeに相当するようなメソッドがないクラスは
その方法しかありません。勘違いしてました。
>>697
そもそも、デフォルトコンストラクタを持たないクラスの場合には、書かないと
コンパイル通らないしね。
>>698

もっとも,この場合には

hoge(int n) { vi = std::vector<int>(n); }

とできるけどね.

結局,初期化と代入とを区別するための記法だね.
701デフォルトの名無しさん:02/02/01 14:40
それだとコンストラクタが2回と代入演算子が使われるのでは?
でも例えばコンストラクタ用の例外構文をコンパイラがサポートしてない場合とかは
このように書くしかないと思う
703675:02/02/01 15:29
>>684

使用する関数が継承等で増える可能性もあるのでfriend指定は出来ません。
関数をオーバーライドするときにクラスも新しく派生させればいいですけれど。

>>686

m_hDCとlocalが同じとは書いていません。

m_hDCの値はオブジェクトが作成されて破壊または分離されるまでの間でのみ有効ですよね。
(オブジェクトが生成される前に、生成に成功したかどうかをm_hDCの値から判断する処理をしても無意味です。)
有効範囲という意味で、m_hDCのような値が常に有効とは限らない変数。

しかしm_hDCほど寿命は長くなく、もっと一時的に、ある関数が呼ばれている間のみ、意味を持つ変数はみなさんどうするかなぁと。
Perlのlocal変数と同じようなことはメンバ変数を使った最初のやり方で出来ています。
しかしPerlのlocal変数同様特定の関数からのみ呼ばれることを期待して書いたとき、ほかの場所から呼ばれた場合に問題がでます。

で、それへの対応策が必要な変数をすべて引数へ渡すこと、さらにそれをクラスにまとめることです。
こうすればどこから呼ばれても、引数さえちゃんと渡されていれば問題なく動きます。
メンバ変数の無駄遣いもなくなりますが、クラスが1つ増えます。
704683:02/02/01 15:44
>>703
> m_hDCとlocalが同じとは書いていません。
書き方が悪すぎ、に一票。
705にゃお:02/02/01 16:24
Windows 9x において現在接続されている HDD / CD-ROM / IDE コントローラ
などのハードウェア名情報はどのように取得すればよいのでしょうか?
レジストリエディタで検索してみると当然みつかりますが、環境によって場所が違うようです。
706 :02/02/01 16:41
>705
そーゆープラットフォーム依存の話は他当たった方が良いと思われ
707にゃお:02/02/01 16:46
>706
ごっ、ごめんなさい。どーもスレチガイだったようで・・・
Windowsプログラムの話題をやってるところに投稿するべきですね。
708デフォルトの名無しさん:02/02/01 21:45
g++2.95用のリンカでコンパイルした
ライブラリはg++3.03でリンクすることは
できないのでしょうか?
VD++6.0でClistBoxを使っているのですが、
リストを選択した状態でエンターを押した時に
エディットボックスに、選択状態のリストの文字列を送ってやりたいのですが、
リストの項目番号を取得することもエンターを検出することも出来ません。

どうやったらいいのでしょうか?


>>708-709
処理系のスレへどうぞ
>>703
……ようやくあなたの言っている意味が分かった。しかし、
「書き方が悪すぎ」に、もう一票だな。
で、あらためて >>675 に戻るが、コンパイル時にチェックしたいなら、
引数で渡すしかない。実行時の assert によるチェックでよいなら、
変数をポインタにするという手はある。ふだんは NULL のままだけど、
関数 A() の中で有効なポインタを設定する。
それよりも設計を見直して、変数a, b と関数 B(), C() だけをまとめた
クラスを考えたほうがよいと思う。
712デフォルトの名無しさん :02/02/02 17:27
ハンドルされていない例外があります。
stack overflowとか出るんですけど、どうしたらいいですか?
節約しなさい、スタック。
C++って、全ての基底クラス?っていうのかな
MFCでいうところのCObjectクラスってのがないよね。
あれって何でなの?
そういうものだって言われて終わりかな…。
715デフォルトの名無しさん:02/02/02 17:36
スタックって何ですか?どうしたら節約できるんですか?
そういうものだ。
>>715
> どうしたら節約できるんですか?

でかいauto変数を使わないようにする。
少しは自分で調べろよ。
718デフォルトの名無しさん:02/02/02 18:32
>>715
「おいオメー さっきから うるせえぞ
『知りません』『知りません』ってよォーーーー
『知りません』・・・そんな言葉は使う必要がねーんだ
なぜなら オレやオレたちの仲間は その言葉を頭に浮かべた時には!
既にGoogleや書籍で調べがついちまって もうすでに『知っている』からだッ!
だから 使った事がねェーーーッ
『知っている』なら 使ってもいいッ!」
719ithink:02/02/02 20:07
>714
基底クラスがあるとすると例えば多重継承をどう処理する?などなど
>>714
そんなもん要らんから。
>>714
MFCがこまるから。
>>715
再帰で無限ループとかになってないか?
'a'ってint型じゃないのですか?
プログラミング言語C++に
void print(int);
void print(char);
があった場合、print('a');とするとprint(char)が
呼ばれるって書いてあるんですけど。
>>723
C だと int, C++ だと char
こういうときはポインタでわたす
こういうときはリファレンスでわたす
とか決めてる?
>>725
場合によって相手を変える場合にはポインタ
初期設定したら二度と相手を変えない場合には参照

NULL がくる可能性があるならポインタ
NULL がきたらまずい場合は参照

もちろん

 foo(int& n);

 int *p = NULL;
 foo(*p);

とか書けばコンパイラのエラーチェックに引っかからないが、そりゃ NULL ポインタ
をデリファレンスしたヤツが悪い。
ポインタの場合は、メンバ変数とかグローバル変数とかに保持されて、その関数を抜けた後も使われる場合があるけど、
参照で渡す場合はそれをしないという自分ルール。

参照にNULL渡す奴なんぞ知らんってことついては >>726 に同意。
privateとpublic書く順番。

class A{
private:
 int a;
public:
 void f();
};

class A{
public:
 void f();
private:
 int a;
};

今までずっとprivateを先に書いてたけど、STLのソースなんかは逆なのね・・・どっちが普通??
729 :02/02/03 22:59
>728
漏れはヘッダ見た時にインターフェースが見やすいように
public が先
>>728漏れは
public:クラス名・タイプ宣言
public:コンストラクタ
public:メソッド
public:フィールド
public:クラス
protected:クラス名・タイプ宣言
 :
 :
private:クラス名・タイプ宣言
 :
 :
>>729
おれは private 書かずに、いきなりメンバ変数書くので private が先。

たいてい、メンバ変数は pImpl だけだったり。
732デフォルトの名無しさん:02/02/04 09:19
C++で追加された演算子(?)に
  const_cast dynamic_cast reinterpret_cast static_cast
がありますよね?
これがいまいちわからんのです。
普通のキャストと何が違うんでしょうか?
C++を勉強した本には載ってなかったし、BCBのヘルプを見ても使用例がなくてどうも。。
有用な使用例サンプルを出していただけると泣けるほど嬉しいです。
>>732
>C++を勉強した本

どんな本で勉強してるんだよ...
735デフォルトの名無しさん:02/02/04 11:04
>>733
すばらしい。そこみたら即効で理解できてしまいました。
いいとこ教えてもらった〜。ありがとー。

>>734
「CプログラマのためのC++入門」です。
ネームスペースやテンプレートもなかったです。
まだ定まってないようでした。
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄」
―――――――――――――‐┬┘
                        | 
       ____.____    | 
     |        |        |   | 
     |        | ∧_∧ |   | 
     |        |( ´∀`)つ ミ | 古くさい本は投げ捨てろ
     |        |/ ⊃  ノ |   |  □
        ̄ ̄ ̄ ̄' ̄ ̄ ̄ ̄    |
燃やして暖をとろう
738デフォルトの名無しさん:02/02/04 14:43
質問です。
A[0]=1,A[1]=2,A[2]=3
B[0]=4,B[1]=5,B[2]=6,B[3]=7
上記のデータを
vector<vector<int> > IntAry;
で用意して以下の様に格納したいのですが
IntAry[0][0]=1
IntAry[0][1]=2
IntAry[0][2]=3

IntAry[1][0]=4
IntAry[1][1]=5
IntAry[1][2]=6
IntAry[1][3]=7

一発で*Aから*IntAry[0]にコピーする方法がどうも出来ません。
なにか良い方法ありましたらご教授お願いします。
>>735
>「CプログラマのためのC++入門」

Cプログラマ向けの本らしいのにCと違うキャストの種類すら載って
ないとは恐ろしい度胸だね。
classとstructの違いくらいしか載ってないのかね。
入門向けC++本といえば、ろくにSTLと標準ライブラリについて書いてない
のが沢山ありそうだ。Cの本でprintfについて書いてないというのもあまり
ないだろうに。そういうものがSTLの周知を妨げているのかもしれん。
740739:02/02/04 14:51
std::copy(A, A + 2, IntAry[0].begin());
std::copy(B, B + 3, IntAry[1].begin());
一発ってコレの繰り返しじゃ駄目なの?
741740:02/02/04 14:51
>>738ね。
>>739
まぁ、参考文献が『The Programming Language C++ second edition』だったりするからな。
つか、謝辞の日付1992年4月だぞ。古すぎてやめといたほうがいい部類の本かもな。
743デフォルトの名無しさん:02/02/04 15:51
>>740
ありがとうございます。今検証中なのですが
std::copy(IntAry[0], IntAry[0].begin() + 2, C[0]);
逆に書き戻す場合上記ではないのでしょうか。
といいつつエラーが出るのでまずはgoogleしてきます。
744 :02/02/04 15:58
>743
vector の vector の中身は直列な一つのメモリにはならんぞ
745744:02/02/04 15:59
スマソ,勘違いしたっぽい

std::copy(IntAry[0].begin(), IntAry[0].end(), C[0]);

で良いっつー話かな?
746744:02/02/04 16:01
さらにスマソ
std::copy(IntAry[0].begin(), IntAry[0].end(), &C[0]);
だな.
これなら C が配列でも vector でもOK
747ワェス・パラヤ:02/02/04 17:49
「みんな嫌いだぁ!メモリリーク起きちゃえ〜」

#include <iostream.h>
int main()
{
for(int i=0;i < 1000;i++)
int *p=new int;
return 0;
}
748デフォルトの名無しさん:02/02/04 17:58
>>746
出来ました。ありがとうございます。
今度は自分がBYTE配列、相手(C)がLPVOIDの場合に上手く行く様に
頑張ってます。これは同じ様にやれば特に問題なしかな??
749(l)←マムコ:02/02/04 18:01
>>747
while(1){

}

↑じゃないの?
>>747
E-mail欄のコメント書き忘れんなよ
>>747
プログラム終了と同時にメモリは解放されます。
752デフォルトの名無しさん:02/02/07 00:28
boostはここでいいんでしょうか?

boost::threadはPOSIX環境ではPthreadのラッパーとして
機能するみたいですけどLinuxとかSolarisの上ならこれで
SMPで動いてしまうんでしょうか?

これが使えそうならPthreadインターフェイスは捨てたいのですが・・・

# Boostって日本語の解説は少ないですね
>>752
libs/src/thread.cpp 見ると pthread_create() してるから、使ってる POSIX Thread
ライブラリが SMP 対応なら、問題なく SMP で動くと思われ。
754デフォルトの名無しさん:02/02/07 01:52
ショボイ質問。
deleteって配列消すとき、[ ]付けても付けなくてもどっちでもいいんだっけ?
それは何次でもかわらん?
>>754 よくない。
756またりろ:02/02/07 01:59
wsprintf(str, "%d", strlen(ccc));
MessageBox(hWnd, str, "", MB_OK);//////42

wsprintf(str, "%d", strlen(str));
MessageBox(hWnd, str, "", MB_OK);//////48

if(strcmp(ccc,str))MessageBox(hWnd, "同じ", "", MB_OK);

同じっていうメッセージボックスは表示されるから
cccとstrは等しい。でも、strlenの結果が違う。
どうしてなんだろう?
757754:02/02/07 02:00
>>755
素早いレス、どうも。
ついでに
(*a)[5][5] 消す場合、
delete[] a;
で良い?
758またりろ:02/02/07 02:01
あ、分かった。スマソ。
759またりろ:02/02/07 02:06
やっぱり分からん。

wsprintf(buf, "%d", strlen(ccc));
MessageBox(hWnd, buf, "", MB_OK);////// buf=42

wsprintf(buf, "%d", strlen(ptr));
MessageBox(hWnd, buf, "", MB_OK);////// buf=48

if(strcmp(ccc,ptr))MessageBox(hWnd, "同じ", "", MB_OK);

同じっていうメッセージボックスは表示されるから
cccとptrは等しい。でも、strlenの結果が違う。
どうしてなんだろう?
760デフォルトの名無しさん:02/02/07 02:08
>759
strcmp()は比較した文字列が等しいとき0を返す。
だから表示されたということはif()で0以外が評価されてる。
(*a)[5][5] 消す場合、
delete[] a;
aは配列へのポインタだろ? 配列じゃなくて…
762またりろ:02/02/07 02:12
うはっ。ありがとう。そうそう、異なってれば0以外でしたね。
763ドンキホーテかな、おれって?:02/02/07 21:57
試食版で、ms-DOSベースのアンチウイルスソフトって作れますか?
JAVAじゃないと無理ですか?
小一時間の説教覚悟してますんで、出来るか出来ないかをまず回答ください。
764デフォルトの名無しさん:02/02/07 22:19
こんばんは。初めまして。
C++Builderのexeをスタートアップに登録して
起動時にある処理を行いたいのですがその時フォームを非表示
にして処理を行いたいのです。
で,下記の様に記述するとフォームを非表示にできる事は
解ったのですが最初の処理をどこに記述したら良いかよく
解らないのです。
VBの場合だとSub Main()ルーチンに記述するのですが・・・
Formのshowイベントとかはまずいし・・・・・・
参考になる物があったら教えて下さい(T__T)
Application->ShowMainForm = false;
>764
だからそれぞれのプラットフォームのスレ逝けっつーの
>>765
これだな。

新C++Builder相談室
http://pc.2ch.net/test/read.cgi/tech/997074601/
767デフォルトの名無しさん:02/02/08 08:26
C++では、「Cでchar*型をつかっていたような場所では
string型にすべておきかえられる。また、そのほうが効率がいい」
って、どっかの本にかいてあったんだけど、
すべておきかえられるもの?
char*型がいらないってことではないよね?
>>767
corbaのstringってcharにマッピングされてなかったっけ?
というかもし今でもそうなら仕様を変えた方がいいような、、、
すべてなわけはないけど、文字列を扱ってる箇所なら置き換えて良いのでわ。
効率に関してはノーコメント。
>>769
そして可変長バッファは vector で置き換え。

効率は、それまで const char * で渡してきた部分を const string& にすれば、
いずれにせよポインタひとつ分で受け渡せるから問題ない。strdup() の代わり
にコピーコンストラクタってのも悪いトレードオフじゃないし。

気をつけないといけないのは + 演算子なんかを多用して、ソースコードには
直接見えない一時オブジェクトをたくさん作ってしまうことかな。C++ だと、何
気ない 1 ステートメントが、大量のオブジェクト生成/破棄を行うことがある
ので。
771デフォルトの名無しさん:02/02/09 04:52
ねぇ、こういう使いかたってできないの?

class Command{
};
class CommandA:public Command{};
class CommandB:public Command{};
struct TestData{
TCHAR *com;
Command *c;
};
TestData test[]={
{"func1",new CommandA}
};

関数ポインタを使う代わりにコマンドオブジェクトをテーブルにもたせろ
って言われたんだけど、こういうことじゃないのかなぁ?
こんぱいるとおらない。

>>771
俺はそのソースそのままコピペで通るんだけど。
773771:02/02/09 05:19
>>772
おおぉ、
new CommandA()
にしたら、とおった。
そのままじゃむりっぽい。
ちなみに、うちのコンパイラはVC++6です。
ご協力サンクス
774デフォルトの名無しさん:02/02/09 14:59
クラスの中でメンバ関数
void abc::hoge(void) {}
を定義して、クラスの外で
void hoge(void) {}
を定義した場合、

クラスの中でhoge()を読んだ場合、メンバ関数が優先して呼ばれるのでしょうか?
そうならば、クラス内でグローバルな関数を呼びたい場合はどうするのでしょうか?
::hoge()
>>775
できました。ありがとうございます。
777デフォルトの名無しさん:02/02/09 15:52
さまざまなファイルに頻繁にアクセスするプログラムを作っているんですが、
ファイルアクセスに関するエラー処理ってほんとにいるんですかねぇ?

openに失敗した場合の処理はともかくとして、
一旦openに成功した後ではファイルに書き込んでるときのエラー処理とかって
現実におき得ないような気がするんですが・・・

一行書き込む毎に、いちいちエラー処理って入れなきゃならないものなんでしょうか?
メディアが満杯とか
じゃあ かかなきゃえーやんかー
とりあえず空き不足
可能性はある。
ディスクフルとか、
ネットワークファイルシステムでサーバだのルータが落ちたとか、
実はpipeで相手のプロセスが終了してEPIPEとか。
鬱氏
783777:02/02/09 16:03
ふむ。ディスクフル、ネットワークドライブ・・・
ありそうですねぇ。

でもそしたら、たとえば、

ofsFile << "hogehoge" << endl;
if(!ofsFile.fail())
{
 return false;
}
ofsFile << "FunyaFunya" << endl;
if(!ofsFile.fail())
{
 return false;
}

てな感じで毎行毎行入れてかなきゃならないでしょうか?
とても現実的な話ではないような気がするんですが。
>>783
思いっきりシステム依存。他行け
いちいち調べたくないときはラッパー作って例外投げればいいんじゃない?
786777:02/02/09 16:13
>>785
こんなかんじ?

CMyFile::Write(std::ofstream& ofsFile, string strLine)
{
 ofsFile << "hogehoge" << endl;
 if(!ofsFile.fail())
 {
  throw "File Write Error";
 }
}

でもひょっとしてこれの同じものを、ofstreamそのものの例外でもってたりします?
>>777
C++ なんだから、例外で拾うようにすれば、と答えとく。
>>786
ios_base あたりに、書き込み失敗したら例外投げるようにフラグを立てるメソッドが
あったと思うが
>> 783
> とても現実的な話ではないような気がするんですが。

あたりまえなんじゃないの?
フロッピーに書き込みにいって途中で抜いてみるとか、
手元のアプリでためしてみれば?
790777:02/02/09 18:12
>>788
できましたですぅ。ありがとうございますです。

以下サンプル(Zはネットワークドライブ):

openとoutの間でネットワークケーブルを引っこ抜くと、
bbb.txtは何事もなかったかのように終了し、
aaa.txtは例外を発生します。(failbitも立てるとopen時に例外となります。)

try {
std::ofstream ofsbFile("z:\\bbb.txt");
Sleep(10000);
ofsbFile << "bbb" << std::endl;

std::ofstream ofsFile("z:\\aaa.txt");
// ofsFile.exceptions(ios_base::badbit | ios_base::failbit);
ofsFile.exceptions(ios_base::badbit);
Sleep(10000);
ofsFile << "aaa" << std::endl;
}
catch(ios_base::failure& exc)
{
cerr << exc.what() << endl;
}
791デフォルトの名無しさん:02/02/09 22:20
ベクトルクラスを作りたいのですが
クラスに複数のfloatがあるとします
class Vector4
{
public:
....
public:
float x, y, z, w;
};

この時にoperator[]を次のように記述する事はメモリレイアウト上
問題はないのでしょうか?処理系依存でしょうか?
float& Vector::operator [](int i)
{
float *f = &x;
return f[i];
}
上記Vector4::operator []・・・の間違いです
i=0以外は、未定義のはず。なぜ、
switch(i){
case 0:return x;
case 1:return y;
case 2:return z;
case 3:return w;
}
throw RangeException;
と素直にかかないのでしょうか?
794デフォルトの名無しさん:02/02/09 22:52
>>793
やっぱりそうなんですか?
最終的にこれをメンバにした4x4の行列クラスを作りたいのですが
逆行列を求める時などにi, jでアクセスできるとforが使えるから
書きやすいと思うのです

これをやるには一時的に配列に入れるしかないかな?
>これをやるには一時的に配列に入れるしかないかな?

つか、793で書いたのは、まさしくfloat& operator [](int i)の
コードなんだが‥‥
796デフォルトの名無しさん:02/02/09 23:27
>>795
あそうか
すいませんアホデシタ・・・

自分で割り振ってやれば良いんですね
これで逝ってみます有難うございました
>794
union {
 struct { float x, y, z, w; };;
 float f[4];
};
とでもしとくとか。
>797
それってstructのパディングの関係で上手く逝かない事無い?
799798:02/02/09 23:51
悪い,float だったらならないか・・・本当?
実はその辺の知識漏れ怪しいわ.スマソ
たとえfloatが32ビットでアラインメントが64ビットだとしても、float2個で、64ビット境界またがないから、
アラインメントの問題は無いでしょ。
パディングは通常、アラインメントをまたがないと、発生しないのよ。
>>791
class Vector4
{
private:
float f[4];
public:
float& x() {return f[0];}
float x() const {return f[0];}
float& y() {return f[1];}
float y() const {return f[1];}
...
};
としそうなもんだな。()が邪魔っけだが。
float &x = f[0], &y = f[1], &z = f[2], &w = f[3];
で逝けるかもよ。
803791:02/02/10 00:38
みなさん色々有難うございます
>>801も考えたんですが仰るように()がちと邪魔なのと
i, jアクセスはあまり頻繁には使わないのとで
>>793の方法で逝っていますがどれが一番一般的でしょうか?
別にどれがというのは無いかな?
俺は>>797の方法取ってる。
>>804
だが、そもそも union のメモリ配置自体も実装依存じゃない? まぁ、大抵の環境で
は問題は発生しないだろうから、そこまで規格にこだわらなくても良いけど。

いちおう assert(&x == &f[0] && &w == &f[3]); ぐらい入れておくのが吉か。
806デフォルトの名無しさん:02/02/10 01:01
>>797でええんちゃう?
安全性をとるなら>>793だと思うけど。
807デフォルトの名無しさん:02/02/10 21:25
>>791
こんなのはどう

class Vector4
{
float f[4];
public:
float &x,&y,&z,&w;
Vector4() : x(f[0]), y(f[1]), z(f[2]), w(f[3]) {}
float& operator[](int i){return f[i];}
const operator[](int i)const{return f[i];}
};
808807:02/02/10 21:28
ちょい間違い
const float& operator[](int i)const{return f[i];}
>>807
それだと Vector4 のサイズが大きくなるから、ちょっと嫌かと。
810デフォルトの名無しさん:02/02/10 22:35
皆さん set/multiset ってどーゆー時に使います?
シーケンスコンテナとか map/multimap, hash とかは
使い道はだいたい思い浮かぶんですけど,set/multiset
の使い道ってイマイチ思い浮かばないんですが…
思い浮かばないなら使うなって。
使いたいと思ったやつが使うんだろ。
>>810
逐次入力されていく値をソートしたいとき。
813810:02/02/10 23:26
>812
なるほど,そーゆー時は確かにsetを使う価値はありますね.ふむふむ

>811
まぁそー言わんといて下さいよ.
見聞を少しでも広めようというだけなので…
814デフォルトの名無しさん:02/02/11 02:37
ofstreamデフォルトの<<演算子を行う前に独自の処理を入れたいと思い、
ofstreamを継承したクラスを作ってます。

<<operator引数の全パターンを網羅させるのは面倒なので、
以下のように安直な解決策を計ってみました。
よくわからないのがソース中の@、A、Bです。

class CMyFile : public ofstream
{
 public:
  // @ 全引数のパターンを一気に受けたい。
ostream& operator<<(void* input);
};

ostream& CMyFile::operator <<(void *input)
{
 // 独自の処理
 cout << input << std::endl;

 // 親の処理
 // A 親の<<を呼び出したい。
 parent? << input; // ???
 
// B 何を返すの?
  return ???; // ???
}
>814
return ofstream::operator<<(input);

ぢゃマズいかのぅ?
816815:02/02/11 02:58
あぁ,input って void* なのか.
うーん,そりは・・・任せたぞ!他の人!!
817デフォルトの名無しさん:02/02/11 03:22
C++で
int ** foo= new int[10][10];
みたいなことってできないんですか?
>>817
出来ね。
foo[1][1]はどこをさすんだ?
new int[10][10]とnew int[9][9]で別のアドレスをさす必要があるのにint**からじゃわからんだろ。
>>814
template 関数の出番じゃない? 詳細はともかく、こんな感じで。

template <typename T> ostream& (ostream& os, T& input)
820デフォルトの名無しさん:02/02/11 03:34
二次元配列を動的に確保するにはどうすれば良いのでしょう
821デフォルトの名無しさん:02/02/11 03:50
>>818
なにいってんのかわかんねーぞ
822突然すみません・・・:02/02/11 04:13
error LNK2001: unresolved external symbol "void __cdecl fileout(char *)" (?fileout@@YAXPAD@Z)
ってエラーどうやったらいいですか???
ちなみに初心者なんで、やさしくお願いします。
823初学者:02/02/11 04:53
質問です。

C++クラスメンバ関数ないで宣言したstaticな変数ってCのそれを同じと考えて良いですか?
つまり

MYSTRUCT *foo::boo()
{
  static MYSTRUCT mystruct;

  処理

  return &mystruct;
}
として呼び出し側からmystructを使うのは可能ですか?
でもこんなやり方するのかな?
こういう場合は皆さんどうします?構造体をそのまま返すと構造体が大きい場合負荷がかかりますよねぇ。
かといってポインタを返すと実体の生存時間が気になりますよね。
staticメンバにしてみてもべつのに上書きされる可能性があるし。
>>822 __cdecl の fileout(char *)の実体がないらしい探して
>>823 よくわからんけど、俺ならメンバ変数にしてそれのポインタを返すな。
属性も指定できるし。
>823
sigletonの安直な実装としては便利。
826デフォルトの名無しさん:02/02/11 08:32
>>823
可能。ただ、その手で作ったオブジェクトのデストラクトの順番に
気ぃつけるよーに。ただデータ入れただけの構造体なら大丈夫だと思うけど。

> かといってポインタを返すと実体の生存時間が気になりますよね。
std::auto_ptr で返してしまうとか。
827初学者:02/02/11 10:05
>>824-826
ありがとうございます。よくわかりました。ではでは。
newやdeleteのオーバーロードって
よくやりますか?
829814:02/02/11 19:59
>>815 >>819 ども。
お二人の意見を参考につくってみたんですが、リンクエラーが・・・

<テンプレートを使ったメソッド>
template <typename T> ofstream& CMyFile::operator<<(T input)
{
 return ofstream::operator <<(T input);
}

<使用例>
CMyFile cMyFile("XXXX.txt");
cMyFile.readOpen();
int a=1;
cMyFile << a ;

<リンクエラー>
 TestProj.obj : error LNK2001:
外部シンボル ""public: class std::basic_ofstream<char,struct std::char_traits<char> > &
__thiscall CMyFile::operator<<(int)"
(??6CMyFile@@QAEAAV?$basic_ofstream@DU?$char_traits@D@std@@@std@@H@Z)" は未解決です

オペレータでのテンプレートの使い方がよくわからんです。
830815:02/02/11 21:23
>814=829
うーむ g++ 3.0.3 では

template <typename T>
ofstream& CMyFile::operator<<(T input)
{
ofstream::operator<<(input);
return *this;
}

とすれば逝ける模様.

なんでそのまま return 出来ないんぢゃろう・・・
誰か教えてプリーズ
831デフォルトの名無しさん:02/02/12 00:05
誰か教えてケロ。
template<class T>class A
{
 void func(void);
};
void A::func(void){}
見たいに外で関数を定義したいのですがどうしたら良いのでしょうか。
template<class T>void A::func(void){}
833デフォルトの名無しさん:02/02/12 00:15
ん?
template<class T>void A<T>::func(void){}
じゃなかったっけ?
違ったらスマソ。
>>833 そうだった。スマソ。
835831:02/02/12 00:25
>>832-834
おお!ありがとうございます。
今まで、その方法が分からなかったもので。
助かりました。
836デフォルトの名無しさん:02/02/12 17:20
main(){
int * num = new int[1000];
delete num;
}
VC6のコンパイラは配列をdeleteするとき、
delete [] numとしなくてもいいのか?

実行してみても、
Detected memory leaks!
が表示されないだけれども…
VC6のコンパイラで、全てのリークが、検出されるというわけではない。
#つか、detected leakなんて報告するのは、ライブラリでわ‥‥
>>836
intやcharなどの組み込み型なら問題ない模様。
クラスや構造体はデストラクタが呼ばれないのでだめ。
839デフォルトの名無しさん:02/02/12 18:01
>>837
>>838
レスありがとうございます。

www.codeguru.com/richedit/SyntaxColorizer.html

実は、codeguruのCSyntaxColorizerクラスを実行したら、
~CSyntaxColorizer()で落ちるから、
何だろうと思ったら、配列のdeleteに一つも[]がついてないのよ。

それはunsigned shortの配列だったけど、
deleteに[]つけたら解決しました。

"Comments:"で誰も言及してないから、
マジ焦ったよ。
>>836
VC6 だと delete, delete[] は同じ動作をする。(だからといって、これに依存した
コード書いちゃダメだよ)
841814:02/02/13 00:32
>>830
メンバー関数をtemplateで作るときは、宣言部に直接本体を埋め込まないと
うまくいかないみたいですね。

CMyFile : ofstream public
{

template <typename T> bool write(T input)
{
cout << input;
return true;
}
};

それから、よく考えたらoperator<<をオーバーライドしてしまってるので、
望みの動作させるためには、friend関数の力を借りねばならないみたいです・・・・・・・・
842デフォルトの名無しさん:02/02/13 01:49
void func(void){cout<<"Hello"<<endl;}
template<class T1,class T2>
T1(*FUNC)(T2)=&(void func(void));

これなんでエラーになるんでしょう?
どこか間違えていますか??
テンプレートは、関数かクラスに対してしか使えないきがするけど‥‥
>>842
&(void func(void)) じゃなくて &func だろ。
>>844
いいえ。これはエラーにはなっていません。
>>843
確かに。しかし VC6 だと、こんなコードもコンパイル通るな(実行すると落ちるけど)。
もしかしたら、昔は OK だったのかも。

void func(int) {}
template<class T1,class T2> T1 (*f)(T2) = &func;

int
main(void)
{
  (*f)(1);
  return 0;
}
>>840
> VC6 だと delete, delete[] は同じ動作をする
マジですか? VC5 だと delete では配列の解放をしてくれなかったと思ったけど。
class Ca
{
public:
 ~Ca(){cout << "deleted." << endl;}
};

int main(int argc, char* argv[])
{
 Ca* pca = new Ca[16];
 delete pca;
 return 0;
}
deleteとdelete[]でちゃんと動作違うけど。@VC6SP5
>>847
ごめん、勘違いだわ。
#include <iostream>
using namespase std

class<a,b>
int main(void)
double abu;
omaemona-
851超初心者:02/02/13 16:58
FreeBSDでC++
勉強して1時間目です。

今、hello.ccというファイルに、
#include <iostream>

int main()
{
std::cout << "Hello, world!\n";
}
と書き、

$ gcc hello.cc
としたら、
$ gcc hello.cc
/tmp/ccGQTMfz.o: In function `main':
/tmp/ccGQTMfz.o(.text+0xf): undefined reference to `cout'
/tmp/ccGQTMfz.o(.text+0x14): undefined reference to `ostream::operator<<(char const *)'
となりました。

なぜうまくいかないのか説明してください。
> なぜうまくいかないのか説明してください。
って,きっとネタなんだろうな.まぁマジレスしとくと,
使うコマンドは gcc じゃなくって g++ にしろ

ほんでよ,
http://www.freeml.com/message/[email protected]/0001221
でなんか面白い事やってる
853852:02/02/13 17:18
最初の三行は >851へのレスね.
まぁ見りゃ分かると思うけど.
854超初心者:02/02/13 17:38
>>852
gccとg++
ってどうちがうの?
855超初心者:02/02/13 17:48
FreeBSD で XEmacs から C++ をコンパイル,実行する方法
を教えて.
[ESC]X+compile
ってやってからどーすんの?
それぐらい自分でしらべろよ。
なんでもかんでも
おしえて君だと、あとでこまるぞ。
857超初心者:02/02/13 17:54
最初が一番わからんのよ。
有る程度自分の足で立てるまで教えてよ。
>>857
なんでキミのために無料奉仕しなきゃならんのだ?
>854とか>857とか、どう見ても自分の足で立つ意志のある奴の吐くセリフじゃないな(w
Emacs使ってるなら、
M-x info
で>854も>855も解決する。infoの使い方がわからなかったらinfo読め。以上。
860デフォルトの名無しさん:02/02/13 19:52
delete delete[]ですが、組み込み型ならOKなのはVC6だけ
でしょうか?他の環境ではNGですか?
862860:02/02/13 19:59
>>838へのレスでした。
わかりにくくてスマソ
863デフォルトの名無しさん:02/02/13 20:04
>>860
VC6でもたまたまOKなだけだと思った方がいい。
現実にはほとんどの処理系でもOKだけど、悪癖は早いうちに矯正することを
お勧めする。
864860:02/02/13 20:12
>>863
ありがとう!
ちょうどそのネタで上司とちょっと揉めてました(汗)。
上司が [] つけない人なんです。
>>863
スタイルの問題をいうなら、そもそも delete[] を陽に呼び出すようなプログラムを
書くな、という気がするが。std::vector や boost::scoped_array を使うことを考えた
方が良い。
866852:02/02/13 20:37
>854,855
しょーがねーな.まぁ最初は確かにどこから手付けていいか分からんからな.

gcc は C コンパイラ, g++ は C++ コンパイラだと思っとけ.

Emacs の M-X compile は実質上 make を起動するだけだから,make について
お勉強するべし.make についてのサイトは探せば色々見付かるから自分で探
すべし.
867デフォルトの名無しさん:02/02/13 22:10
virtualキーワードについて質問です。
class A
{
 virtual class B
 {
 };
};
このvirtual付けたBってどういう扱いになるんでしょうか?
付けたときと付けない時の違いが分からないもので。
>>867
virtual class B なんて定義は C++ の規格にはないぞ。

virtual を使えるのは

1. メンバ関数
2. 継承

いずれかのみだ。
869デフォルトの名無しさん:02/02/13 22:43
>>868
それが何故か出来るんですよ。
(一応、バージョンは古いけどBCB、VC、GCCでは確認済み)
C++ の規格に無いなら気にしなくていいなっと。
どうもありがと。
エディットボックス上にデスクトップのファイルをドラッグ&ドロップして
エディットボックスにそのドラッグ&ドロップしたファイルのパスを表示してやりたいのですが
どうやったらいいでしょうか?
>>869
最近の gcc だと怒られる。

% g++ test.cpp
test.cpp:4: `virtual' can only be specified for functions
test.cpp:4: virtual outside class declaration
dragqueryfileかなんかで
ファイル名とかとれるでしょ?
>870
プラットフォーム依存の質問はそれぞれのスレへ逝け.
ここはスレ違いだ.
874791:02/02/14 01:10
>>866
アフォですか?
gccはフロントエンドだから.ccなファイルならC++コードのコンパイルが通る

>>851
のエラーメッセージを良く見ろリンカのエラーだろが

正解は
$gcc hello.cc -lstdc++
875!866:02/02/14 01:29
>>874
だから「思っとけ」なんだろ。

なんで、わざわざ煽るかなぁ。(カルシウムが足りてない?)
>>874
名前を消し忘れたな。
791とのギャップにワラタ
877デフォルトの名無しさん:02/02/14 02:27
漏れもワラタ
>>791
>>874を晒しage
private継承をコンポジション
どうやってつかいわけてる?
を→と
void func(void){}
template<typename T>T* t=func;

((void(*)(void))t)();

これは何で落ちるんでしょう?テンプレートはこのような使い方を
してはいけないのでしょうか?
template は関数かクラスだけ。

# …って、「落ちる」??
>>878
private 継承なんて使ったことないなあ。つか、なるべく継承より
コンポジションを使うようにしてるよ。継承のレベルが深くなると
後の保守が大変なんで。
>>880
そんな使い方出来ることすら知らなんだ。
operatorを定義しているのか?
多分それできるのってVCだけでしょ?
>>880
ネタだとは思うが、もしそれが可能だとするなら t をキャストしているのは
無意味。むしろ t<void(*)(void)>() にすべきかと。
template<typename T>T* t;
int main()
{t=func; }
ってやると、
'void(*)(int)'から' *'に変換できないとかすごいことを云われるYO!
これこそホントのvoidポインタなのかな(ワラ
886デフォルトの名無しさん:02/02/15 18:14
どんな単位でクラスをsoやdllに分けるのがいいのか
そういったことを解説してる本やサイトを知ってる人がいたら教えて下さい。
class{
}
クラスはヘッダファイルに書くものですか?
>>887
別に *.cpp の方に書いても良い。

俺は外部に公開したくないクラスについては *.cpp に書いてる。

// 外部に公開するのでヘッダに書く
class Foo {
  struct Impl;
  const std::auto_ptr<Impl> pImpl;
public:
  ...
};

// 実装は外部に公開しないので *.cpp に書く
struct Foo::Impl {
  // いろいろ
};
>>888
勉強になりました。
thanx!!
890デフォルトの名無しさん:02/02/16 01:06
template<typename T>class TCA{};
template<typename U>class TCB{
public:
   friend template<typename A>class TCA<A>;
};

何故エラーに・・・?普通のfrindなら通るのですが・・・。
A-T&T ベル研究所 所長:デニス・M・リッチィ博士
892デフォルトの名無しさん:02/02/16 01:46
>>890
Aのタイプは誰が決めるの?
893デフォルトの名無しさん:02/02/16 01:49
//皆で分担してソースを書くと
const int MIN = 0;
const int MAX = 9;
#include <iostream>

struct A {
int hoge(int i) {//A君が値の範囲チェック
if (i > MIN && i < MAX) return i * 3; return i;
}
};

struct B {
int hoge(int i) {//B君も値の範囲チェック
struct A a; if (i > MIN && i < MAX) return a.hoge(i); return i;
}
};

void main()
{
B b;
int i, num = 8;
if (num > MIN && num < MAX)//メイン君も値の範囲チェック
i = b.hoge(num);
else
i = num;
std::cout << i << std::endl;
}

//のような事が頻出するのですが、そもそも誰が値の範囲チェック
//をするべきとか、決まりはあるのでしょうか?
そんなだからC++って遅いんだ!あ〜納得!
>>893
そりゃ、仕様で決めるだろ。

assert() はあらゆる場所にばら撒いておくが、正常パスの値チェックは仕様で決めた
関数でしかやらない。
>>892
・・・成る程。そりゃそうですよね。型が決定しなけりゃエラーになりますよね。
>893
うちならA・Bの側では一切値のチェックなんてしないよ!
食わせる前にチェックしろと言う仕様。
こう決まってるほうが都合がよくない?
898デフォルトの名無しさん:02/02/16 03:40
え?
>>893の場合ではmain内でチェックする方がいいの?
899初心者:02/02/16 03:47
template<class Type>...
この<>のにはclassとtypenameどちらを使うのが主流なんですか?
本にはclassとあって、さっき見たサイトだとtypenameと書いてありました。
900デフォルトの名無しさん:02/02/16 03:54
ANSI/ISO では汎用関数には typename を、汎用クラスには class を
使うように推奨していますが、古い処理系には typename という予約語
がなく、すべて class で代用していたのです。
ですから古い処理系で書かれたプログラムをコンパイルする互換性と、
これから新しくC++を学んでいく人は、必要に応じて書き分ければ
いいでしょう。
901初心者:02/02/16 04:01
ありがとうございました。
902デフォルトの名無しさん:02/02/16 05:33
int (*p)[10];
とあるとき、
p = new int[5][10];
は分かる。これは組み込み型にかぎれば、
p = (int (*)[10])malloc(5*sizeof(int [10]));
と同じことだよね。

しかし、
p = new int[][10];
の意味が分からない。コンパイルは通るんだが、これは何をやってるの?
サイズを指定しなくていいの?
>>902
うちの gcc(2.95.3) じゃ parse error になったよ。
通るの?
>>903 ども。
VCなら通った。
どうもVCでは、new int[0][10]と解釈されるみたい。
なーんだ。
905デフォルトの名無しさん:02/02/17 13:20
次の様なことがしたいのですが、
class A
{
 void FuncX(void){}
 void FuncY(void){}
 void FuncZ(void){}
public:
 void Call(int sel)
 {
  void (*func[])(void)={FuncX,FuncY,FuncZ};
  func[sel]();
 }
};
メンバー関数からポインタ取って呼び出すことは出来ないのでしょうか。
C++相談室 540より。

class Hoge {
 double (*Hoge::myfunc)(double);
public:
 double func1(double a);
 void setfunc(void) { myfunc = func1; }
 double callfunc(double a ) { return( (this->*(myfunc))(a) ); }
...
};
907名無しさん:02/02/17 14:24
STLPortをインストールしてみたのですが、
e:\program files\microsoft visual studio\vc98\include\stlport-4.5.3\stlport\exception(60) : fatal error C1083: インクルード ファイルがオープンできません。'../include/exception': No such file or directory
のように出てビルドできません。
なんかvc98\includeにファイルを読みに逝ってるみたいなんですが・・・
解決方法を知っている方、いませんでしょうか?
>> 906

コンパイル出来ないものを書くな。

class Hoge {
 double (Hoge::*myfunc)(double);
public:
 double func1(double a);
 void setfunc(void) { myfunc = &Hoge::func1; }
 double callfunc(double a) { return( (this->*myfunc)(a) ); }
};

あと、最近のC++だと&Hoge::func1のように
明確に指定しないといけないみたい。
>>907
stl/_site_config.h を INCLUDE で検索
911905:02/02/17 14:40
>>906,>>908
いままでその方法が分からず、staticにしてやっていました。
どうもありがとうございます。
912デフォルトの名無しさん:02/02/17 15:26
.hで定義したクラスメソッドを.cppでinlineで実装する事って意味ある?
inlineについて小一時間勉強セヨ
>>912
ヘッダで定義したものを *.cpp でも定義したら、そりゃ二重定義で怒られるだろ。
915名無しさん:02/02/17 16:07
>>909
>>910
stl_msvc.hを編集したらパスが変更できたみたいなんですが、
e:\program files\microsoft visual studio\vc98\include\stlport-4.5.3\stlport\stdarg.h(23) : warning C4182: #include のネスト レベルは 546 です; 無限再帰の可能性があります。
e:\program files\microsoft visual studio\vc98\include\stlport-4.5.3\stlport\stdarg.h(23) : fatal error C1076: コンパイラの制限 : ヒープの領域を使い果たしました; 上限を設定するために /Zm オプションを使用してください。
上のようなエラーが出てしまいます・・・
>>915
単にパスの設定をミスって再帰的に同じファイルを #include してるだけだと思うが。

悩みたくなければ ..\vc98\stlport の下に STLport をインストールしとけ。include の
下に入れると、いろいろめんどうだ。
917名無しさん:02/02/17 16:38
# include _STLP_NATIVE_C_HEADER(stdarg.h)
最初からネストするようになってるみたいですが・・・
>>917
違うだろ。

STLport の stdarg.h を #include すると、標準ヘッダの stdarg.h が #include
されるのが正解。そこで設定をミスって STLport の stdarg.h を再度 #include
してるから無限ループにはまってる。

919名無しさん:02/02/17 17:25
うーん、exceptionの方にも同じようなのがあるんですが、
こっちはincludeには入っていないみたいなんですが・・・
>912
「定義」という用語の使い方が間違っているとして、
privateなメソッドならあっても変ではない。
921デフォルトの名無しさん:02/02/17 20:13
new
deleteを使う基準がわかりません。
クラスの中の変数としてそのクラスのヘッダファイルでポインタを宣言した
らデコンストラクタでFreeしてやればいいのでしょうか?
クラスの各関数の中でnewした場合はその関数を出るときにdeleteする必要があるのでしょうか?
それともないのでしょうか?
>>921
とりあえず一から勉強し直した方がいいように思う。…が、まぁいいや。

new で作ったオブジェクトは、どこかで delete しないと消えてくれない。
だから、new したまんま放っておくとメモリリークしたりリソースリークしたりて
よろしくない。ので、使い終わったらどこかで責任持って必ずdeleteせよ。

逆に、「deleteしないと消えない」ことを利用した使い方もある。
関数の中で string xxx; とかやって作ったオブジェクトは、関数から抜けるときに
必ず消えてしまう。これを外までもたせようとしたら、
string* pXxx = new string;
とかやって new で作って返すことになる。この場合関数の中でdeleteしちゃったら
何の意味もないので、別のどこかの関数で delete することになるだろう。

#1 あと、newで作ったのではないオブジェクトは delete するな。

#2 ていうか、new/delete の意味が理解できたら、 auto_ptr を積極的に使え。

以上、健闘を祈る。
その後
#3 でauto_ptrをコンテナに入れようとしてはまる
に一票
#4 そして boost::shared_ptr にたどり着く
>>923
>>924
彼らはEffective STLを読んだばかりで嬉しいのです
そうそして漏れも(w
926超初心者:02/02/18 00:52
>>855
です。

>Emacs の M-X compile は実質上 make を起動するだけだから,make について
>お勉強するべし.make についてのサイトは探せば色々見付かるから自分で探
>すべし.
ちょっとしらべたけど、わからんかった。
Makefileっていうのは、c++ファイルと同じディレクトリ
に作成したらいいんかいな?
で、そのMakefileはc++ファイル作るたびに、
別途用意しなあかんの?
結構めんどくさい気がするんだけど。
汎用性のあるMakefileってないの??
autoconf,automake
>926
M-x compile ってやったらミニバッファに make -k とか出るよな?
それを全部消して gcc hello.cc とでも入力してからENTER。
一行ですまないようだったら、スクリプトファイルにでも書いておいて
そのファイル名を入れればいい。
makeのありがたみがわからないうちはそれで十分。
929デフォルトの名無しさん:02/02/18 01:14
>926
とりあえず調べたサイトを列挙せよ
930デフォルトの名無しさん:02/02/18 01:15
931デフォルトの名無しさん:02/02/18 01:22
 % cat Makefile
 #
 % make hoge
 cc  tmp.c  -o tmp
 %
充分有り難い。
違った宇津
 % make hoge
 cc  hoge.c  -o hoge
 %
933デフォルトの名無しさん:02/02/18 03:04
テキストエディタ作りたいんすけど、文章を選択した範囲に
全角文字、半角文字(できれば英数と仮名を区別)が何文字あるかを
調べるにはどうしたらいいですか???
とりあえず過去ログで「半角」で全検索、もちろんサーチで検索も
してみました。よくわからない・・・です(^-^;
文字コードはSJISかな? 何か便利な関数がありそうな予感してるんですが。
>結構めんどくさい気がするんだけど。
>汎用性のあるMakefileってないの??
ソースと実行ファイルが一対一なら書かなくてもいいの。
デフォルトでルール持ってるから。
これは商用UNIX/Linux/BSD/Windows共通。
どれでも「make 実行ファイル名」だけ。
Visual-Cなら「nmake filename.exe」。
ファイル名拡張子を見て、CかC++かフォートランかパスカルを
起動してくれる。gcc->.cc, Visual-C->.cpp
935デフォルトの名無しさん:02/02/18 03:16
>>926

Makefileはそもそも、どういう目的で作られたのかを考えな!
ちなみにC++のファイルと同じじゃなくちゃいけないって事は無い!
Make は make install でセットアップまでしてくれますな。
(書いてあれば)
汎用性でいえば最強の部類に入ると思われ。
937デフォルトの名無しさん:02/02/18 07:41
マウスの位置やボタン状態、キーの状態(できれば押した瞬間でなく取得する度に
今押されているかどうかを知りたい)を取得したいのですが、APIからのメッセージ
は一度に一つしか送られてこないので使い勝手が悪いです。なにか良い関数は
あるでしょうか?
938937:02/02/18 07:45
すいません、キー状態ってのはどのキーが押されているかではなく、
どれか一つでもキーが押されているかどうか知らせてくれる、ってことです。
マウスとキーを同時に扱えない(メッセージが1つ&瞬間なので)ので困ってます。
Windowsならdirectinput使うのはどうでしょう
>>933
nAlpha = nDigit = nSbc = nDbc = 0;
for( p=start; p<end; p=next(p) )
{
  if( isalpha(*p) ) nAlpha++;
  else if( isdigit(*p) )nDigit++;
  else if( isSingleByteChar(*p) ) nSbc++;
  else nDbc++;
}
こんな感じで数えりゃいいんでないの?
↑には流れしか書いてないから実装は自分で好きなようにどーぞ。
941937:02/02/18 08:14
>>939
ありがとうございます。ちょっとやってみます。
942デフォルトの名無しさん:02/02/18 17:45
>>940
さんくす! そんな関数あったんやね。
isSingleByteCharはC++にあるん? 半角カナも取得したいっすな。
さすがにもうちょい自分で調べまっす。
943940:02/02/18 18:33
>>940
そんな関数は無いから自分で作れゆーとるんじゃゴルァ (゚д゚ )
iskanji とか ismbcslead とか何かそんなのはあるかもしれんが。

ガンバッテーネ。
944940:02/02/18 18:34
ちなみにリンク先は>>942の間違いだ。
945デフォルトの名無しさん:02/02/18 23:17
突然すいません。
次のコードがエラーになるのですが、
なぜなのですか?コンパイラはgccです。
両方抽象クラスだから、実装はなくてもいいと思って
いるんですよね。

class A {
public:
virtual bool funcA() = 0;
};

class B
{
public:
virtual A funcB() = 0;
};
946デフォルトの名無しさん:02/02/18 23:19
抽象クラスは戻り値の型に使えないのですか?
純粋仮想関数じゃエラーでるんじゃないの?
>>946
使えるわけがなかろう。落ち着いて考えろ。
949デフォルトの名無しさん:02/02/18 23:26
class CA{
class inA{
};
};
これがOKなら、このメンバクラス(メンバ?)
のオーバロードをしたいのですが、出来るでしょうか?
class CA{
template<class C1>class inA{cout<<"A"<<endl;};
template<class C2,class C3>class inA{cout<<"B"<<endl;};
public:
CA{inA<int,int> ina;};
};
は、通るのですが、
CA(){inA<int> ina;};
とすると、エラーになってしまいます。これは出来ないということなのでしょうか?

950デフォルトの名無しさん:02/02/18 23:29
>>948
そういわれればそうだな。
ありがとうございます。あー、どうしましょう。
951デフォルトの名無しさん:02/02/18 23:30
char* name;
というのがあって、これがNULLならcin(標準入力)から、
NULLでないならこの名前のファイルを開いてifstreamから
入力したいんですが、どう書くのがC++的に一番いいでしょう?

istream* ifs;
if(name)
  ifs=new ifstream(name);
else
  ifs=&cin;
int i;
(*ifs)>>i;

とかだとどうもポインタが出てきて嫌なんですが…。
かといって参照だとスコープとかの関係で無理っぽいし…。
というわけでかっこいい書き方をおしえてください。
>>948
え?なんで?
>>952
ポインタじゃないからって事じゃない?
このスレ見てると
C++が使える人がそんなに多くないのと、
C++にあこがれる人がまだ沢山いるのとの
二つがよく分かって少し安心しました。
955デフォルトの名無しさん:02/02/19 01:19
>951
それでいいんじゃん,別に.見て何やってんのかスグ分かるし.
まぁあとは3項演算子使いたければ使えってぐらいで.

ただ ifs っつーと ifstream を連想するのは漏れだけ?
istream だったら・・・ is ・・・ かなぁ?
956名無しさん:02/02/19 01:34
957デフォルトの名無しさん:02/02/19 07:02
>>953
ポインタ返しにすればいいわけね。
ほんと、俺はバカだな。ありがとう。
>>951
ifstream(name)の生存期間が不明だからあまり具体的にはアドバイス
出来ないけど、ひとつの関数で作業をやりすぎてないか?
実際のコードではint iじゃなくて、もっといろいろ入力するんだろ?

1.入力すべきストリームを決定
2.ストリームからデータを入力

という二つの作業があるんだから、別の関数に分けた方が
いいと思うぞ。そうやって構造をスッキリさせれば、ポインタを
なくす方法も見えてくるはずだ。
959デフォルトの名無しさん:02/02/19 23:31
static関数のなかでクラスの変数にアクセスするにはどうしたら良いのでしょうか?
クラスにflag変数をもっておいて
そのflagの値によってstatic関数の中で処理を変化させたいのです。
クラス内でstatic BOOL flagを宣言するとコンパイラは通るのですが、
実行ができません。
>959
誰もが平均0.6回は通る道だな。
クラスの外側(ソースファイルのどれか)で static BOOL xxx::flag; と定義すれ。
961デフォルトの名無しさん:02/02/20 00:04
>960
でもそれだったらリンカエラー出るからそーゆー話じゃないんじゃない?
>959 は
> static (でprivate or protected) な関数の処理をメンバ変数の値によって
> 挙動を変えたい
という意味不明の事を言ってるように見えるのはヲレの日本語能力が足りない
からかな?

それだったら
> そんな関数staticにすんな
が答えなんだけど...

962959:02/02/20 01:00
>960,961
レスありがとうございます。
すみません。言葉足らずだったようなのでもう一度。

ええとボタンがクリックされたら
GetListCtrl().SortItems(CompareFunc,pNMListView->iSubItem);
この行から


static int CALLBACK CompareFunc(LPARAM lParam1,LPARAM lParam2,LPARAM lParamSor

int CALLBACK MemListView::CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)

このように宣言された関数を呼んで
sortを行いたいのですが、
これがCompareFuncの中でflagがTRUEならば昇順に
flagがfalseならば降順にと切り分けたいのです。
このようなときflagは
どこに(クラス内かクラス外か)
どのように(staticかそうでないのか)持たすのが一番良いでしょうか?
当て嵌るかどうかは不明だが、このような要求のあるケースとして、
thisをもらえない関数であるウインドウプロシジャー/
コールバック関数からメンバー関数を使いたいということある。
マックならウインドウのプロパティにクラスへのポインタを
セットする。ウインドウのプロパティからそのウインドウを
作成したインスタンスを参照する。
WindowsならばGetWindowLongのユーザーデータを使用したい
ところだなと、マニュアルを見ながら思った。
>962
SortItemsの第2引数で工夫してflagの値も引き渡すようにするのが筋ではないかと。
たとえば、サブアイテムの個数がWORDの範囲を超えないのなら
MAKELONG(pNMListView->iSubItem, flag) としてみるとか。
>>959
そのstatic関数に、該当するインスタンスのポインタを渡してやればいいんじゃないの?
全体がどーゆーデザインになってるのか見当がつかんが。
966デフォルトの名無しさん:02/02/20 02:04
CListViewで項目の間のバーをドラッグしたときにウインドウに
送られるメッセージは何でしょうか?
Spy++を使ってみましたが量が多すぎてよくわかりませんでした。
967デフォルトの名無しさん :02/02/20 02:08
Visual C++ でSTLを使うようになってから
Debugビルドでは平気なのにReleaseビルド
すると計算結果がおかしくりました。私が
悪いのでしょうか?

printf("\n")って入れたらちゃんと動いた
りもします????


>>967
たぶんヒープを壊してる。次のコードを WinMain の直後に追加して、デバッグビルド
でヒープのチェックを有効にしてみ。

_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_LEAK_CHECK_DF);

あと STLport を使ってるなら #define _STLP_DEBUG とかも定義しておくと便利だ。
969デフォルトの名無しさん:02/02/20 10:05
今度からC++をメインで使うプロジェクトに参加することになりました。
よろしく
>966
VCスレ逝け
もしかして
  VC++ == C++
と思ってる奴って多くない?
>971
operator == の定義によると思われ。
g++まんせー
974デフォルトの名無しさん:02/02/20 18:57
boost や loki に tuple ってありますよね,アレって普通の構造体
を使うのに比べて何かメリットはあるのでしょうか?

struct.first_item
ってやるのと
get<0>(tuple)
っていう書式違い以上の違いが厨房な僕には分からないんで,
どなたか教えて下さい.
# まぁ構造体定義せずに済むという利点があるというのは分かりますが.

「利点が分からねーなら使うなゴルァ」と言われそうですが,利点がある
なら知りたいのです.どうぞよろしく.
975デフォルトの名無しさん:02/02/20 21:29
Auto<TCA<int>> temp;

何故にエラーになる・・・???
>> の間に空白入れてっか?
> >

ここにスペースがないと >>演算子とカンチガイしてしまう
978デフォルトの名無しさん:02/02/20 21:42
>>976,977

をを、そうだったのですか。
動きました♪有難うございます♪
979デフォルトの名無しさん:02/02/20 22:26
C言語の基礎を工業高校時代に習ったのですがC++とはC言語の基礎が役にたちますか?
それとも普通のC言語とはまったくの別物ですか?
いまから趣味でプログラムやるならCとC++のどっちのほうがいいですか?
>>979
Cと一緒に勉強するのがいいよ。
このスレではこう答えるけど、
他じゃCやっとけっていいたいところだったり。
981デフォルトの名無しさん:02/02/20 22:44
class CB{
public:
template<typename T>void func(T a);
};
template<typename T>inline void CB::func(T a){};

これがエラーになるのは何故なのでしょうか?
>981
CB<T>::func
にしる!!
何故だかスレッド立てすぎですって怒られた…。

誰か新スレ立てない?
984982:02/02/20 23:40
スマソ思いっ切りウソ付いた
>>981
g++ 3.0.2 だと通るけど。たんに使ってるコンパイラが
メンバテンプレートに対応していないだけなんじゃない?
VSは通らないのですか・・・
残念。