1 :
デフォルトの名無しさん :
01/10/23 19:26
前スレでも聞いたけど、ファイルを読み書きするときに FILE構造体とfstreamとどっちを使ってますか?
>>4 まず、どうして、そういうことを気にするのかを聞きたい。
8 :
デフォルトの名無しさん :01/10/23 20:33
CFileだ
9 :
デフォルトの名無しさん :01/10/23 20:35
>
>>1 v(^・^)v
>なんすか!、コレ!(怒
なんすか!、コレ!(怒
>
>>1 v(^・^)v
意味フメイで怖いんですけど!?
v(^Д^)v ギャハ!
に似てる?ムカツク!
>>1
v(^・^)v やっぱりこれがないと。
v(^・^)v (C++) ノ∪ヽ
v(^・^)v ( * ) ノ∪ヽ
v(^・^)v (∩∩)
∧_∧
v(^・^)v
γ⌒" ̄ `Y" ̄`⌒ヽ
/´ 、 ¥ ノ `ヽ.
/ ,-ュ人` -‐´;`ー イ` ェ-、 ヽ
l 「 } i 彡 i ミ/ { `ノ
` `ー' .} { `ー'´/ ̄ ̄\
/ \|| | グシャ |
/ /`ヽ、 i |i \ _/
/ ノ l| | i| //
\ `ヽ | || /
\ \ l|| l|i | ,, '⌒Y
ノ _>‘、|l |・i/ノ , ノ
>>1 <.,,_/~,-・i |゚;・li。i,・'(__,.J
なんつーか……最近芸術的なAAが増えたな。
∧∧ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ v( ^・^)v < こういう生き物です。 U U \_____________
∧∧ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ v( ^・^)v < ミカン星人に近づいたかな? )) )) \_____________
┌───────── < ガオガオシテナイーヨ v( ^・^)v └───/|──── \.\______// \ 観鈴ちん / ∪∪ ̄∪∪
21 :
デフォルトの名無しさん :01/10/23 20:59
>>5 理由は無いけど、同じ事が出来る手段が2つあるから。
パフォーマンスとかポータビリティとかについてはどうなんだろ?
テキストファイルだとfstreamが便利そう
バイナリファイルだとFILEの方が書きやすそう
という漏れの認識はおかしい?
っていうかどうして荒らされてるの?
fstreamに決まってるだろ。 C++らしい方使っとけ。
23 :
デフォルトの名無しさん :01/10/23 22:22
>>21 VCだと、FILEの方が、かなり軽いね。
∧ ∧ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
v( *^・^*)v <
>>22 FILEに決まってんだろ。
)) )) \_____________
25 :
デフォルトの名無しさん :01/10/24 11:10
最近C++を勉強を始めました。 静的メンバ関数をclassの宣言外にだそうとする(2)と、 >error C2352: 静的でないメンバ関数の中で呼び出しが正しくありません。 なんて言われてしまいます。 静的メンバ関数は、外にだしちゃダメなのですか? -----(1) class mydat { static int num ; public: static int foo(){ return num } ; } ; -----(2) class hoo { static int num ; public: static int foo(); } ; static int hoo::foo() { return num ; }
// MSDN, C2352 指定された関数は静的なメンバ関数ではありませんでしたが、static メンバ関数内で呼び出されています。 次にこのエラーの例を示します。 class X { public: static void func1(); void func2(); static void func3() { func1(); // OK, 静的な関数 func1 を呼び出しています func2(); // エラー, 非静的関数 func2 を呼び出しています } };
27 :
デフォルトの名無しさん :01/10/24 11:37
コンパイラ エラー C2724 'identifier' : 'static' をファイル スコープでのメンバ関数の定義に使うことはできません。 static メンバ関数がファイル スコープで定義されています。static メンバ関数は、外部リンケージで宣言しなければなりません。 この誤りは、Microsoft の拡張機能を使っているとき (/Ze オプション指定) には警告となり、Microsoft の拡張機能を無効にしているとき (/Za オプション指定) はエラーとなります。 次にこのエラーの例を示します。 class C { static void func(); }; static void C::func(){}; // エラー
>>25 class hoo {
static int num ;
public:
static int foo();
} ;
int hoo::foo()
{
return num ;
}
int hoo::num;
>>28 様、ありがとうございます。それで、できました。
30 :
デフォルトの名無しさん :01/10/25 09:35
純粋仮想関数を使用する意味はなんですか?
インタフェースの提供>30 下位クラスでoverrideする
>>31 レスありがとう。
C++勉強したてでよくわからんのです。
純粋仮想関数って、なにもないのと同じじゃないかって思うんです。
枠だけ作って、中は下位クラスで作ろうってことなら、
初めから上位に関係なく下位で作ればすむなんて思ったんです。
なんかメリットは、あるんですか?
34 :
デフォルトの名無しさん :01/10/25 12:10
>>32 よくあるAnimal、Cat、Dogの例で説明すると、CatやDogクラスの
オブジェクトをAnimalのインタフェースを使って呼び出したいが、
Animalは抽象的過ぎて実際の処理をまかせられないので、インタ
フェースだけを定義しておく。
こんな時にC++では純粋仮想クラスを使います。
っていうか、GoF本とか読んだほうがいいかも。
35 :
デフォルトの名無しさん :01/10/26 10:14
Animal クラスに 足の本数を返すメンバ関数を純粋仮想関数で作る。 class Animal { public: virtual int get_ashi() = 0 ; } class Neko : public Animal { public: int get_ashi() { return 4 ; } } class Tako : public Animal { public: int get_ashi() { return 10 ; } } class Ototake : public Animal { public: int get_ashi() { return 0 ; } } と。
36 :
デフォルトの名無しさん :01/10/26 10:38
僕はテストの時に楽できるように、親クラスではデフォルト値を返すようなメソッドを設定して、 純粋仮想クラスにはしないことが多いんですが、なんか副作用とか出てきたりするもんなんでしょうか。
>>36 サブクラスで override を忘れたときに、コンパイラが文句をいってくれない。
個人でやってる分にはどうでもいいけど、複数人で行うプロジェクトの場合には、
「これは絶対にサブクラスで上書きしろ」と主張するために、純粋仮想メソッドに
しておくのが吉。
それに、そもそも「デフォルトの振る舞い」が想定できないケースもある。実装継
承ではなくインターフェース継承を重視するようになると、よくある。
38 :
デフォルトの名無しさん :01/10/26 13:53
39 :
デフォルトの名無しさん :01/10/26 14:22
全スレ900の > string line_buf; > ifstream file("text.txt"); > getline(file, line_buf); > こんなクソコード書いていいのは初心者のうちだけだぞ! がクソな理由を教えてください。今ちょうどこんなの書いてたので……
>>38 えっ?
たしかにインスタンス構築時に vptr を 2 回(親クラスのコンストラクタで一回、子クラス
のコンストラクタで一回)埋めるオーバーヘッドはかかるけど、仮想メソッド呼び出しにか
かるコストは同じだと思うが。
41 :
デフォルトの名無しさん :01/10/26 16:57
>>40 >たしかにインスタンス構築時に vptr を 2 回(親クラスのコンストラクタで一回、子クラス
>のコンストラクタで一回)埋めるオーバーヘッドはかかる
これだけで十分遅くなる&メモリを無駄に使う気がするけど? そういうことじゃなくて?
もっとも、コンパイラ依存だろうけど。無理して継承関係を採用するのをやめてテンプ
レートにすれば抽象クラスにするよりもっとうまくやってくれるかもしれない。
42 :
デフォルトの名無しさん :01/10/26 17:20
>>41 クラスを継承すれば、純粋仮想関数があってもなくても
複数回のvptrのセットが行われるんで、純粋仮想関数が
必要な理由にはならんでしょ?
43 :
デフォルトの名無しさん :01/10/27 17:18
あげとく
>>41 template だとコンパイル時に型が決まっていしまうから多態できないじゃない。Generic Programming
と OO は対立するよりは、むしろ直交する概念でしょう。
それと VC++ 限定ですが __declspec(novtable) という拡張指定があります。これをつけたクラスは
コンストラクタ/デストラクタから vtbl 初期化用のコードが削除されます。
45 :
デフォルトの名無しさん :01/10/27 21:54
int* dat; dat = new int[100]; てすると delete [] dat; しなっきゃいけないのに int dat[100]; だとなんでデリートしなくていいのですか?
46 :
デフォルトの名無しさん :01/10/27 21:59
stackに確保されるから。
>46 サンクス ってもsatcckってなんだかわからんから 勉強してきます push,popとかってやつ?んなわけないか。。。
>>48 スコープっていうと変数の通用範囲ですよね??
スタックにつまれた変数はそのプログラマぐが終わると
かってに開放されて
動的に確保した奴はされないとか???
50 :
デフォルトの名無しさん :01/10/27 22:15
そういうことだ。
>>49 > スタックにつまれた変数はそのプログラマぐが終わると
スタックにつまれた変数はスコープを出ると
だけどな。
>>50 なるほど。。。。
勉強になりました
なんかすごく基本的なことなんだろうけど
目からうろこです
はずかちっ!
52 :
デフォルトの名無しさん :01/10/27 22:25
>>51 スタック上のオブジェクトについても同様だ。もしdeleteしなければ
ならんと仮定すると、std::string なんて使いものにならんと思わん?
(わらい
int d[100]; delete d []; ってできないにょ?
54 :
デフォルトの名無しさん :01/10/27 22:27
質問の意図がわからん。 コンパイル通らないんですけど。 delete[] d; できるか?という意味ならできない。
すいまっせん。。。 std::stringってのがわからないので。。。 なにぶんCc++はじめて二日な門で。。。 勉強してきます!
おれは最初autoオブジェクトが必ずデストラクトされるのが不思議というか、 どうやってスコープを抜けたことを判断してるのか謎だった。 あれは実行時に動的に判断してるんだと思い込んでたから。 動的?んなわきゃねー、と言えるのは今だからこそである。
そうか…。stringの使い方覚えたらCには戻れなくなる(なれる)ぞ。 がんばれ。
>>57 VBやPerlには戻れるかもな(藁
Javaには…戻る方が賢明だったりしてw
どなたか
>>39 にも愛を!気になって先進まないよ〜
60 :
デフォルトの名無しさん :01/10/27 23:29
string使うのはいいが、それなりにパフォーマンスを犠牲にすることは 念頭に置くようにしよーね
61 :
デフォルトの名無しさん :01/10/27 23:45
char*文字列でstrlen連発の方がよっぽど(以下略)
どうせCではsprintfを多用してたから、std::basic_stringに変えたからってそれほど効率が落ちるもんでもない。
63 :
デフォルトの名無しさん :01/10/28 00:09
どきゅんコードによる文字列操作のバグが減るならよいが、 std::string input_data1; std::string input_data2; char buf[1024]; std::string input_data3; strcpy(buf, input_data1.c_str()); strcat(buf, ","); strcat(buf, input_data2.c_str()); input_data3 = buf; とかやられて鬱確定。
64 :
デフォルトの名無しさん :01/10/28 00:11
>>35 を真面目に読んでて最後のオトタケで激しくワラタ
66 :
デフォルトの名無しさん :01/10/28 01:28
>>35 >>64-65 オトタケって何ですか?
それと、タコの足は8本だった気がします。どうでも良い事ですが。
10本はイカだったような?
67 :
デフォルトの名無しさん :01/10/28 01:59
一夜漬け程度でネオ上げるとは情け納屋。
69 :
デフォルトの名無しさん :01/10/28 17:08
float* pfBuf = reinterpret_cast<float*>(pnBuf); のコードの <float*>はキャストでしょうか? C++をコードを読んで勉強しているのですが、 参考書をよんでもちょっと調べられませんでした
70 :
デフォルトの名無しさん :01/10/28 17:11
71 :
デフォルトの名無しさん :01/10/28 17:12
キャストでしょうか?って、わけわかんない日本語 を使ってしまいました どういうキャストなんでしょうか? 「根本的に別の方に変換する」と書いてありますが
>>69 「プログラミング言語C++」は読んだ?
reinterpret_cast はビットパターンを変えずにデータを再解釈するキャストだと思っておけば、
だいたい合ってる。C では型を変える (int -> float とか) タイプのキャストと型再解釈のキャ
ストは両方とも同じ構文を使っていたけど、違いを明確にするために reinterpret_cast が規定
されてる。
73 :
デフォルトの名無しさん :01/10/28 17:13
まぁ、 float* pfBuf = (float*)pnBuf; だと思ってるだけでもいいと思うわ。 とりあえずは。
74 :
デフォルトの名無しさん :01/10/28 17:50
>>72 >reinterpret_cast はビットパターンを変えずにデータを再解釈するキャスト
ビットパターンを変えるキャストって?
int n = (int)5.0f // -> 5
76 :
デフォルトの名無しさん :01/10/28 18:11
>70 >72 どうもです shortをfloatで扱うと,各演算(+-*/%)はどうなるのでしょうか? ちなみにプログラムは以下のうような感じです BOOL CClip::Transform( short* pnBuf, long cSampBuf ) { CCriticalSection cs( &m_csState ); float* pfBuf = reinterpret_cast<float*>(pnBuf); for(int i=0;i<cSampBuf * m_wfx.nChannels; i++) { if(pfBuf[i] > m_p.fClipLevel)pfBuf[i]=m_p.fClipLevel; else if(pfBuf[i] < -m_p.fClipLevel)pfBuf[i]=-m_p.fClipLevel; } return TRUE; }
77 :
デフォルトの名無しさん :01/10/28 18:15
pnBufをdereferenceしてからfloatにキャストしないとダメでわ。
78 :
デフォルトの名無しさん :01/10/28 18:36
ポインタはどうあがいても32ビットのビットパターンだぞよ
>>78 32bit かどうかは処理系依存だし、float* と short* の内部表現が違うかもしれない……という
話は置いといて、
unsigned char *buf;
int *np = reinterpret_cast<short*>(buf);
としたときに *buf, *np が異なるコードを生成することは良いよね? buf を int へのポインタ
として扱うために必要になるのが reinterpret_cast。これをやらんとコンパイル時エラーになる。
80 :
デフォルトの名無しさん :01/10/28 19:09
charのサイズは1。これ、C++の常識だぞよ
81 :
デフォルトの名無しさん :01/10/28 19:35
shortもfloatも16bitですよね という事は、本来floatの値が、shortとして流れて来て ここでfloatとして計算していると言う事かもしれません いろいろなご意見どうもありがとうございました
>shortもfloatも16bitですよね 処理系依存だがな
>>81 単精度浮動小数点は、ふつうは (IEEE の規格に従ってる場合は) 32bit ですって。
おそらく、件のプログラムは pBuf が指しているメモリ領域に、場合によって short やら float やら
各種のデータを詰め込んでるのだと思う。読み出す部分だけではなく、書き込んでる部分も読んで
みては?
84 :
デフォルトの名無しさん :01/10/28 19:50
>>79 内部表現や実装はC++という言語規格とは関係ありません。実装が言語を
規定するのではなく、言語が実装を規定するのです。
>>84 ごめん、言ってることがよく分からん。
reinterpret_cast に関しては実装を踏まえた上で使わないと意味がないと思うが、どうよ?
86 :
デフォルトの名無しさん :01/10/28 20:28
>>83 なるほど
そう言う事かもしれません
書き込む部分探してみます
というかCOMになってて、他からデータ渡される気がします
float32bitですね(^_^;
87 :
デフォルトの名無しさん :01/10/28 20:37
>>84 言語規格は、実装に絶望的なほど影響される。
実装のために削除された提案が多数ある。
プログラムのぷの字もワカラン全くの初心者です。 自分でゲームとかいろんなソフト作れるようになったらカッコいいなと思い C++プログラミングVol.1 H・Mダイテル+P・Jダイテル著を買ってきました。 この本の評価はどの程度なんでしょう?
89 :
サポートパンク :01/10/29 03:58
Cから始めたほうがいいかも〜。
C++からプログラムをやるってのは無謀なんすか? Cの方が簡単なのすかね?
92 :
デフォルトの名無しさん :01/10/29 04:15
>>88 悪くないと思うが、それ読んだあとできちんと「プログラミング言語C++」
も読むこと
93 :
サポートパンク :01/10/29 04:19
VisualStudio.NETベータ版で BCCみたいにコンソールプログラミング って出来ますか?
>>93 C:\Program Files\Microsoft Visual Studio.NET\common7\tools\vsvars32.bat
に環境変数の設定バッチがあるから
あとは好きなように。
cl : C/C++コンパイラ
nmake : makeユーティリティー
csc : C#コンパイラ (おまけ)
96 :
デフォルトの名無しさん :01/10/29 06:09
Cからプログラムをやるというのは、当座はUNIX専門でやるということ でなければ今の時代無意味だよ。 本当はC++をやってからCやJava、C#をやるのがお勧めだが(というの はそれらの言語は大体C++の古いバージョンやサブセット/微少な拡張 として手間をかけずに理解できるので)、最近の状況からすると、 JavaやC#をやってから必要になったらC++なんてのも悪くないかも しれない。アメリカの大学だと最初はJavaってところが増えている ようだから。 CをやってからC++だと、変な癖が付く恐れがあるので、既存のCの 参考書を売ろうという出版社や古い教育者の謀略に乗らない方が 良いと思われ。
97 :
デフォルトの名無しさん :01/10/30 01:54
>107氏 初心者な質問なのですが 「CをやってからC++」というパターンでつく可能性のある 変な癖って具体的にどういう感じなんでしょう。 私はそのパターンで勉強してしまったので 実際もしそういう癖があるなら直したいのですが…。
>>97 「107」って?
C++の参考書の著者にはCくらい先にやっとけと言う者とやらんでよろしいと
言う者の2通り真っ二つに分かれているので、かなり異論が出そうだが。
ま主観的な問題なんでどっちが正解という話でもない。Stroustrupは後者。
- Cプリプロセッサの多用
- グローバル/スタティック-変数/関数、関数ポインタの多用
- Cスタイル文字列ならびにCスタイル文字列関数の多用
- ローカルオブジェクトの先頭宣言
- 異様に長いメンバ関数(とデータメンバの準グローバル変数化)
- private/protected/publicの不適切な使い分け/実装継承の多用
- 別スレのOO不要/C万能/GNOMEサイコー/UNIXマンセー論者の種になる(藁)
なんで濫用が問題かというと、別に禁止されているわけではない
ので少しくらいやっても良い。Cライブラリの文字列関数だって中身
はアセンブリだからそれなりに速い。
他のオブジェクト指向言語では禁止されている物が、C++の場合たま
たま許容されているところを悪用できる点が問題になる。煙草を吸う
ような開放感があるのかもしれない。周囲には少々迷惑をかけるけども。
ただし、他とも協調するための制度もそれなりに備わっている。
C++はリアリティを持った、自由な大人のための言語だから好きだ。
99 :
デフォルトの名無しさん :01/10/30 04:31
>>98 「自由な大人」が二人集まると,お互いの自由が相手を束縛することに
気がつく。そこで喧嘩せずに目標を達成するためにルールを作る。
ルールのある言語を使って協調するか
協調するためにルールを作るか。
結局、最後に行き着くところは同じさ。
100 :
デフォルトの名無しさん :01/10/30 05:23
C++Builderの無料版かKylixのC++版が出れば、C++から始めろと言えるのだが。
Cライブラリの文字列関数ってCで書かれたソースがどこかにあったような...
102 :
デフォルトの名無しさん :01/10/30 16:01
現在,C++で画面を100×100のブロックに分割して,指定された ブロックから指定されたブロックまでの経路の全通りを作り出す プログラムを作っています.これを作るアルゴリズム難しくてで きません.どうしたらよいのでしょうか?
103 :
デフォルトの名無しさん :01/10/30 16:03
>>100 C++ builderのコマンドライン版でないということは、無料のGUI開発
環境でなきゃ駄目ってこと? 探せばそれなりにあると思うけど。
338 名前:心得をよく読みましょう :01/10/14 22:17 ID:5r0xorkP ひろゆきもそろそろ管理人としての姿勢を見直すべき 珍走団がひろゆきに土下座をさせたのは、荒らしの責任を取らせたのではなく あくまでも、ひろゆきの電話での態度について落とし前をつけたまで 日本生命やINSIのように、安全を確信できる相手には、イキガッテみて、 珍走団のように理屈の通じない相手には遜って土下座までするようでは あまりにもカッコワルイ
>>99 >ルールのある言語を使って協調するか
>協調するためにルールを作るか。
>結局、最後に行き着くところは同じさ。
本当に同じか?
ルールを毎回一から作るより、再利用する方が効率的だよね!
ルールを必要としない言語が良いYO!
>>99 C言語だと配列の上限ルールが居る。から、プリプロセッサに頼る。
110 :
デフォルトの名無しさん :01/10/30 19:59
C++でファイル(HD)に書き込む動作を含むプログラムを 作ろうと思っているのですが linuxとwindowsで違いますか?
>>102 最短距離だよね?
●○○○○○
○○○○○○
○○○◎○○
○○○○○●
黒丸から黒丸まで行くとすると、(◎は障害物)
→5回
↓3回の全ての組み合わせから
◎の通る、組み合わせを引けばいいのでは?
5×3の全通りの配列を作って、右=1、下=2みたいな感じで。
11111222
11112122
11112212
・・・
・・・
こっから、最初の5個を見て、右3下2のを取り除く。
11111222→11111→OK
11112122→11112→OK
・・・
・・・
11122112→11122→だめ
・・・
ってなところじゃね?
問題自体が違ったらすまん
これからVisualCとか普通のCとか勉強したいと思ってるんですけど 初心者にも分かりやすい入門書 ありますか? ホントにアホみたいな質問でスマソ
>>112 すいません。最短距離ではないのです。
一度とおったブロックは通過しないのですが、
●○○○○○○
○○○○○○○
○○○○○○○
○○◎○○●○
○○○○○○○
○○○○○○○
障害物を回避するときに
↓4回、→5回、↑一回って経路も必要なのです。
>>113 入門書よりも、作りたいと思う物が無いならやっても無駄。
>>114 キーワードは再帰。スレ違いだから、続きは宿題スレなどで頼む。
117 :
気になる新刊情報 :01/10/31 06:23
やはりMoreなのね・・ More Exceptional C++: 40 New Engineering Puzzles, Programming Problems, and Solutions 発売予定日は 2001/11/23 です。 価格: ¥4,121 んでこれ。上の入れて5冊全部入っとる・・。 C++ In-Depth Box Set 価格: ¥17,076 発売予定日は 2001/12/07 です。 コードきれいなってるのかな。 Bundle of Algorithms in C++, Parts 1-5: Fundamentals, Data Structures, Sorting, Searching, and Graph Algorithms Robert Sedgewick (著) 価格: ¥8,832 発売予定日は 2001/12/28 です。
>>115 とりあえず勉強したいんです、
色々応用の利くような気がして・・・
119 :
デフォルトの名無しさん :01/11/01 09:28
クラス内のconst配列を初期化したいのですが、 どう記述したらよいのでしょうか?
120 :
デフォルトの名無しさん :01/11/01 09:33
const int a_class::table[] = {0, 1, 2, ...};
>>120 ありがとうございます。
その方法は知りませんでしたが、私がやろうとしているのは
staticではないconst arrayの初期化です。
要素も大量にあるので、すべて記述するのには抵抗があります。
122 :
デフォルトの名無しさん :01/11/01 09:58
const_cast〜
>>112 for(int i=size-1; i>=0; i--) { const_cast<int*>(table)[i] = INITIAL; }
こういうことですね?ありがとうございました。
126 :
デフォルトの名無しさん :01/11/01 21:52
VCだとクラスのメンバに const変数つくれないの?
>>126 つくれるよ。初期設定もコンストラクタで簡単にできる。
上のはconst配列の初期設定の話だが別の話か?
129 :
デフォルトの名無しさん :01/11/01 23:03
値を決めるのを コンストラクタでやらなきゃいけないとか? class A{ public: const int a=8; } ってやるとエラーが出る
130 :
名無しさん++ :01/11/01 23:24
>>129 > 値を決めるのを コンストラクタでやらなきゃいけないとか?
そうです。
> 9.2 Class members
> 4 A member declarator can contain a constant initializer only if it declares a static member (9.4) of integral
> or enumeration type, see 9.4.2.
というわけで、次の選択肢からお好きなものをどうぞ。
1. コンストラクタで初期化する。(実体が複数必要な場合)
2. 変数を static にする。(実体が一つ必要な場合)
3. enum にする。(実体は不要で、値だけあれば良い場合)
なお 2 に関して、規格では
class A {
static const int a = 8;
};
という書き方が許されていますが、残念ながらこれは VC ではコンパイルできません。宣言と定義を
分離して、次のように書き換えてください。
class A {
static const int a;
};
const int A::a = 8;
aho VC sine
VC7でもコンパイルできなかたよ・・・。
ANSI(だっけ?)C++にもっとも準拠していると思われるコンパイラって、どれになるんでしょ。
>>133 私は使ったことはありませんが Win32 では CodeWarrier の評判が良いようです。Modern C++ Design
というテンプレートの限界に挑んでるような書籍があるのですが、これのサンプルコードは
- CodeWarrier Pro 6.0
- Comeau C++ 4.2.38
- KAI C++
でテストした、とのこと。
>>134 thx!
CodeWarrierかぁ。見直したぜ。
VCもgccも便利だから手放せないけど、もうちょっとテンプレート周りはなんとかならないものか。
>>128 これでもできるよ
---aaa.h---
class A{
public:
A();
~A();
const int a;
}
---aaa.cpp---
#include "aaa.h"
const int a = 8;
A::A() { ... }
A::~A() { ... }
つまりコンストラクタじゃなくても初期化できるよって事
すいません上のは無視してください 思いっきりがいしゅつでした しかもstatic付け忘れてるし討つだし膿
手元の資料では、分からなかったので教えてください。 純粋仮想関数の関数定義は、ANSI/ISOではどういう扱いに なってるんでしょうか? gcc だとコンパイルが通って、定義した関数が普通に呼べてます。
>>138 意図が良くわからないので、
- サンプルコード
- それが、どう動作するべきだと思うのか? 実際にはどう動作しているのか。
を書いてもらえませんか?
>>139 コピペではないので、誤字脱字は勘弁して下さい。
class abst
{
virtual void pvf()=0;
};
void abst::pvf() {}
class deriv : public abst
{
void f() {abst::pvf();} // 呼べる
};
私自身は、どう動作してもいいと思うのですが、
ANSI/ISO での、純粋仮想関数呼び出し時の扱いを押さえて
おきたいと思い、書き込みました。
>>140 純粋仮想関数は宣言だけでなく定義もできたのですね。初めて知りました。
> 10.4 Abstract classes
> 2 (略) A pure virtual function need be defined only if explicitly called with the qualifiedid
> syntax (5.1).
規格書には上記のように書いてあるので、純粋仮想関数を定義した上で、クラス名を明示して呼び
出すことは想定されているようです。
別のスレッドでも書きましたが ANSI C++ の規格書は英語の PDF 版でよければ $18 で購入できます。
こういう事態に備えて、一つ手元においておくと便利かと。
ISO/IEC 14882
Programming languages -- C++
http://webstore.ansi.org/ansidocstore/product.asp?sku=ISO%2FIEC+14882%2D1998
142 :
デフォルトの名無しさん :01/11/02 02:46
単に仮想関数扱いされてないようだが。というかそんな コード実際書いてなんの役に立つの。
144 :
デフォルトの名無しさん :01/11/02 03:04
C++って自分の知らない仕様が見つかるのはよくあることですか?
145 :
デフォルトの名無しさん :01/11/02 03:49
146 :
デフォルトの名無しさん :01/11/02 04:20
>>145 異ならないよ
まPDF版もってても損はないがコピぺできないようにプロテクトされてないかい
147 :
デフォルトの名無しさん :01/11/02 09:05
JISのC++の規格ってないの?
>>140 オレもミスって純粋仮想の関数内容書いたことある。
派生クラスでは普通にオーバライドできて動作的に問題は無かった。
だからなかなか気づかなかった。コンパイラはVCとgcc
あ、規格でオッケーなんだ・・・。 むしろコンパイルエラーにしてほしい・・・。
150 :
デフォルトの名無しさん :01/11/02 11:12
>>142 派生クラスで独自に定義してほしいけど、ディフォルトの実装は用意しておきたい
ときに使います。
ディフォルト実装はprotectedなメンバにしておいてもいいけど、余計なメンバ関数が
増えてイヤな人とかは、定義のある純粋仮想関数を使ったりします。
151 :
デフォルトの名無しさん :01/11/02 11:34
んー、結局 定義のある純粋仮想をオーバーライドした場合と 普通の仮想関数をオーバーライドした場合で 違いはあるの?
152 :
デフォルトの名無しさん :01/11/02 13:08
>>151 オーバーライドした場合に違いはない
ただ、定義があったとしても純粋仮想関数を持ったクラスの派生クラスは、
明示的にオーバーライドしないと抽象クラスになる
153 :
デフォルトの名無しさん :01/11/02 13:35
>>151 ない。オーバーライド「しなければならない」か「しなくてもいい」かの違いだけ。
154 :
デフォルトの名無しさん :01/11/02 13:49
ああ、なるほど。
くいちがってないでしょ。
>>153 はちょっと言葉が足りないけど。
性格には、インスタンス化するならば「しなければならない」
つまり、オーバライドしなければ抽象クラスになる。
だよね?
156 :
デフォルトの名無しさん :01/11/02 20:15
クラスを複数のファイルに分けてるんですが こんなエラーでてしまいます Base.h class Base{ 〜〜 }; Der1.h class Der1 : public Base{ 〜〜 }; Der2,h class Der2.h : public Base{ 〜〜 }; main.cpp #include "Der1.h" #inlucde "Der2.h" Base.h(7) : error C2011: 'Base' : 'class' で示される型としてすでに 定義されています。 どうしたらいいでしょう?
>>156 #ifndef か #if !defined つかいなはれ。
158 :
デフォルトの名無しさん :01/11/02 20:44
main.cpp #include "Base.h" #include "Der1.h" #inlucde "Der2.h" でいいだろ。 だがそれ以前に、本当に継承しなきゃいかんのかと、聞きたい。 問いつめたい。
>>156 それもよくわからないので
ちょっと調べてみます
>>158 勉強中なので特に意味はないのです。。。
>>160 こんな風に各ヘッダにおまじないしておけば、一度読み込まれたヘッダが
二度読み込まれることがなくなり、再定義errorを防げるんだよ〜。
>>157 (INC_BASEとかの名称はお好きなものを)
Base.h
#ifndef INC_BASE
#define INC_BASE
class Base{
〜〜
};
#endif
↑俗称: インクルードガード
>>162 適当な名前でインクルードガードをつけると、あとでハマルことがあるので注意ね。昔 "Types.h" と
"DLib/Types.h" が両方 _H_TYPES_ というインクルードガード使ってたことが(元々別のプロジェクト
から持ってきたファイルだから、仕方ないんだが)。
私はファイル名と GUID からインクルードガードの文字列を作るプログラムを書いて、使ってます。
164 :
デフォルトの名無しさん :01/11/03 01:24
_で始まる名前は予約語だっつーの。 K&R嫁。 K&R読んで理解スレ。
>>164 C++ スレで K&R 読め、というのは初めて見たが(w
>>166 164 が何を憤ってるのか良く分からんが(_H_TYPES_ なんてつけたの俺じゃないぞ) _ で始まる名前は
使わんほうが良いというのは正しい。ANSI C++ の規格書から抜粋ね。
17.4.3.1.2 Global names
1 Certain sets of names and function signatures are always reserved to the implementation:
- Each name that contains a double underscore (_ _) or begins with an underscore followed by an uppercase
letter (2.11) is reserved to the implementation for any use.
- Each name that begins with an underscore is reserved to the implementation for use as a name in the
global namespace.
168 :
デフォルトの名無しさん :01/11/03 02:00
>>167 __はまるきりだめで
M_aとかも駄目なんですね。
テンプレート仮引数とかも分けたいと思うから
悩み増えます。本当はSGI風のまねたかった。
169 :
デフォルトの名無しさん :01/11/03 02:06
__で始まる名前と _ + 大文字 で始まる名前がダメ、といっているように読めるが?
>>167 うわ、、、ちょっとビツクリ
_fooみたいなグローバルな名前はダメそうだと思っていたんだけど、
_Foo とか hoge__hoge みたいのはあらゆるところでダメ(であってる?)
ていうのは初耳・・・
で、これってマクロにも当てはまるの?
>>170 > で、これってマクロにも当てはまるの?
当てはまるでしょ。
たとえば cygwin だ <errno.h> に関数 __errno() の宣言が書いてあります。もし、ユーザが
#define __errno 1
なんてマクロを定義して <errno.h> を include すると、宣言部分でエラーになりますよね。
それに、標準ヘッダのコードガードとかち合う可能性もありますし。
>>171 そういえばそうですね・・・
いままで
#ifndef __MyTools_h
みたいなやつでいっぱいくくってるよ・・・まあ、かち合わなきゃいいや
173 :
デフォルトの名無しさん :01/11/03 10:13
constは確かにstaticにするべきですね 勉強になりました 3つも方法を教えていただきありがとうございました
174 :
デフォルトの名無しさん :01/11/03 14:57
クラスの中でクラスの定義を行っていて、中のクラスから 外のクラスのメンバにアクセスしたいのですが、 class A{ int a class B{ void b(); } } void A::B::b() { A::a = 2; } でb内でaにアクセスしようとしたら、 「スタティック メンバ関数内の不正なデータ メンバへの参照です」 と言われて、怒られてしまいます(コンパイラはVC6)。 この場合、A::aにアクセスする方法はあるんでしょうか?
177 :
名無しサソ :01/11/04 09:37
すみません。忘れていたのでageます。
やりたいことが良くわからないが、一応これでコンパイルはできる。 class A { public: static int a; class B { public: void b(); }; }; int A::a; void A::B::b() { A::a =2; };
Bが定義されてる場所は特に関係なく、 たんにstaticメンバ定義方法が間違って板だけ。
あ、早とちりしたかも。 staticにしたくないのなら、たとえばこんな方法。 class A { public: int a; class B { public: void b(A& arg); }; }; void A::B::b(A& arg) { arg.a = 2; };
181 :
デフォルトの名無しさん :01/11/04 11:08
>>180 A::A() : B(this) { }
ってやるの?
たしか、この位置でthis使っちゃいけないはずだけど
>>181 んー、どーもやりたいことが良くわかんないけど
クラスBは何のためにネストしてるの?
AはメンバとしてBを持ってないの?
いや、俺は176じゃないっす。 ただ、文法的に間違いだと思ったから突っ込んだだけ
>>183 まちがってないよ、コンパイルできたし。
>>180 で定義されてる void A::B::b(A& arg)をコンストラクタと
勘違いしてない?
そもそもこの定義だけだと、
たとえばMain関数でAをインスタンス化してもBのインスタンスは
どこにもできない。別途作る必要がある。
だから
>>176 の意図をもっと聞かないと、どうしたいのか良く分からない。
186 :
エディタを作ってます :01/11/04 12:56
あの、C++じゃなくてCの方だと思うんですが、教えて下さい。 c=getch()のループでキー入力を取得しているのですが、 altとctrlとescが入ってきません。 こういった特殊なキーを入力するにはどういった関数を使えばいいのでしょうか? コンソールなので、メッセージ処理以外の方法で教えて下さい。
面倒くさいなら、cursesでkeypad()
189 :
login:Penguin :01/11/04 13:57
あ、違うっていっても、ほんの少しね。字句の修正レベルがほとんど。
>182 >185 スマソ。書き忘れです。 class A{ int a class B{ void b(); } B *b; } と言う感じで、Bのポインタを持たせて、Aのコンストラクタが 呼ばれた時点でnewしようとしています。クラスBは継承された 描画関数で、Aは物体です。で、Aを描画するために、Bで継承 してオーバーロードした関数内に、Aのメンバ変数が欲しいな、と・・・。 AはBと大きく違うし、複数のBみたいなクラスを持っているので、 描画クラスから継承したくはないと思っています。 初期化したときにクラスAのポインタをコンストラクタでクラスB に突っ込む事で動作するようにはなりましたが、こんな汚い方法 以外で出来ない物かと。
やっぱり、Class BをAの中でネストト定義する理由がわからない。 外で定義したほうが、変な制約つかなくていいと思うのだが。
こんな感じじゃだめなのかな・・・ class Picture { public: int data[256]; }; class Canvas : class Graphics { public: void Draw(Picture& p){/*pをCanvasに描画*/} }; int main() { Canvas canvas1; Canvas canvas2; Picture pic; canvas1.Draw(pic); canvas2.Draw(pic); return 0; }
>>191 描画対象のオブジェクト
描画方法
それぞれ独立したクラス階層で管理して、最終的にまとめたい、と。それだとコンポジション使う
場面だと思うなぁ。
class AObject { /* */ };
class DrawImpl1 { /* */ };
class DrawImpl2 { /* */ };
struct ObjectInterface {
virtual void doSomeThing1() = 0;
virtual void doSomeThing2() = 0;
/* */
};
class A
: public ObjectInterface
{
AObject aobj_;
DrawImpl1 draw1_;
DrawImpl2 draw2_;
void doSomeThing1() {
draw1_.doSomeThing(aobj_);
}
void doSomeThing2() {
draw2_.doSomeThing(aobj_);
}
};
誤 class Canvas : class Graphics 正 class Canvas : public Graphics
みなさん、どうもです。C++は触って結構経つのに、未だに 仕様を使い切れてない物で・・・。 >192 >193 言われていることを見ると、外のクラスのメンバにアクセスできる 訳じゃないので、ネストは確かに間違いっぽいですね。 要は、そのmainで定義・処理されている部分を隠蔽したい(canvas をpic内部に持ちたい)、と言う話なんですよ。となると、>194で 書かれている方法に切り替えた方が良さそうですね。
delete 0; って無害だったっけ? 即答で頼む。
無害。
どこかにcursesでダイアログボックスみたいのを出せたり、 メニューをつけたりできるようなクラスないですか?
早く教えて!! 昼休みが終わっちゃう!!
203 :
名無しさん :01/11/05 12:25
きっと、複雑怪奇なマクロが前スレで#defineされてるんだよ。
205 :
デフォルトの名無しさん :01/11/06 00:55
int i = 0; cout << i++ << i++ << i++ << endl; の動作の合理的な説明してください。
207 :
デフォルトの名無しさん :01/11/06 01:02
>>205 お?てっきり012って出力されるかと思ったんだけど
210って出力された。なんで?
209 :
デフォルトの名無しさん :01/11/06 01:28
>>208 それで207のようになるのは不思議。
これは不定ってことだよね?
210 :
デフォルトの名無しさん :01/11/06 02:05
207です。
>>209 コンパイラによって結果が違うの?
ちなみに私はLinuxのGCCでコンパイルして試しました。
>>210 結合順序の問題だから、不定ってことは無いと思われ。
212 :
デフォルトの名無しさん :01/11/06 02:18
う〜ん、なんだかこんがらがってきた・・・ 職業プログラマさん達には常識的な知識なのかな? 私はただいまC++勉強中なんで208を理解するには 時間がかかりそう。
213 :
デフォルトの名無しさん :01/11/06 02:19
複数行に分けて記述すれば済むだろう。
ガーン。 今度のプロジェクトでSTLの使用禁止令が出てしまった。 用意されてるのはイテレータも無い、出来の悪いlistとmapだけ。 vectorを使いたいと言ったら、代替クラスを作れだと。 STLportでいいじゃん・・・。 愚痴スマソ。
216 :
デフォルトの名無しさん :01/11/06 13:28
>>221 不定というか、処理系依存というか。
いずれにしろ、そういうコードは書かない方が。
218 :
デフォルトの名無しさん :01/11/06 14:03
ちょっと問題がわからないので質問です。 bbbbatttooのような文字列をb5a1t3o2のように文字種と連続回数で書き表すことによって 文字列の長さを圧縮する方法を連長圧縮という。 aからyまでの文字を1文字づつ入力として受け付け、zが入力されるまでこれを繰り返す。 連長圧縮を行って結果を出力せよ。 例:入力 a a u 出力 a2u1 やり方がぜんぜんわからないので、教えてください。
219 :
デフォルトの名無しさん :01/11/06 14:03
>>215 STLのvectorのコードそのまま持ってきて「代替クラスです」って言い張るとか。
220 :
デフォルトの名無しさん :01/11/06 14:10
>>218 まず連長圧縮の内容を理解する
↓
(プログラムでやる代わりに)自分の頭でその処理をやるとき、どういう風にやるか考えて、紙に箇条書きする
↓
そのままプログラム化
↓
(゚д゚)ウマー
221 :
デフォルトの名無しさん :01/11/06 14:23
う〜ん、文字を使うやり方はなれていないので・・・ charを使うんですよね?
理由は「信頼性が無いから」だって。 既存のSTLのvectorを使いたいなら、 ・信頼性を証明して ・性能を検証して ・是非使いたい理由を提示しろ ということらしい。 auto_ptrならともかく、vectorだったら問題ないと思うんだけど・・・。 ちなみに会社はF系列です。ここはこんなんばっか。 驚くことに、stringの代替クラスまでありました。 素直にstring使えよ・・・。
223 :
デフォルトの名無しさん :01/11/06 15:00
>>222 既存のvectorの代わりに自分で作った代替クラスなら
信頼性があるんだ・・・・・・ふーん。へーぇ。
ぜひ使いたい理由:
「既にあるものを使わず同じ物を新しく作ると、無駄な時間がかかる。
無駄な時間がかかるということは、無駄な金(人件費)がかかる。
我々には無駄に浪費できるほど金が余っているのでしょうか?」
金が余ってるなら、それでいいです。別に異議はありません。
>218 ランレングス圧縮は簡単よ。 この前までちゃんとソースも提供したり、書き上げたりもしたけど、 これじゃ学生クンのためにはならないと気づき、ヒントのみにするヨ ランレングス圧縮は、連続した文字列を記号と数で表現するものナノヨ。 例えば、aaaabbcだと、a4b2c1となるわけネ。 アルゴリズムは 1:n = 1 ↓ 2:文字を受け取る ↓ 3:文字列(ファイル)の終端? YES→goto 9 NO→goto 4 4:次のに取得される予定の文字は同じ文字か? YES→goto 5 NO→goto 7 5:nをインクリメント ↓ 6:goto 2 7:"入力された文字"'n'を出力 ↓ 8:goto 1 9:"入力された文字"'n'を出力 ↓ 10:end ソラで書いたから間違ってるかもネ
漏れも工房時代に自作AVGの画像圧縮をしたいが為に ランレングスヤッターヨ。あの頃はPC98でした・・・ 鮪真似たりいろいろやったよ。 今じゃ一端のアウトローなゲームプログラマですわ(;´Д`) ガンバレ学生タン!
226 :
名無しさん :01/11/06 15:24
C/C++で、Excelファイルを扱う際に、 列(A,B、C,・・・)を選択するには どうしたらいいでしょうか? 普通にやるとA列のみに格納されます。
>>222 プラットフォームが書いてないけど、
特殊な環境向けならコンパイラちゃんとしてなくてもおかしくないし。
それでSTL使って問題が起きた時に、
「STLのバグなのでどうしようもありません」とか言われると困る。
>>227 >プラットフォームが書いてないけど、
Solaris8のForte6とかいう奴らしいです。
SolarisのC++は初めてだけど、そんなにダメダメなんでしょうか?
>>228 標準じゃなくて、STLPort使用するようにすれば?
こっちは実績もあるから。
>>229 そうか、そうですね。
駄目もとでSTLportの使用を主張してみます。
231 :
デフォルトの名無しさん :01/11/06 18:13
218です。 やっぱりランレングスのプログラムだけはうまくかけません。 大体わかったのですが、一度にすべての文字を出力する方法がわかりません。 たとえば、a3d2f1のようにできないのです。 この問題だけは終わらせないとマズイのでマジでヘルプです〜。
233 :
デフォルトの名無しさん :01/11/06 20:28
>>231 224の方針でプログラムが書けたんだね?じゃああとは、
結果を逐一coutに出力せずに、適当なstrstreamに出力するように変更。
最後にその内容を一気にcoutに出す。てなかんじでオーケー。
WindowsAPIの CreateFontIndirect(&lf) LOGFONT lf; の使い方教えてください。
236 :
デフォルトの名無しさん :01/11/06 22:10
delete [] obj_array を使って疑問に思ったのですが 何でこれでクラス配列に割り当てたメモリが全て解放されるのでしょうか? それと、delete base で、baseが派生型へのポインタの場合(実体は違うクラス) 問題が生じますか?
237 :
デフォルトの名無しさん :01/11/06 22:33
>>236 割り当てたアドレスの始端 & 割り当てたサイズ
が把握できていれば型は関係ないと思うが。C/C++では配列 = ポインタ
として扱うことができることから類推できないか? 配列といっても
JavaやC#なんかとは違う。
238 :
デフォルトの名無しさん :01/11/06 22:38
>>236 実装によると思うけど、メモリブロックのサイズを調べて、
その先頭から最後まで順にデストラクタを適用するだけじゃない?
VC++でアセンブリコード吐かせてみたらそうなってた。
baseのデストラクタがvirtualなら問題なし……だと思ったが。
239 :
デフォルトの名無しさん :01/11/06 22:51
>メモリブロックのサイズを調べて、 まだ、私はメモリがどう扱われているかわかっていないようです メモリブロックのサイズを調べるのは,コンパイラですよね >割り当てたアドレスの始端 & 割り当てたサイズ a[10] だと、aがベースアドレスで 配列の添え字と型で、アクセスするアドレスを決定するのですよね? だから、 delete a[10] ならわかるのですが delete [] a というところが,納得いかないのです 例えば del(A a){ delete [] a; } なんてのもありなわけです
241 :
デフォルトの名無しさん :01/11/06 22:54
>>239 | メモリブロックのサイズを調べるのは,コンパイラですよね
よくある実装ではメモリブロック自身にサイズ情報が含まれており
delete[]が実行時にメモリサイズを調べている。
243 :
デフォルトの名無しさん :01/11/06 23:14
WindowsXPで他のユーザーがログオンしているかどうかってどうやって調べるの?
244 :
デフォルトの名無しさん :01/11/06 23:16
245 :
デフォルトの名無しさん :01/11/06 23:22
STLスレが死んでいるのでこちらで質問です。 std::listとstd::map を例外安全かつ中立な実装にできないかな? 型引数として渡されるクラスが例外安全・かつ中立であると 仮定しての話でよいです。 すでに、例外安全だったら素マン。出直してくる。
246 :
デフォルトの名無しさん :01/11/06 23:23
>>244 ありがとう〜。
ネタでなくドキュソを承知で聞きます。システムコールってなあに?
247 :
デフォルトの名無しさん :01/11/06 23:24
>>245 話についてけない厨房ですんません。
例外安全でない実装ってどのあたりか教えてー。
うっ 複数要素の挿入を除いては安全かつ中立であると、書いてあった。 というわけで、出直してきます
250 :
デフォルトの名無しさん :01/11/07 00:26
ExceptionalC++をオススメしておく。
>>248
252 :
デフォルトの名無しさん :01/11/07 01:04
「例外安全」「中立」ってなに? 用語がわからん
例外安全
例外発生時にもリソースが適切に解放され、かつ一貫性が保たれること
例外中立
例えが委を処理しない場合、呼び出し側で処理できるようにその例外を伝えること。
C++を使う上で設計にも関わるくらい大切なことみたい。
>>250 の本を読んでみてね。
254 :
デフォルトの名無しさん :01/11/07 01:19
>>253 > 例外安全
> 例外発生時にもリソースが適切に解放され、かつ一貫性が保たれること
「リソースが適切に解放され、かつ」は冗長。
>>253 ・・・それって、当たり前にそうあるべきことじゃないの?
257 :
デフォルトの名無しさん :01/11/07 01:32
コンストラクタ、デストラクタ。 演算子オーバーロード。 テンプレート。 これらのキーワードと例外処理くんの民族紛争の話です。
258 :
デフォルトの名無しさん :01/11/07 02:03
クラスの関係にis_a(継承)と has_a(インスタンス保持)ってあるじゃん。 あれの使い分けがようわからん。 なんかhas_aばっかしになる私はDQN?
つーか、基礎英語ヤレ。
260 :
デフォルトの名無しさん :01/11/07 02:31
スレッドセーフなので エクセプションセーフの方が良かったかも いや例外セーフか。 やっぱ例外安全か。
is-a has-aって久々に聞いたなぁ
>>258 委譲やコンポジションを使いこなしているならOK
VCで, CMap <int,int,CArray,CArray&> Fx; って宣言すると,CArrayが引っかかる.なぜ? 使い方が根本的にまちがってるのかつら?
264 :
デフォルトの名無しさん :01/11/07 09:08
>>263 CMap<int,int,CArray<int,int>,CArray<int,int>&> Fx;
>>255 いいえ。
例外安全にしようと思うと、メソッドのインターフェースから制限されてしまう場合もあるし、特に
テンプレートが絡む場合には設計の難易度が上がります。例外が発生したら「例外が発生し
ました」という情報だけ伝えることにして、例外を発生させたインスタンスは以後は使えないこと
(デストラクトだけは可能)にするという選択もアリです。
266 :
デフォルトの名無しさん :01/11/07 11:46
igoire , tolower, boolalpha... これってみなさん何て呼んでます?
267 :
デフォルトの名無しさん :01/11/07 14:21
268 :
デフォルトの名無しさん :01/11/07 14:23
>>265 適切にデストラクトできるという保証をするには、
それなりのコストがいるので、どうせやるならはじめから
強い保証を行うべきだと思ってる。
たとえばスレッドのハンドルを管理するmapのようなコンテナクラスが
あったとして、新しいスレッドの追加時に例外が発生したら、
それ以降はデストラクトしかできませんよ、というわけにはいかないよね。
mymap<threadhandle> threadmap;
threadmap.insert(CreateThread()); // ここで死んだらどうする?
単純なクラスであればそれもいけるかもしれないけど、
すべてがすべて、失敗したらプログラムも終わり(後始末も無し)
ってわけにはいかないよ。
269 :
デフォルトの名無しさん :01/11/07 14:24
質問です。 ストリームとは何なんでしょうか?cout等はストリームを操作しているらしいのですが・・・・・ いまいちピンときません。 tcpのストリームとは全く違った概念なんでしょうか?
270 :
デフォルトの名無しさん :01/11/07 14:34
どっちも広い意味でのストリームだが、扱うものも意味も違う。
>>268 > 単純なクラスであればそれもいけるかもしれないけど、
> すべてがすべて、失敗したらプログラムも終わり(後始末も無し)
そもそも 265 は
「すべてのクラスが堤外安全」でなくてもいい
であって、
すべてのクラスが「例外安全でなくても」いい
ではないと思われ。
リソースとしてメモリしか使わないコレクションクラスの類はともかく、ハードウェアと密接に絡むような
操作だと、一度発行したら容易には元に戻せないこともあるし。
272 :
デフォルトの名無しさん :01/11/07 14:41
274 :
デフォルトの名無しさん :01/11/07 15:17
初歩的な事だと思うんですけど整数を表示させる時10桁以上の整数は どのようにすればいいんでしょうか? 教えて下さい
275 :
デフォルトの名無しさん :01/11/07 15:50
>>274 64ビットの整数演算は「long long」や「__int64」などで使える場合が多いです。
(処理系によって違うので、ドキュメントなどで調べてください)
64bit以上の数十、数百桁の演算を行う場合は、それ用のライブラリを用意する必要があります。
ネットで公開されていると思いますので「多倍長」などの言葉で検索をかけてください。
276 :
デフォルトの名無しさん :01/11/07 16:16
>>275 ありがとうございました。自分はUNIXでやってるんですけど
long long int a=10000000000
みたいな感じでいいんでしょうか?
277 :
デフォルトの名無しさん :01/11/07 16:22
>>276 gccだったら、それでOKです。
printf()なんかで表示するときは、%dじゃダメっぽいので、
気をつけてください。
278 :
デフォルトの名無しさん :01/11/07 16:26
long long int で定義したらこのようなエラーが出ました、なぜなんでしょうか? syukudai.cpp:17: integer constant out of range syukudai.cpp:17: warning: decimal integer constant is so large that it is unsigned
>>276 ビット長は処理系依存なので、環境も明記したほうが良いと思われ。64bit 版 Solaris だと long で
64bit, int 32 bit だったりするし。
280 :
デフォルトの名無しさん :01/11/07 16:32
家のパソコンで宿題してるのでlinuxです
>>278 1000000000 とか書いても、それは「int 型の定数」だから。整数の型を明示したければ、適切な
サフィックスを付けないとダメ。
>>280 で、CPU は Alpha なんですか?
282 :
デフォルトの名無しさん :01/11/07 16:38
すいませんペンティアム3です
>>282 x86 アーキテクチャの Linux だと、int 32bit, long 32bit, long long 64bit ですね。gcc では long long 型の
整数定数は、サフィックス LL をつけることになっています。
long long int a=10000000000LL;
これで試してみてください。
284 :
デフォルトの名無しさん :01/11/07 22:20
>>266 igoire : アイゴイレ tolower : トゥロワー boolalpha : ブーラルファ
全部てきとー・・・
285 :
デフォルトの名無しさん :01/11/09 21:45
string型とwstring型の相互変換のやり方を教えてください〜。
>>285 どういう相互変換よ? 文字コード含めた変換はプラットフォーム
依存のAPIかライブラリつかえや
「C++実践プログラミング」って本持ってる人います? 面白いかどうか聞きたいのですが。
>>288 オライリーのやつ?あれは「面白い」かどーかだったら「面白くない」と思うよ,漏れは.
Effective C++ とかの方が面白いと思うけど.
まぁ悪くは無いけどね.
Exceptional C++はおもしろいよ
291 :
デフォルトの名無しさん :01/11/10 11:59
>>289 そっか。ありがと。
Effective C++はとっくに読んでるので、
とりあえず、Exceptional C++読むことにするよ。
>>287 seylocaleを忘れるとハマるよね‥‥
293 :
デフォルトの名無しさん :01/11/10 23:05
継承を制限するJavaでいうclass修飾子finalと同じ働きをするものはありますか?
>>293 無い.
C++ Gems あたりで
/* final */ とコメント入れてるのを見たことがある.
ドキュメネトでやるしか無いってことね.
privateで継承して、元publicメソッドをpublicで全部くくり直す……駄目か
298 :
デフォルトの名無しさん :01/11/11 08:32
周波数を指定してスピーカーから音を出そうとして、
Web上でサンプルを検索したところ、
http://www.thevine.net/~hopkins/seth_cpp.html のようなページを見つけ、早速コンパイルしてみました。
ですが、「未定義の関数soud」というコンパイルエラーがでてしまいます。
dos.hのファイルをみたところ、soundなどの関数はありませんでした。
サンプルではBorland C++ 4.xを使っているようですが、
これより上のバージョンでサポートしなくなるということはあるのでしょうか。
また、周波数を指定して、音を出すために、他に簡単な方法はありますでしょうか。
以下、HP上のサンプルコードです。
#include <stdio.h>
#include <dos.h>
void main() {
int x;
printf("\n\n Are we having fun yet? \n\n");
for (x=50; x<2000; x++) {
sound(x);
delay(3);
}
nosound();
}
299 :
デフォルトの名無しさん :01/11/11 12:42
関数の定義でconstを使いたいのですが、 何かいい本ないでしょうか?
>>299 const使って何をするのかわからないと答えようがない。
とりあえずプログラミング言語C++読んでから聞け
301 :
名無しさん :01/11/11 14:17
入力で N01 68 56 N02 74 79 N03 39 56 出力で N01 68 56 144 N02 74 79 153 N03 39 56 95 としたいんです。 で、宣言を int n [3]; として while (k<=3) z=x+y k=k+1 としてみたんっすけどうまくいきません。 助言ください。 当方殆ど初心者です。
何がどううまくいかないのか書きなさい。 わかりやすくいうとだな、 どういうメッセージが表示されたか書きなさい。 どういうプログラムを書いたのか書きなさい。 だ。
304 :
デフォルトの名無しさん :01/11/11 14:33
Winプログラマです。誰か教えてください VC++で以下のようなインターフェースのDLLを作りました #include <vector> using namespace std; __declspec(dllexport) void WINAPI Foo(vector<string>& arg) { arg.pushback("AAA"); } これを他のC++コンパイラ(C++Buiilderとか)でビルドしたEXEから 上記DLLのエクスポート関数を正常に処理することは可能でしょうか? 試してみたところ、上記関数を実行した時点でGPFが起こります。 コンパイラによって当然vectorの実装方式が違うため、 無理な気がするのですが気のせいでしょうか... 板違いかもしれませんが、宜しくお願いします
おまえは医者に、 調子が悪いんです。 いつもは朝起きてご飯食べて学校に行ってるんですが、 調子が悪いんです。 なんて説明するのか?
他のコンパイラとC++そのもので協調するのは名前の問題や ヒープ管理の問題もあるから、あなたの言うとおり、絶望的。 というかC++のクラスをdllexportするのは、たとえ同じコンパイラ であてもちと気持ち悪い。 安直にはCのみになるのかな。当然vectorとか使えない。 がんばりたければCOMだろうけど・・・疲れるよ
COMはべつに疲れるもんでもないがなー
>>306 様
レス有難うございました。
やっぱり、そうですね。本当にバイナリレベルの互換
を望むならCOMでしょうが・・・確かに疲れますしねぇ
309 :
デフォルトの名無しさん :01/11/15 04:24
mage
310 :
デフォルトの名無しさん :01/11/15 10:06
例外安全、例外中立とはなんですか?
コピペコンストラクタ
クラス階層を表示したりメンバをスーパークラスまでたどって 表示できるツールってVC以外で無い? コマンドラインアプリでも良いんだけど・・・
>>314 td32ってできるんじゃない [View|Hierarchy]
>>315 ありがとう
Turbo Debuggerはできるんだね
でもあれってユーザ登録が必要でしょ?それってちとイヤンな感じ
>>316 たまにメールが来るだけだから気にするこたぁない
それも嫌ならすぐ登録解除でもすれば?
C++なんか相手にしてませんが。
320 :
デフォルトの名無しさん :01/11/18 19:07
doxygenってどうですか?
321 :
デフォルトの名無しさん :01/11/18 22:18
'/0'ってのはNULLって意味でしょうか? char a='/0'; とするのと char a; *a=0; とするのは同じ事となる?
322 :
デフォルトの名無しさん :01/11/18 22:23
unko
>>321 まず /0 (スラッシュゼロ)ではなく \0 (バックスラッシュゼロ)。
NULL ではなくヌル文字といい、文字配列の終端を表す。
規格上 char ポインタの文脈で使われる 0 はヌル文字に変換されることになっている。
>>321 それじゃ意味が全然違うというかコンパイルとおらないんじゃ?
char a='\0';
と
char a;
char *p = &a;
*p = '\0';
なら同じことです。
'\0'とNULLは違うものです。
'\0'はキャラクタコードでNULLはポインタ。
>>323 > 規格上 char ポインタの文脈で使われる 0 はヌル文字に変換されることになっている。
「char ポインタ」じゃなくて「char」の間違いだよね。
>>325 フォローサンクス。書いてから気付いた。
char ポインタの文脈だとメモリ壊れるね(笑
327 :
日本@名無史さん :01/11/18 22:51
>>323 > NULL ではなくヌル文字といい、文字配列の終端を表す。
「文字配列」じゃなくて「文字列」の間違いだよね。
>>321 実際問題として
'\0'とNULLはどっちも 0 だから混同してもコンパイルできたり
正常に動いたりはする。
でも処理系によってはトラブルの元になるからちゃんと区別して
使わないとダメ。
>>328 処理系依存だからというのも理由の一つだが、ソースコードを読んで
ポインタなのか
文字型なのか
それとも整数の 0 なのか
が一発で分かるので、読みやすくなるというのも少なからぬメリット。もっとも C++ だと
#define NULL 0
って処理系がほとんどだが、その場合 foo(NULL) で foo(int) が呼ばれる点だけは注意が必要。
char a='\0'; とするのと char a; &a=0; ですね、すいません で結論としては char a='\0'; と char a=0; が同じなんですね
>>330 前者はやってることが違う。
a = '\0'はaに値を代入している。
&a = 0; はaのアドレスを0で上書きしている。こんなことはしてはいけない。
後者はまぁオッケー。
NULLはC++じゃないだろ。Cスレへ逝け
>>332 そういうときには、論拠も示してくれると助かるんだが。
>>335 手元には ISO C++ の規格書がありますが、これには 18.1 で NULL は C++ null pointer constant だと
明記してありますな。
337 :
デフォルトの名無しさん :01/11/19 00:19
世渡り上手になりましょう
>>335 オタッキーなデブになってはいけません
338 :
オタッキーなデブ :01/11/19 01:34
while (NULL == (void*)0);
>>338 ネタは sage てな。
それとも NULL の定義や、整数型とポインタ型の比較についてディープに語りたい?
CとC++におけるvoid *の違いについてディープな議論キボンヌ。
独習C++読んだけどムズイ・・・
NULL が __null とか定義されてて 0 と違った特別扱いになってるコンパイラはないのかしらん。 __null は何型のヌルポインタにもなるけど整数には変換できないみたいな。 規格違反?
NULL が __null とか定義されてて 0 と違った特別扱いになってるコンパイラはないのかしらん。 __null は何型のヌルポインタにもなるけど整数には変換できないみたいな。
gccは__nullなんてのを導入してるよ。
346 :
デフォルトの名無しさん :01/11/19 22:22
18.1 - Types [lib.support.types] -4- The macro NULL is an implementation-defined C++ null pointer constant in this International Standard (conv.ptr).* [Footnote: Possible definitions include 0 and 0L, but not (void*)0. --- end foonote] NULLはnull pointer定数なんだねえ。
>>346 念のため、キーワードではなく単なるマクロなのでよろしく。
348 :
デフォルトの名無しさん :01/11/19 23:23
>>346 ISOで定義されているというのはデカいな。
イソイソイソ
VC++6.0 sp5でstlport4.5使用してるんですが、 int WINAPI WinMain(...) { std::string str("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); } コレだけのプログラムで、BoundsCheckerが4800バイトのメモリリークを検出します。 他の方はどうですか? ビルドに失敗したんじゃないかと心配です
351 :
デフォルトの名無しさん :01/11/21 02:05
>>350 漏れのところもそうなるよ。
stringの数だけリークしてるわけじゃないから、メモリプールじゃないか?
無視して問題ないと思うが、他人の回答も欲しいからage
352 :
デフォルトの名無しさん :01/11/21 02:51
>>350 かなりがいしゅつ。リークではない。
ロケールだかなんだかのために、STLportが
最初の一回だけ確保するメモリだ。
厳密に言えばboundscheckerの言うとおりリークだが、
深刻なリークではない。
プロセスが終了すれば解放されるので気にしないでよい。
>>352 確かに既出だが、細かい話はこのスレじゃなくて STL スレでやってた気がする。
354 :
デフォルトの名無しさん :01/11/21 05:06
タイマーを作りたい!たとえば5秒の待ち時間をつくるとか。 簡単にできますかね?
356 :
デフォルトの名無しさん :01/11/21 05:29
仮想関数ってJavaのインターフェースと一緒だと思って良いのかな?
>>356 仮想関数=Javaのすべてのメソッド
C++の非仮想関数に相当する物はJavaに無いよ
359 :
デフォルトの名無しさん :01/11/21 14:12
Exceptional C++ とか、C++ FAQ とかをみると、operator= で 明示的にデストラクタを呼ぶときに、そのクラスが X だとすると、 this->~X(); って書いてある。this-> っているだろうか?
要らないと思う。
Exceptional C++ とかのコードは C++ のエキスパートの 目にふれているはずなのだけど、やはり this-> はただの 飾りなのかな? 非 virtual なメソッドから virtual なメソッドを呼び 出していることを明示してるだけの気はするが、何か深遠 な理由があるのではないかと勘ぐってみたり。
@ throw new classA で catch(classA* a) ってうけとるのと A throw classA で catch(classA &a) ってうけとるのと なにがどうちがうの @はdelet aするけど Aはしなくていいの?
そぉいうことです。
>>363 そしたらAのほうがぜったいつかいやすいとおもうんだけど
どーして@のようなそーすがおおいの?
>>364 多いか? MFC は過去のしがらみがあるので catch (CException*) だが、それ以外で例外を
new で投げてるのは、私の周囲では見ないよ。
366 :
デフォルトの名無しさん :01/11/21 21:36
小心者なのでnewい失敗するのが怖い :−<
>>365 そーなんだ ありがとー
それで、もひとつしつもんだんだけど
AでthrowしたclassAはどのじてんできえてなくなるの?
catchしたばしょでまたthrowしたかったとき?
>>367 まちがえた!
catchしたばしょでまたthrowしたかったとき?
↓
catchしたばしょでまたthrowしなかったとき?
369 :
デフォルトの名無しさん :01/11/21 22:21
>>368 オブジェクトはスコープの終わりで解体される
推薦図書スレに逝ったのですが荒れまくっていて話しにならなかったのでここで質問させてください。 STLを勉強したいのですが、お勧めの本はありますでしょうか?
throw classA; の時点で生成されたインスタンスを仮に a とする。 a はコピーコンストラクタで一時的にコピーされる(bとする)。 throw 文が実行終了したので a は破棄される。 catch に突入。 ここで受け取る方法が参照の場合は、b を参照する。 参照でなければ、もっかいコピーコンストラクトされる。 catch 終了時点で b は破棄される。 って感じだと、勝手に思ってます。規格を調べたわけではない。
>>370 C++標準ライブラリについて知りたいならプログラミング言語C++を。
STLに限るなら「標準テンプレートライブラリによるC++プログラミング」あたり?
>>371 くわしいせつめいありがとー
じゃあまたまたしつもんだけど
classA;
がもし
int i[10000];
ってゆーくらすへんすう?をもってたら
やっぱり@のほうがいいのかなー??
>>374 int i[10000];
ってゆーくらすへんすう?をもってたら
↓
すごーくいっぱいめもりつかってるからもったいないとか、
こぴーにじかんかかるとか
そーゆーいみです
わかりずらい?
>>374 読みにくすぎ。漢字を少しは使おう。
漢字を使いたくなければ単語の間を適当にスペースで区切るか、英語で書いてくれ。
>>371 例外発生時にコピーコンストラクタが呼ばれるなんて聞いたこと無いが?
漢字使って書き直してみました。 >throw classA; >の時点で生成されたインスタンスを仮に a とする。 >a はコピーコンストラクタで一時的にコピーされる(bとする)。 >throw 文が実行終了したので a は破棄される。 classA がもし int i[10000] あるいはもっと大きいクラス変数?を持っていた場合 一時的にコピーされる際の、時間・メモリ大きさのことを考えると やはり@のようにポインタを投げる方が良いのでしょうか?? 話しはそれますが(コピーコンストラクタもよく知りません) コピーコンストラクタでコピーされる内容は 仮に classA が持っているクラス変数?がポインタの場合、 コピーされるのはそのポインタのみでしょうか? 下記の *a の値は、どうなるのでしょうか? class classA{ intr* p; classA(){ p = new int; *p = 10; } ~classA{ delete p; } } これを throw classA した場合 catch(classA &a) で受け取った a の持つ *p の値は保証される(この場合値は10になるのか)のでしょうか?
まちがえた!! 下記の *a の値は、どうなるのでしょうか? ↓ 下記の *p の値は、どうなるのでしょうか?
実験してみたよ。 VC++ だと、catchが参照なら、コピーコンストラクタ呼ばれない。 catchが実体なら、コピーコンストラクタ呼ばれる。 C++Builder だと、catchが参照なら、コピーコンストラクタが1回呼ばれる。 catchが実体なら、コピーコンストラクタが2回呼ばれる。 gccは試してない。 テストコードはこんな感じ↓ #include <stdio.h> class A{ public: A(){ printf("constructor %p\n", this); } A(A&){ printf("copy constructor %p\n", this); } ~A(){ printf("destructor %p\n", this); } }; void f() { throw A(); } int main() { try{ f(); }catch(A a){ } return 0; }
>>379-380 というわけで、保証されません。
上手く動くこともあるけど、上手く動かないこともある。
潜在的なバグですな。
コピーコンストラクタを書くべき。
ついでに代入演算子も書くべき。
このように↓
class classA{
intr* p;
classA(){
p = new int;
*p = 10;
}
classA(const classA& a){
p = new int;
*p = *a.p;
}
~classA{
delete p;
}
classA& operator=(const classA& a){
*p = *a.p;
return *this;
}
}
383 :
デフォルトの名無しさん :01/11/22 01:32
>C++Builder だと、catchが参照なら、コピーコンストラクタが1回呼ばれる だとしたら型が変わる可能性があるぞ? class a {}; class b : public a {} void f(){ try { throw b(); } catch( a aa ){ aa は b ニアラスズ } }
>>383 それ terminate() されないか?
実験した。 一度 b のコピーコンストラクタでコピーされたあと、 a に変換されて catch が実行される。 たぶん throw b(); の b() で生成した一時オブジェクトは、 throw 文の終了時点で消滅する理屈なのかなぁと。 コピーして取っておかないと、元のオブジェクトは消滅して catch ブロックで使えない。
>>382 なるほどー
とっても勉強になりました。
ありがとうございました。
>>383 さんのをみてると、またわかんなくなってきました。
>>382 の classA を 継承する classB を throw し、
catch(classA &a) や catch(classB &b) できるようにする場合の
classB はどう書けばいいんだろう???
classA と同じようにコピーコンストラクタと代入演算子も書くべきなのかなー??
寝ながら考えてみます。
382については「コピーコンストラクタと代入演算子」の問題 383については「スライス」の問題で 別件です。
コピーコンストラクタや代入演算子は、 基本的に多くの場合、書くべきだと思うけど? 書かなくても自動生成されるけど、これはC++の罠だし。
391 :
デフォルトの名無しさん :01/11/22 12:47
throwはreturnと同じような意味を持っていると理解しているが どうでしょう。 例外の説明でスタックの巻き戻しとか出てくるけど return文だって同じことするのになぜだろう。
>>391 return は呼び出しもとの関数に戻るけど、throw は catch されるまで一気に戻るのが違い。
throw は C なら return よりも setjmp, longjmp に近いと思われ。
>>391 たとえばこんな感じかな。
void f1()
{
try{
f2();
}catch(...){
}
}
void f2()
{
f3();
}
void f3()
{
f4();
}
void f4()
{
throw 0;
}
どこまで戻るかが違う。
>>372 プログラミング言語C++買ってきました
7000円は痛い・・・
>>394 今後3年は使えると考えて、1年に2000円なら安いもんだ
396 :
デフォルトの名無しさん :01/11/22 23:55
>>393 おおなるほど。
ってreturnでも一緒じゃん!
393じゃないけど。
>>396 >ってreturnでも一緒じゃん!
違うよ。もっと考えてみて。実行してみるのが一番だよ。
もし良かったら、今後の参考のために「一緒」と思った理由を教えて。
どうでもいいけど
>>393 のソースなら一緒だっていみだろ。
内部定義したいょ
400 :
デフォルトの名無しさん :01/11/23 04:51
仮想関数を何度か呼び出すのですが、インスタンスは変化しないので、 2回目以降はvftableのようなものを経由しないで呼び出したいのですが、 どうすればよいでしょうか?
何のためにそういった手の込んだことをするのですか?
>>400
多分vtblのオーバーヘッドが〜とかいいたいのでしょう
では。仮想関数を呼び出すニーモニックは ほぼ call [vtable+n] です。 さて、インスタンスが変化しないのでそれを経由せずに 自分でポインタで関数を管理したとします。でも インスタンスは当然一つではないので、それぞれの インスタンスにポインタが必要です。 コレを呼び出す手間は最小で call [footable+pointeraddress] です。 言語側の仮想関数と自前のポインタ処理は同じような機械語になります。 よって呼び出しを自前で処理してもあまり意味がないと思うのですが。 そうでもないのかな?
>>400 1 仮想関数にするのをやめる。仮想関数でなければ、オブジェクトのクラス名とメソッド名から、
呼び出すコードが一意に決まりますから vtbl 引きませんし、うまくいけばインライン化できま
す。コンパイル時に型が確定するのであれば、template を使う手もあります。
2 メンバ関数へのポインタを使う。
ただ、ほんとうにボトルネックはそこですか? 細工を始める前に本当に仮想関数呼び出しが
オーバーヘッドになっているのか、プロファイラを使って計測した方が良いです。細かい工夫で
数サイクル稼ぐより、アルゴリズムを工夫してメソッド呼び出し回数のオーダーを下げた方が
遥かに効果的です。
406 :
デフォルトの名無しさん :01/11/23 13:35
>>405 メンバ関数へのポインタではオーバーヘッドなくならないんじゃない?
あと、正直プロファイラがどんなものなのか分からない。
おいおい パフォーマンスを気にするなら、プロファイラがどんなものか 理解しておくべきだ。 プログラムを実際に動かしてみて、 どの関数が何回呼ばれたとか、 どの関数で何ミリ秒時間がかかったとか、 そういう様々な実行時の情報を計測してくれるツール のことだよ。 小手先最適化の前に まず、こっちを先に調べなさい。
どうもありがとうです。
>>404 VC++のはいたコードを見てみたのですが、
たしかにそういう呼び出し方をしていますね。
>>405 >2 メンバ関数へのポインタを使う。
は
>>404 さんの
>言語側の仮想関数と自前のポインタ処理は同じような機械語になります。
と同じですよね?
>数サイクル稼ぐより、アルゴリズムを工夫してメソッド呼び出し回数のオーダーを下げた方が
>遥かに効果的です
にしたいのですが、もともと仮想関数を使う理由は
あるコンテナ群に対する処理をひとつのソースで済ませたいからなのですが、
コンテナのインタフェースに対して処理しているので、
どうしてもvirtual invokeが発生するのです。
やはり、この場合はコンテナにアルゴリズムを持たせるのが一番でしょうかね・・・。
>382 classBが下記のような場合はコピーコンストラクタいるの? classA を継承しているし、いらないかなー なんて思ってしまうのですが・・・ (わけわかんない事いってたらごめんなさい) classB throw classB; して carch(classB &b){ } で受け取ると class classB : public classA { int q; classB(){ q = 20; } ~classB{} } class classA{ public: int* p; classA(){ p = new int; *p = 10; } classA(const classA& a){ p = new int; *p = *a.p; } ~classA{ delete p; } classA& operator=(const classA& a){ *p = *a.p; return *this; } }
410 :
デフォルトの名無しさん :01/11/23 16:50
class container_base { public: virtual void each() = 0; }; class container1 : public container_base { public: virtual void each() { } }; class container2 : public container_base { public: virtual void each() { } }; //ひとつのソース template <typename Container> void general_test(container_base* pBase) { Container* pCont = dynamic_cast<Container*>(pBase); for (int i = 0; i < 10000; i++) pCont->Container::each();// no virutal call } container_base* pCont = new container1; general_test<container1>(pCont); 仮想関数を非仮想呼び出しするには、明示的限定以外ないので(関数ポインタによる呼び出しも仮想呼び出し)、 こんな感じですがあまり役に立ちそうにない。
411 :
デフォルトの名無しさん :01/11/23 18:43
A:すべてのクラスの基底クラス A1,A2:Aから派生したクラス X:A1,A2を多重継承したクラス としてAのポインタをXのポインタにキャストしたいのですが どうすればよいでしょうか #BCCでエラー('A *' から 'X *' へのキャストはできない) class A {}; class A1 : virtual A {}; class A2 : virtual A {}; class X : A1, A2 {}; main() { A *pa; X *px = (X *)pa; }
>>411 何のためにそんなコトしたいのか知らんが、できないものはできない。
>>411 X* から A* ではなく、逆なのか? やってやれないことはないが、設計が腐ってるとしか思えん。
414 :
デフォルトの名無しさん :01/11/23 19:09
>>411 Aが仮想関数もってないからじゃないの?
class A {virtual void virtual_method(){}};
class A1 : A {};
class A2 : A {};
class X : A1, A2 {};
main() { A *pa; X *px = dynamic_cast<X *>(pa);}
ところで、class A1 : virtual A {}; での
「virtual」の意味を教えてちょ。どんなときに使うの?
>>414 仮想継承は菱形継承するときに使う。この場合だと、仮想継承しないと X オブジェクトの内部には
A オブジェクトが二つ含まれることになるが、仮想継承すると A オブジェクトが一つしか含まれな
くなる。
プログラミング言語 C++ に図入りで解説があるから、読んでみ。
>>415 おお、さんくす。
プログラミング言語 C++買ってこよ。
7000円の壁にくじけ、本屋で膝を崩す414の画像をキボンヌ、と
万引きしようとして不自然に服がふくらんで店員に捕まっている414の画像をキボンヌ
gotoのかわりにtry catch使う人多い?
break一発じゃぬけだせない深いループから抜け出すときに
414キボンヌ
膝を崩すって変だな、本屋でくつろいでどうするよ。逝ってこよう… ただtry catchはやはり例外発生時にのみ使うべきだと思うのであります。
7000円の壁にくじけ、座り読みを始めて、隣で立ち読みしているょぅι゛ょの スカートの中を覗き見しようとしている414の画像をキボンヌ
>>419 俺は goto 使う場面では goto 使う。
>>411-413 Aを基底クラスとした様々な派生クラスをリスト化
その要素にアクセスするためのイテレーターをA*
X以降の派生クラスであることがわかっている要素(一応typeidで確認して)で
Xのメソッドを使用したいときにA*→X*のキャストが必要となりました。
多重継承させずに設計すべきだったんでしょうかね。
できないなら仕方ありませんが、
やれないことはないとは、どのようなことか教えてくださいませんか?
>>425 > X以降の派生クラスであることがわかっている要素(一応typeidで確認して)で
> Xのメソッドを使用したいときにA*→X*のキャストが必要となりました。
X の派生クラスであることが分かっているのなら X* のまま渡すべきであって、途中で A* に落としてしまう
設計がイマイチでしょう。
基底クラスを扱う側で本当に「その X 固有のメソッド」を参照する必要があるのなら、そのメソッドを A に移
して仮想メソッドにするべき。A では純粋仮想メソッドにして派生クラスで実装させるか、もしくは適当なデフォ
ルト値を返すようなメソッドを定義しておく。
> やれないことはないとは、どのようなことか教えてくださいませんか?
dynamic_cast です。
>>426 なるほど。色々と説明ありがとうございます。
dynamic_cast を使う場合は
>>414 のようにするのですね。
レスくださった方に感謝します。
設計から再考してみようと思います。
428 :
デフォルトの名無しさん :01/11/24 13:29
C++自体の話とはずれるかも知れませんが、ちょっとしたプログラムを書いて 1. VC++(ver6) 2. g++(2.96, Kondara MNU/Linux 2.0) 3. g++(cygwin2.95.3-5, WIN2K) でコンパイルしたのですが、1,2ではコンパイルが通って(警告もなし) 3ではどばっとエラーが出ます。エラーの内容は最初に class my_itr : public iterator<bidirectional_iterator_tag, my_type>{ と書いた行で parse error before `<' と出た以後、 何かがずれたようにsyntax errorやundeclaredといったエラーが延々と出ます。 こんな経験のある方いませんか? cygwinメインで書いてるのでホトホト困ってます。
>>428 絶対ソースのせた方が早く解決すると思う。
ほんとだ、とーらないね。
ソース200行ほどになるのですが、ここに張っつけて可能でしょうか。
とりあえず80行程度になりました。
g++ -c
で試してみると
>>428 のようになります。
2回にわけます。
---以下ファイル ---
#include <list>
#include <map>
#include <iostream>
using namespace std;
typedef unsigned long ulong;
template<typename VRTX,typename EDGE>
class _graph{
public:
class _vwrap;
class _ewrap;
class _vrtx_itr;
// 頂点リストの型
class _vlist : public list<_vwrap*>{
public:
list<_vwrap*>::iterator operator[](const ulong& i){
if(i>=size()){
cerr << "ERROR: Index out of range" << endl;
exit(1);
}
list<_vwrap*>::iterator itr = begin();
advance(itr,i);
return itr;
}
};
typedef _vlist::iterator _vlist_itr;
// エッジリスト型
typedef list<_ewrap*> _elist;
typedef _elist::iterator _elist_itr;
// 結合マップのソートの基準
struct _less_vlist_itr :
binary_function<_vlist_itr,_vlist_itr,bool>{
bool operator()(const _vlist_itr& v0,const _vlist_itr& v1) const{
return *v0<*v1;
}
};
// 結合マップ<結合先頂点,対応エッジ>
typedef map<_vlist_itr,_elist_itr,_less_vlist_itr> _amap;
typedef _amap::iterator _amap_itr;
// 頂点のラッパ class _vwrap{ friend _graph; friend _vrtx_itr; private: VRTX vrtx; // 頂点本体 _amap amap; // 結合マップ _vwrap(){} _vwrap(const VRTX& v) : vrtx(v){} }; // エッジのラッパ class _ewrap{ private: EDGE edge; // エッジ本体 _vlist_itr vrtx[2]; // 両端点の頂点 }; // 頂点の内容(VRTX)にアクセスするための反復子 class _vrtx_itr : public iterator<bidirectional_iterator_tag,_vwrap*>{ friend _graph; private: _vlist_itr itr; public: _vrtx_itr(void){} _vrtx_itr(_vlist_itr v) : itr(v){} _vrtx_itr(_amap_itr a) : itr(a->first){} VRTX& operator*(){ return (*itr)->vrtx; } VRTX* operator->(){ return &(*itr)->vrtx; } _vrtx_itr& operator++(){ ++itr; return *this; } _vrtx_itr& operator--(){ --itr; return *this; } }; private: _vlist vlist; // 頂点リスト _elist elist; // エッジリスト public: _graph(void){} ~_graph(){} };
あ、もしコンパイルを試してくださるなら 全角のスペースを使ってるので注意です。
std::のつけわすれじゃなくって?
なんだか不必要な部分も貼っつけたみたいで煩雑になってすみません。 std::は4行目で宣言してるので問題ないと思います。 それといまSUNのSPARC(gcc2.95.1)でも試してみました。 結果・・・通りませんでした。 ん〜。gccの最近のバージョンでSTLの枠が少し変わったのかなぁ。 自分のやり方が間違ってないことが判れば、今コンパイルが通らなくても 将来通るようになるだろうということで納得できるんですけど。
>>436 g++ -E で、プリプロッサを通した後の <iterator> を読んでみれば? 実は struct iterator が
削除されてたりしない?
とりあえず、_で始まる識別子は使うなよ。 コンパイラで使ってる名前とぶつからないかどうか いちいちチェックしないといけないだろ
__STL_USE_NAMESPACES をソースの最初で定義するべし
>>439 いい忘れたが#include よりも前の行で(つまりほんとの1行目)
>>437 struct iterator。
確かにコンパイルが通らなかった方には存在しませんでした・・・。
これが原因ですか?だとすればなぜこうなってしまうのでしょうか。
>>438 なんか昔から大文字と小文字がくっついてるのが気持ち悪くて
型は全部"_"で始めるようにしてます。それと定数以外は全て小文字です。
あまり複雑なプログラムは組んだことがないので(専門は流体計算です)
これまでは気にせずに来ましたが、やっぱり常識的にまずいですか?
>>439 エラーが増えました・・・。
#ifdef __STL_USE_NAMESPACES struct iterator ... になってるはず。
>>441 _で始まる名前は Cの予約語。
__で始まる名前と _ + 英大文字 で始まる名前はC++の予約語。
厳密にいえば _ + 英子文字で始まる名前は C++の予約語ではないが、
さけるべき。
>>442 確認しました。それでプログラムの冒頭で
#define __STL_USE_NAMESPACES
としたのですが、やはりg++ -Eで出力を見ると
struct iteratorは存在しません・・・。どこで消えてるの?(泣)
>>443 厳密には予約語ではないけれども常識的には避けるべきということですね。
了解しました。少しずつ慣れるようにしてみます。
いろいろと有難う御座います。
ちょっとピグミン買いに行ってきます。
gcc 3.0.2だとエラーがちと違いますな。 > foo.cc:47: friend declaration requires class-key, i.e. `friend class > _graph<VRTX, EDGE>' > foo.cc:48: friend declaration requires class-key, i.e. `friend class > _graph<VRTX, EDGE>::_vrtx_itr' > foo.cc:65: friend declaration requires class-key, i.e. `friend class > _graph<VRTX, EDGE>'
friend class XXXXを friend class XXXX<VRTX,EDGE>にすりゃいいのか? 試してなくてす万コ
>>446 駄目みたいです。
それで買い物に行く前にもう一つだけ試してみました。
無理やりですが、ファイル冒頭の#include <list>の後に
stl_iterator.h内の該当部分
template <class _Category, class _Tp, class _Distance = ptrdiff_t,
class _Pointer = _Tp*, class _Reference = _Tp&>
struct iterator {
typedef _Category iterator_category;
typedef _Tp value_type;
typedef _Distance difference_type;
typedef _Pointer pointer;
typedef _Reference reference;
};
を貼っ付けてみました・・・。
コンパイル通りました(泣)。
納得できません・・・。
448 :
デフォルトの名無しさん :01/11/24 22:17
*.objってなんのファイルですか?
コンパイル中に作られるファイルで、exeが出来た後には要らないものです。
450 :
デフォルトの名無しさん :01/11/25 02:31
EffectiveC++改定2版のp38のサンプルでハマった以下のコード。 なぜかVC++で全然通らないのはなぜでしょう? class CFoo { public: CFoo(int foo) {m_foo = foo;} private: int m_foo; friend ostream& operator<<(ostream& s, const CFoo& r); }; ostream& operator<<(ostream& s, const CFoo& r) { s << r.m_foo; return s; } main()の中で、 CFoo obj(10); cout << obj << endl; VC++コンパイルすると以下のエラーが出る > error C2248: 'm_foo' : private メンバ (クラス 'CFoo' で宣言されている)にアクセスできません。 > error C2593: 'operator <<' があいまいです。 最初のエラーは m_foo を public にすると通るけどpublicにはしたくない 次のエラーは friend の行を外すと通るが、理解不能。
sp5で問題なくコンパイル通るけど、 それどういう環境?
g++ 2.95.3-6 (mingw), Borland C++ 5.5 でも通るね
>>451 試してくれてアリガトウ。
cl.exe のバージョンはこのようになっています。
> Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86
> Copyright (C) Microsoft Corp 1984-1998. All rights reserved.
sp5とか当てた覚えが無いのでやっぱりコンパイラが古いんだろうか。
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86 うちのこんなかんじ。 spあてたら?(でかいけど)
>>454 あきらかにバージョン違うね。
sp5当ててみます。
一年半以上前のバージョンだね。 古すぎ。
457 :
デフォルトの名無しさん :01/11/25 03:04
VCの次バージョンっていつ出るの?
来年2月
sp5いれてコンパイル出来るようになったぞ〜!
460 :
デフォルトの名無しさん :01/11/25 03:49
>>428 class _vrtx_itr : public iterator<bidirectional_iterator_tag,_vwrap*>{
このiteratorって何者?
class _vrtx_itr : public list<_vwrap*>::iterator {
とかじゃないの?
質問です。 if(!hoge)と判定するためには operator!をオーバーライドしますが、 if(hoge)と判定するためには 何をオーバーライドしたらいいのですか?
まちがってsageちゃったのでage
operator bool かな?
>>459 もう解決してるみたいだが、うちは未だにVC++5の
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 11.00.7022 for 80x86
だけど通った(古すぎて悪かったな)。
うへ、そこが荒れるんですか。
467 :
デフォルトの名無しさん :01/11/25 16:56
typeidで どのクラスを継承しているかという情報は 取れるのでしょうか?
C++超初心者です。 VC++6.0を使ってWIN32コンソールアプリケーションのMFCをサポートしない プログラムの練習をしているんだけど、画面を制御する方法が判らなくて 困ってます。 具体的に、coutで出力した文字を全て消去して、新たに文字を画面の頭から 出力したいとき、必要なライブラリと関数は何かを教えて欲しいんだけど だれかご教授お願いします。 使用OSはWIN-Meです。
ANSI.SYSとエスケープシーケンスをとりあえず調べろ。
>>467 取れません。typeid で取れるのは、クラス名だけです。
簡単なバイナリビューアを作ったんですけど 普通NULL文字と0x0d,0x0aはテキスト情報としてどう 表現しますか? 今のところ暫定的にNULl文字→'0' 0x0d→'D'0x0a→'A'としてるんですけどこれじゃ だめなのはわかっています。
\0\r\n って書けば?
できれば1文字にしたいっす
>>473 他のバイナリビュアーつかったことないの?
例えば char* を int* に変換したいとき、 みんな static_cast と reinterpret_cast どっち使ってる?
そんなことしない
>>467 >>470 あるクラスを継承してるかどうかなら
type_info::before()で判定できるはず
>>475 ふつーreinterpret_castだろ。つーかコンパイラがエラー出さないか?>static
479 :
デフォルトの名無しさん :01/11/25 22:22
>>477 それ違う。a.before(b) は strcmp(a.name(), b.name()) < 0 程度の意味。
>>476 それはミもフタもないです。。。
>>478 ほんとだ。
基本型のポインタ同士では static_cast 使えないのか・・・知らなかった
>>480 俺もしないと思う。
なんのメリットがあんの?
MSDN>reinterpret_cast 演算子は、const、volatile、__unaligned の各属性をキャストして除去することはできません
こんだけしかない気が・・・
483 :
デフォルトの名無しさん :01/11/25 23:31
ポインタだらけのソースをC++風にリファレンスを活用して 書き直しているんだけど、なぜかリファレンスにNULLが指定出来ないという 問題にぶちあたった。これってそういうもの?
>>483 そういうもの。
全部参照ならNULLポインタにアクセスする危険性がなくなる。
>>484 あー、なるほど。リファレンスにするメリットはそこにあったのか。
-> が . で書けるって事ぐらいしか気づいてなかったよ(w
>>481 intをシリアライズした生メモリ(まPVOIDでもいいんだけど)がたまたま
途中の都合でchar*で与えられたときにreinterpret_castでint*に変換
してintとしてアクセスするとか。
a[i] = b というプログラムがあった場合、逆にa[i]をbが参照するのは、どんな 書き方があるでしょうか? 初歩的な質問で申し訳ありませんが、お願いいたします。
>>487 意味わからん。aとかbとかどんなオブジェクトなんだよ。
489 :
デフォルトの名無しさん :01/11/26 02:01
>>484 安心はできない(*´Д`*)
string *s; //初期化忘れてる
...
hoge(*s); //あぼーん
>>489 純然たる「参照」では初期化は必須では...
string& s; // エラー
491 :
デフォルトの名無しさん :01/11/26 02:31
STLで単純な2分木は実装されてますか? 赤黒木はあったんですけど、あれってツリーをいろいろいじりますよね?
>>491 「2分木」なんていうコンテナはSTLにゃねえよ
>>460 : class _vrtx_itr : public iterator<bidirectional_iterator_tag,_vwrap*>{
: このiteratorって何者?
: class _vrtx_itr : public list<_vwrap*>::iterator {
: とかじゃないの?
ありがとうございます!そうやって
list<_vwrap*>::iterator<bidirectional_iterator_tag,_vwrap*,diff_type,ptr_type,ref_type>
と設定したらうまく行きましたー。
やはり自分の間違いだったのですね。もう少し勉強します。
お蔭様ですっきりしました。
・・・と書きましたが、そのようにしたら今度は
1. g++(2.96, Kondara MNU/Linux 2.0) : OK
2. g++(cygwin2.95.3-5, WIN2K) : OK
3. g++(gcc2.95.1, Solaris) : OK
4. VC++(ver6) : NG
となりました。4のVC++のエラーの内容は『コンパイルされたクラステンプレートの
インスタンス化云々』というものです。ちなみに
iterator<bidirectional_iterator_tag,_vwrap*,diff_type,ptr_type,ref_type>
とした場合だと
1. g++(2.96, Kondara MNU/Linux 2.0) : OK
2. g++(cygwin2.95.3-5, WIN2K) : NG
3. g++(gcc2.95.1, Solaris) : NG
4. VC++(ver6) : OK
となります。この場合の2と3のNGの内容は
>>444 のようにstruct iteratorが
消えたことによるものです。そしてこの場合は
>>447 のように
無理やりstruct iteratorを定義してやると、2と3(2.95以前のg++)についても
コンパイルが通ります。まだすっきりしません。
>>485 参照のメリットは、もうひとつあるぞ。const 参照の場合限定だが、構造体やクラスを実引数「その場」
で作れる。
void Render(const Point& pt, Color color);
Render(Point(0, 0), Color(255, 255, 0));
496 :
デフォルトの名無しさん :01/11/26 15:25
constで定義した変数の値を変えるのはどうすればいいのですか?
>>496 1. mutable にする
2. const_cast する
498 :
デフォルトの名無しさん :01/11/26 15:26
>>496 変数の宣言の所でconstを削除する。
>>499 理想はそのとおりだが、たまに const char * をとるべき関数/メソッドなのに、char * をとるように
書いてあるライブラリとか存在するから。
DrawString(char *s);
みたいなやつね。
小心者は一時領域にオブジェクトをコピーしてから非constメソッドを呼べ(藁
502 :
デフォルトの名無しさん :01/11/26 16:12
class Base{ public: Base(){ init(); } virtual void init()=0; }; class Derived:public Base{ public: void init(){ } }; こういう使い方したいなー
>>502 コンストラクタから派生クラスの仮想メソッドを呼びたい、って話?
504 :
デフォルトの名無しさん :01/11/26 16:18
継承はやめて、集約に直しとけ
>>502 Delphiなら出来るけど、あの仕様はバグの温床だ。
>502 ちょうど知人に、最近、「あなたはオブジェクト指向に詳しいですか?」と、これに ついて尋ねられ、オブジェクト指向のオの字しか知らない自分は、答えに窮した(゜ε ゜ コンストラクタのオーバーライドは、オブジェクト指向的にイケてるのか、という話。
あれ? 良く見たら、そんな話しやないやん。逝きます。
派生クラスでコンストラクタを新たに書きたくないってこと?
だから集約にしとけって
>>495 引数の部分でクラス生成出来るのは便利だなぁ
ちなみに、よくわからないけど const 付けないでもコンパイル出来たよ。
あと Color color は Color& にしなくていいのかな?
511 :
デフォルトの名無しさん :01/11/27 01:05
>>428 http://www.kuzbass.ru/docs/isocpp/lib-iterators.html 24.3.2 -4 を見ると
class _vrtx_itr : public iterator<bidirectional_iterator_tag,_vwrap*,std::ptrdiff_t,_vwrap**,_vwrap*&> {
とかできそうなんだけど。gcc-3.0.xならいけるか?
iterator作るのが目的なら
class _vrtx_itr {
public:
typedef bidirectional_iterator_tag iterator_category;
typedef _vwrap **pointer;
typedef _vwrap *&reference;
typedef _vwrap *value_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
… あといっしょ
でどう?
512 :
デフォルトの名無しさん :01/11/27 01:09
ただの一時オブジェクト... 隠れた動作がおおいっての、C++の悪い面だよなあ。
514 :
デフォルトの名無しさん :01/11/27 01:17
マジで困っています。cに詳しい方、助けてください!! 6000個のデータが入ったテキストファイルを1000個のデータ(double)の入った6つのテキストファイルに分割したいのですが、やり方がわかりません。 元のファイル名はdata.txt、新たに作られるファイルはそれぞれdata1,data2,data3....という名前をつけなければいけません。 どなたか達人の方、教えてください。 お願いします。
>>514 データ形式がどうなっているかわからんとわからん。
データ形式は 123.234, 456.435, 92.412, 4.23, -2.35, 0, 12,26, という感じです、すいません、うまく説明できませんがよろしくお願いします。
宿題用のスレは別にあったと思うが?
perlとかでちょいちょい、の話だと思うがな‥‥ というわけで、見事なワンライナー募集に変更すべし。
520 :
デフォルトの名無しさん :01/11/27 01:43
1行に複数のデータがある場合もあるの? ”ある場合もある”って日本語変じゃないですか?
522 :
デフォルトの名無しさん :01/11/27 01:47
>>521 ",\n"を区切り文字としてstrtok()で分割しちゃえば?
コピーするだけだから数値に変換する必要はないな。
おっと、ここはC++のスレだった。。。
>522 一行に二個ある場合もあるので、 ",\n"じゃだめだと思うの。
あ、でもよく考えてみたら、 12,43, 34 これは3つじゃなくて4つに分割されるな・・・・
PerlでやれPerlで。
見ていない。
ていうか、改行無視して','で切ればいいんでないの?
>>529 そうだな・・・・
一行一行やるのが一番だね。。。。
暇つぶしに #include <stdio.h> #define NUMDATA 2 #define NUMFILE 6 main(){ char from[] = "data.txt"; char *r = "r"; char *w = "w"; char to[] = "data0.txt"; FILE *ff, *tf; int n, k, c; if((ff = fopen(from, r)) == NULL) return; n = 1; do{ to[4] = n + 48; if((tf = fopen(to, w)) == NULL){ fclose(ff); printf("can't open %s\n", tf); return; } k = 0; do{ c = getc(ff); if(c == EOF) break; if(c == ',') k++; putc(c, tf); }while(k < NUMDATA); fclose(tf); n++; if(c == EOF) break; }while(n <= NUMFILE); }
#define NUMDATA 1000 にしといてくだされ。 空白行がうざければ適当に処理してくだされ。
531さん、どうもありがとうございました。実行してみましたがばっちりです!! 一緒に考えてくださった、他の皆さんもどうもありがとうございました。 2ch初心者なので不安でしたが、世の中にはたくさん親切な人がいるんだなぁと思い感激です。 ありがとうございました。
534 :
デフォルトの名無しさん :01/11/27 05:43
>>531 カコイイ!!
俺もサクッと回答できるようになりたい・・・
535 :
デフォルトの名無しさん :01/11/27 06:18
RubyはC++に学ばなかった。 ナゼダカワカルカイ?ハクチドモ
Rubyって何よ?
537 :
デフォルトの名無しさん :01/11/27 06:54
っる胃bふbひうbひうbひうbひうbひうbひうbひうbひうbひうbひうbひうbひうbひうるbyさいこー補は簿言語の湯0−座hじゃしね。!!!
>>511 class _vrtx_itr : public iterator<>
で定義するのはg++2.95以前だと(今の書き方だと)やっぱり駄目みたい。
2.96以上では通るんだけど。
それで
>>511 書かれていたように継承なしで定義するようにしました。
これだとg++(2.95,2.96)でもVC++(v6sp2)でも通るみたいです。
これでいきます。どうもありがとうございました。
539 :
デフォルトの名無しさん :01/11/27 13:12
継承する必要がないときは、継承しちゃいけないよ。 がんばってね
540 :
デフォルトの名無しさん :01/11/27 18:18
class A:public virtual B{} ってやる事のデメリットってなんですか?
>>540 一番致命的なのはやはり、派生クラスへのキャストだね
542 :
(・Λ・)ワカラナイ・・・ :01/11/27 19:40
16進数から10進数への変換を行う関数を考える。 16進数の各桁を文字列の各文字として定義して、その文字を受け取りint型を 返すような関数を定義せよ。 関数名、仮引数および返値は以下のよに定義すること。 int htod(char hex[]){...} 上の問題ですが、全然わかりません。 文字列自体、習ったばかりです・・・。 誰かやりor答えを教えてください。
>>542 スレ違い。宿題スレを探して、そっちで聞け。
544 :
デフォルトの名無しさん :01/11/27 20:03
>>542 int hrod(char hex[])
{
int n;
sscanf(hex, "%x", &n);
return n;
}
545 :
デフォルトの名無しさん :01/11/27 20:52
派生クラスにキャストできないの!?
546 :
通りすがり :01/11/27 21:08
クラスのあたりでもう飽きてしまいました。 コンストラクタだの仮想関数だのって、、。 なにか飽きないで勉強できるネタない?
楽しくゲームでも作ってみたら?
548 :
通りすがり :01/11/27 21:15
>>545 仮想継承した場合、基底クラスと派生クラスで vtbl の配置が変わってしまう(ような実装が一般的だから)
規格でも仮想基底クラスから派生クラスへのキャストは NG になってる。
550 :
九州の学生 :01/11/27 21:48
独自挿入子を使ってストリームに情報を出力したいのですが、 Bの所で+演算子の返すオブジェクトをcoutで出力しようと して@,AのようなオーバーロードをするとBCC(Ver5.5.1)に 「エラー E2094 ref.cpp 20: << 演算子が使われたがクラス ostream では MX 型のための定義が存在しない(関数 main() )」 といわれてしまいます。g++でも出来ませんでした。しかし、 VC5では何の問題もなくコンパイルできます。<<演算子は@の ところでオーバーロードしているので、コンパイルできると 思うのですがどうなのでしょうか。なお、Aのところを参照 を返すように変更すればなぜかコンパイルできるのですが、 そうすると動的な配列が存在する場合にデストラクタによっ てメモリが開放されてしまいます。(元のソースでは"d"はポ インタになっていてコンストラクタで"new"している。) どなたかよい方法、又はこのソースの間違いを教えてください。 #include <iostream> using namespace std; class MX{ double d; public: MX(double x){d = x;} MX(MX &m){d = m.d;} MX &operator+=(MX &m){d += m.d; return *this;} friend ostream &operator<<(ostream &o, MX &m) // @ {o << m.d; return o;} friend MX operator+(MX &lm, MX &rm) // A {return MX(lm) += rm;} }; int main() { MX m1(1.0); MX m2(2.0); cout << m1+m2 << endl; // B return 0; }
>>550 そういう場合はグローバル定義の演算子オーバーロードするんじゃなかったっけ?
552 :
デフォルトの名無しさん :01/11/27 21:58
553 :
デフォルトの名無しさん :01/11/27 22:04
>>550 friend 関数は、そこに実装を書くことはできないはずだ!
あ、そこに実装してたのか。 frendはアクセス指定であって、関数定義じゃないよ〜
>>550 > そうすると動的な配列が存在する場合にデストラクタによっ
> てメモリが開放されてしまいます。(元のソースでは"d"はポ
> インタになっていてコンストラクタで"new"している。)
このように実装すれば良い。
class MX{
double* d;
public:
MX(double x){ d = new double; *d = x; }
MX(const MX& m){ d = new double; *d = *m.d; }
~MX(){ delete d; }
MX& operator=(const MX& m){ *d = *m.d; return *this; }
};
556 :
九州の学生 :01/11/27 22:21
>>551-555 迅速なレスありがとうございます。こんなに早く答えていただける
とは思いませんでした。
555さんのとおりconstをつけたらコンパイルできました。
C++では型のチェックが厳しいのを忘れておりました。
これって、演算子は問題ないの?
>>554 あ、俺が間違い?
friend 宣言と同時に実体の定義もできるみたいだね。(VC6,g++)
知らなかった・・・
>>381 遅いレスで恐縮ですが、
> 実験してみたよ。
> VC++ だと、catchが参照なら、コピーコンストラクタ呼ばれない。
> catchが実体なら、コピーコンストラクタ呼ばれる。
これは、throw A(); というようにインスタンス生成と同時に throw
しているから、最適化が施されたんでしょうね。意味論上は、C++Builder
の場合と同じです。(g++ は C++Builder と同じ動作をした)
ふつうの関数でも
A foo()
{
retunr A();
}
とやると、律義にデフォルトコンストラクタとコピーコンストラクタを
使うというようなことはせず、呼び出し側が用意したインスタンスの領域を
直接コンストラクトするような最適化がなされることがあります。
ちなみに、
void f()
{
A a;
throw a;
}
とやると、VC++ でもちゃんと(?)デフォルトコンストラクタとコピー
コンストラクタが呼ばれるようです。
561 :
BUGMAKER :01/11/29 19:10
自クラスのインスタンスを明示的に他のクラスに 渡すのってどうすれば良いでしょうか? Javaでいうところの、 OtherClass.setMyClass(this); みたいにしたいのですが・・・
>>561 C++ でも、それで良いけど。NULL チェック省くために参照にして
class OtherClass
{
public:
void setMyClass(Foo& foo)
{}
};
OtherClass.setMyClass(*this);
としたり、コンストラクタで渡すと吉。ただし Java と違って GC ないから、どこで
delete するかは要注意ね。
>>561 C++ でも this 使えますが?
なにかマズイんですか?
564 :
デフォルトの名無しさん :01/11/29 20:10
>>562 >C++ でも、それで良いけど。NULL チェック省くために参照にして
参照をそういう使い方してNULLチェックが省けるってのは、
考え違いだろ。
ポインタにNULLが入ってれば、参照でも結局クラッシュするし。
>>564 そりゃあ NULL をデリファレンスしたヤツが悪い。
>>565 言語と実行時環境で強制はしていないから、一種の紳士協定だわな。
ただしポインタを引数にとるメソッドでは、
- メソッドを呼び出す側、メソッド側どちらで NULL に対応すべきか明確ではない
(ふつうはドキュメントに書いておく)
のに対して、参照だったら
- メソッドを呼び出す側が NULL をデリファレンスしないようにすべき
というのは明白になる。NULL が入ったポインタ p に対して *p ってコードを書いた
時点で、そいつのチョンボなのは間違いない。
メソッドって、ひとつのメソッドを数箇所から呼び出すよね。 個人的にはメソッド側でチェックする方がスマートに感じるけどね。
俺は参照の場合はヌルチェックしない。 ポインタの場合は、仕様からして NULL が正常値な場合はそれでいいとして、 そうでない場合は assert 書いてる。
>>567 C++ でスマートといったら、スマートポインタ。
スマートポインタじゃないけど、auto_ptr って、あまり使えないな。 こんなものわざわざ標準化した理由は何?
>>570 exceptional C++読んでみて
ナニソレ?
>>570 オブジェクトの寿命をスコープで管理しないと、例外に対して堅牢なクラスを作るのが
面倒だから。
auto_ptr が微妙に使いづらい面があるのは確かで、Boost.org でも shared_ptr, scoped_ptr,
shared_array, scoped_array なんてクラスを提供しているし、ATL だと CComPtr という COM
用の独自のスマートポインタクラスを提供している。用途によって自分でスマートポインタを
作るのは、常套手段ではあるよね。
574 :
クロスゆるして(マルチ?) :01/11/30 00:21
今更だけど、ISAPIフィルタ作りたい。 良い資料/WEB等、無い??? 作りたいのは、認証システム。 doc, xlsファイルとかだと、直にURLたたかれたら、ユーザチェック できないでしょ?普通。 あ、win統合認証とかは使えない。 ユーザIDとパスワードたちは、DBに入ってるし。。。 MSのUSサイトいっても、イマイチ情報が古いし。
>>574 単純に、直に URL を叩かせなければ良いんでわ。
ごめん、 どこいけばいいの???
>>577 WebProg 板か、VC スレと思われ。
579 :
デフォルトの名無しさん :01/11/30 00:46
あ、ここC++ってことはVCとはかぎらんのか。。。 逝ってきます
580 :
デフォルトの名無しさん :01/11/30 03:55
環境: Win32 + STLport スレッドAの関数a: コンテナfooに値を挿入/削除(クリティカルセクションCで保護) スレッドBの関数b: コンテナfooの全ての要素にイテレータを使って順次アクセス/操作 コンテナfooはスレッドA&Bで共有。 aは任意のタイミングで呼び出され、bは定期的に呼び出される。 の場合、スレッドBの関数b全体をクリティカルセクションCで保護しなければ ならないのでしょうか? 関数bがすぐ終わるならいいのですが、関数aがそれなり に頻繁に呼び出され、bによってブロックされるのが好ましくないような場合、 bが長い時間かかると困ります。コンテナ全体の要素にアクセスしている途中で イテレータが無効になったらそれを判断できればいいのですが。 他方、bのようにするのをやめてコンテナfooの要素それぞれがスレッドを持つ ようにしたりすると効率上問題であると思います。 このような場合どうすればいいでしょうか。
>>580 コンテナに格納する要素数と比較して、挿入/削除される要素数が少ないのなら
> スレッドAの関数a: コンテナfooに値を挿入/削除(クリティカルセクションCで保護)
これをスレッドAで直接行わず、挿入/削除するコマンドを生成して一旦キューに
貯めて、スレッドBで処理を開始する前にコマンドを実行するようにします。
ロックする単位を、要素数が多いコンテナから比較的要素数が少ないコマンドキュー
に移すわけです。
>>581 なるほど... コマンドキューへの出し入れを排他ロックするだけで
よくなるわけですね。キューなら個数だけ調べて先頭をポップする
だけで済むので、イテレートする必要もなくていいですね。
ありがとうございます。
関数b で、コンテナ foo をコピーしてから使うという手もあるぞ。 コピーする一瞬はクリティカルセクションだけど、 コピーしてしまえばどんなに時間かけても大丈夫。 設計問題に絡むけど。
両方のスレッドで同じキューを使っていたら、 キューに対する排他が必要だぞ。
585 :
デフォルトの名無しさん :01/11/30 12:54
こんにちは、メモリの解放で悩んでいます。 取得は、、、 char* szBuf; szBuf = new char [1024]; subFunc(szBuf); で、sub()側で解放します subFunc(char* pBuff) : : delete [] pBUff; ここで、deleteの後 []を付ける事は問題ないのでしょうか? charの配列用のメモリを取得して、 charのポインタの配列用で取得したメモリを解放する。 これって問題ありますか?
586 :
デフォルトの名無しさん :01/11/30 12:56
はじめまして,ikuといいます。 いつも参考にさせて頂いています。 PathFileExistsでファイル検索をしたいのですが, 過去ログも拝見させて頂きまして, MSも見て下記の様な記述をしたのですが リンカーエラーPathFileExistsAが未解決といったエラーが生じて しまいました。 他に何が必要なのか検討がつきません。 大変申し訳ないのですが,教えて頂けないでしょうか? #include <windows.h> #include <iostream.h> #include "Shlwapi.h" char chrPath[100]; sprintf(chrPath,"%s",Edit1->Text); bool status = PathFileExists(chrPath);
588 :
デフォルトの名無しさん :01/11/30 13:10
こんにちは,ikuです。 PathFileExists(chrPath); の件ですが,解決しました。 下記が原因だったようです。 お騒がせしました。 #includeプリプロセッサ指令はコンパイル前にその場所へ そのファイルを挿入する指令です。 <shlwapi.lib> はテキストファイルではないので #include で 取り込むことはできません。 これは shlwapi.dll を暗黙で使うためのインポート ライブラリなので リンカに渡す必要があります。 C++Builderではリンクに使う指令があります #pragma link "shlwapi.lib" とソースファイル中に書くことによってリンカに 渡されます。 ただ、このままだと"shlwapi.lib"へのパスが 正しく張られていないので [プロジェクト|オプション][ディレクトリ/条件] の[ライブラリパス]に $(BCB)\Lib\PSDK を追加してください。
590 :
デフォルトの名無しさん :01/11/30 13:25
>>587 shlwapi.libをリンクする必要があると思われ。
591 :
亜美ちゃん ◆WOLFps4M :01/11/30 13:40
既出かもしれませんが、C言語しかしらないのにC++を使う仕事に今度入ります。 どのようなフローで勉強していくのが正しいでしょうか?
592 :
デフォルトの名無しさん :01/11/30 13:53
>>591 優良書籍を紹介してるスレがあるから、そこでC++とオブジェクト指向の
本を探して読む。
こんにちは。 C++BuilderのTQueryについて教えて頂きたいのですが, Databaseコンポーネントの様に TQueryコンポーネントでSQLServerのUserIDとPasswordを設定する事はできないのでしょうか?
594 :
デフォルトの名無しさん :01/11/30 15:04
>>591 デスマーチにはいりたくなかったら、現在出ている予定工数の1/5位を
C++の勉強に割り当てなさい。
習熟度に従って、開発効率やバグの発生頻度が大きく変わるからね。
>>583 >関数b で、コンテナ foo をコピーしてから使うという手もあるぞ。
>コピーする一瞬はクリティカルセクションだけど、
>コピーしてしまえばどんなに時間かけても大丈夫。
コピーにもそれなりの時間がかかりますので(コンテナの
要素全てがコピーされるので下手すると全要素をイテレートする
のと同様かそれ以上の時間がかかります)。
それにコピーされた要素に操作を行っても元のコンテナへ変更を書き
戻す手間が発生してしまいます。
>>584 >両方のスレッドで同じキューを使っていたら、
>キューに対する排他が必要だぞ。
581さんの話は両方のスレッドでコマンドキューを共有しな
ければ無意味な話だと思うんですが...?
これは582で
>なるほど... コマンドキューへの出し入れを排他ロックするだけで
と述べているように了解済みです。詳しく書けば、関数bでの先頭要素
の参照が終わった段階でのpopと、関数aで行われるpushとを排他する
ということです。
>>585 問題はないですが、例外に対して脆弱になるのと delete[] を間違えて delete
と書くと検出しにくいエラーになるので、STL の vector や string を使うのが
おすすめです。
string というと「文字列」という印象がありますが、多くの実装では参照回数計
測によって不要なコピーを押さえた可変長配列として使うことも出来ます。
あと、標準ライブラリではないですが boost::shared_array も便利ですよ。
http://www.boost.org/libs/smart_ptr/smart_ptr.htm
メモリの解放で悩むレベルだったら、 とりあえず、new/delete malloc/freeでも いいんでないかい?
598 :
デフォルトの名無しさん :01/12/01 10:39
while(1)とwhile(true)とfor(;;)のどれが一番いいんですか? どれも同じなのかな?
599 :
デフォルトの名無しさん :01/12/01 11:10
独学で学んでるちびっこです。 たぶんものすごい初歩的な質問ですみません。 int a[5] while(1) { scanf("%d",&a[i]) i++ } 配列変数のサイズを超えても構わないような方法を教えて下さい。 別の int b[6] を用意して、a からそっくり移せばいいのでしょうか。
一応600ゲットしておきます。
601 :
デフォルトの名無しさん :01/12/01 11:12
>>598 デフォルトの名無しさん wrote:
> while (1)とwhile (true)とfor (;;)のどれが一番いいんですか?
> どれも同じなのかな>
1つめと2つめはlintが文句いいますね。
出てくるコードはどれも同じでしょうけど。
>>601 ありがとうございます。
それ以外の上手い方法はないのでしょうか。
>>599 デフォルトの名無しさん wrote:
> int a[5]
> while(1) {
> scanf("%d",&a[i])
> i++
> }
> 配列変数のサイズを超えても構わないような方法を教えて下さい。
> 別の int b[6] を用意して、a からそっくり移せばいいのでしょうか。
だからscanfなんか使うな。
605 :
デフォルトの名無しさん :01/12/01 11:15
>>598 どれも同じ。
while(1)は警告を出す処理系があるので、for(;;)がよい。
と思うが、なぜかwhile(1)が良いという人も根強くいる。
606 :
デフォルトの名無しさん :01/12/01 11:16
>>604 使ってもいいが戻り値は見ろ、だろ。
ボケ
> 607 デフォルトの名無しさん wrote:
>
>>604 > 使ってもいいが戻り値は見ろ、だろ。
> ボケ
ぼけは自分でしょう。戻り値見ればscanf使ってもいいと思っているんだから:)
609 :
デフォルトの名無しさん :01/12/01 11:22
>>607 戻り値見てもどうしようもない事もある。
申し訳ありませんが、「vector」についてもう少し詳しく教えてください。 検索しても例のページばっかり引っかかっちゃって。
stl という単語を追加すれば?
612 :
デフォルトの名無しさん :01/12/01 11:35
vector <int> a while(1) { a.push_back() scanf("%d",&a[i]) i++ }
>>611 ありがとうございます。引っかかりました。
#include <vector>
vector<型> ベクタ名(サイズ);
ベクタ名.resize(サイズ);
これで解決しますでしょうか。
さっそく試してみます。
と思ったら
>>612 さんわざわざありがとうございます。
「push_back()」のあたりを調べてみます。
vector.hがないです。 VC++ 6.0なのですが。 どういうことでしょう。
C++の標準ヘッダは拡張子つかないのが基本。 拡張子なしのvectorなら確実にあるはずだが。
ごめんなさい、vectorありました。 using namespace std; この文を加えたらエラーが減ったんですが。 どうやら必要みたいですね。
c:\Program Files\Microsoft Visual Studio\VC98\Include\VECTOR
>>617 参考になりました。ありがとうございます。
おかげさまで一応完成しました。
ただ
>>612 さんの方法で
a.push_up() にすると
「関数が不正な 0 個の実引数をともなって呼び出されました。」になっちゃいます。
カッコの中に適当な数を入れたらエラーはでなくなりましたが。
それがちょっと気持ち悪いですね。
>>619 >それがちょっと気持ち悪いですね。
vector <int> a
while(1) {
int n;
scanf("%d",&n)
a.push_back(n)
}
突然ですが暗黙な型変換を防止するには どうやればいいんでしょうか? ヒントだけでもいいのでおねがいします。(ペコリ
>>621 explicit の事か?
それとももっと本質的なところか?
>>622 レスありがとうございます
いや例えば、
void (bool test);
とかでfalseとかtrueとかを引数として持たすとして
普通の定数を入れてもコンパイル側はワーニングとして
でるじゃないですか。だからそれをエラーとして
コンパイルできなくしたいんです。
VCとかでそういう設定をかける以外ってないんでしょうか?
>>624 すいませんclって何処の設定ですか?
探したんですけどみつからないです…
>>625 cl.exe は Visual C++ のコンパイラ実行ファイル。
Visual C++ 統合開発環境で設定するなら、メニューから [プロジェクト] [設定]
を開いて、[C/C++] タブ [カテゴリ] 一般を選択、表示されるダイアログにある
[警告をエラーとして扱う]
にチェック入れる。もしくは [プロジェクトオプション] に直接 /WX って書いても
良いけど(ここに書いた文字列が cl.exe に渡される)。
>>626 ありがとうございます
無事できましたー
628 :
名無し募集中。。。 :01/12/02 01:53
すいません、C++とVC++って何が違うんでしょうか・・・
ビタミン入りかどうかの違い
>>628 C++は言語の種類だがVC++は特定の商品の略称。
それともアレか? VC++のC++標準非準拠部分が知りたいのか?
VC++はC++にWindowを付けたもの。
>>630 いや、単純にVC++ってVBみたいなのかなーとか思ったりしたもんで・・・
VC++でC++の開発もできるんですねー
ありがとうございます
_
>>632 最強のC++開発環境とうたっているしな。
あと、もちろんCのソースもコンパイルできるよ(でなければあんなの使わない)
635 :
ボーランドマンセー :01/12/02 02:36
一般版とアカデミック版の価格差に むかついているのでボーランドマンセーです。
>>635 VS6.0Ent(アカデミック版)がVC++6.0Pro(通常版)の半値以下(笑)
637 :
ボーランドマンセー :01/12/02 02:47
>>636 そうなんだよねー。
それで買う気が失せました。
学生を5000円でスカウトしようと
したら怪しまれて終わりました。
638 :
デフォルトの名無しさん :01/12/02 15:17
constの使い方がいまいちよくわかりません。 誰かご教授おねがいできないでしょうか?
>>638 デフォルトの名無しさん wrote:
> constの使い方がいまいちよくわかりません。
> 誰かご教授おねがいできないでしょうか?
K&R 2ndにわかりやすく解説してありますよ。
template <class T> const T foo :fooオブジェクト const T &foo :fooオブジェクト const T *foo :fooポインタの指すオブジェクト T *const foo :fooポインタの位置 const T*const foo:上の両方 T::method() const :インスタンス変数 を、変更禁止とします。 (同時にconst_castなしでconstを剥がす事も禁止されます)
641 :
デフォルトの名無しさん :01/12/03 00:00
テンプレートの export って、g++ でも VC++ でも、まだサポートされて ないみたいだけど、テンプレートの定義を .cpp のほうにおきたいときって、 みなさん、どうしてますか? やっぱり、ダミーの関数かなんかを作って、その中で、必要なテンプレート 引数を持った型を生成しておく、とかするんでしょうか。 例 foo.h: template<class T> class Foo; foo.cpp: #include <foo.h> template<class T> class Foo { .... }; void dummy() { Foo<int> fooInt; // 型 Foo<int> が生成される Foo<char> fooChar; // 型 Foo<char> が生成される }
642 :
デフォルトの名無しさん :01/12/03 00:15
>>641 foo.cpp:
template<class T> class Foo { .... };
bar.cpp:
#include "foo.cpp"
void dummy() …
と軽くボケといて test.h: template<class T> class Foo {public: void test();} test.cpp: #include "test.h" template<class T> void Foo<T>::test() {} void dummy() { Foo<int> a; a.test(); } とかってこと? > テンプレートの export って、g++ でも VC++ でも、まだサポートされて > ないみたいだけど 「まだ」つーことは、そういう予定があるの??
644 :
デフォルトの名無しさん :01/12/03 00:48
>>642 さらに、別の翻訳単位からも呼び出して、リンクできるようにしたい
わけです。
hoge.cpp:
#include "test.h"
int main()
{
Foo<int> a;
a.test();
}
とか。
> 「まだ」つーことは、そういう予定があるの??
「プログラミング言語 C++ 第3版」の p413 には、
他の翻訳単位からテンプレート関数にアクセスできるようにするためには、
テンプレート定義に明示的に export を宣言しなければならない
という一文があります。
645 :
デフォルトの名無しさん :01/12/03 23:09
class A{ private: int age; double sage; public: A(int =0, double =0.0); } (1)のパターン A::A(int a, double s): age(a), sage(s){} (2)のパターン A::A(int a, double s){ age = a; sgae=s; } (1)と(2)はどう違うんですか? またどっちを使った方がいいのですか?
646 :
デフォルトの名無しさん :01/12/03 23:19
>>645 別に違わないが、(1)ならクラス内での宣言順通りに初期化しないと
コンパイラが警告くれる場合がある(ので(1)の方が厳格)
647 :
デフォルトの名無しさん :01/12/03 23:29
>>645 (1)はメンバオブジェクトのコンストラクタで初期化。
(2)はoperator=で代入。
intにdoubleじゃどっちでも変わらんような気もするが。
648 :
デフォルトの名無しさん :01/12/03 23:30
>>647 int,double以外の何だったら変わるんですか?
>>648 コンストラクタ中で例外が発生すると、デストラクタが呼ばれない、ってのは
知ってる?
(2)の場合、メンバ変数はデフォルトコンストラクタで構築された後、operator=で代入されるので、 デフォルトコンストラクタのコストが高いような場合だと差が出るかも。
>>645 Effective C++ の12項を参照。
652 :
デフォルトの名無しさん :01/12/04 00:49
>Effective C++ の12項を参照。 漏れなら Efficient C++ 2.4 をすすめるけどな
653 :
デフォルトの名無しさん :01/12/04 02:36
exportが有効になるということは プリコンパイル済みヘッダにテンプレートヘッダいれると コンパイル早くなるということなんだが 結局exportが有効になっても大してコンパイル早くならないとおもふ。
プリコンパイル済みヘッダ、云々の話は、正直よくわからないけど、 いい太古とはよくわかる。(IMEのバカめ) 使いたい型が最初から決まっている場合は、やはり、あらかじめ 生成しておくべき、ということでいいのかな。
ちょっとあほな質問で申し訳無いが、 class A: { public: const int b; }; のbってどうやって初期化するの?
まちがったage
コンストラクタで初期化せえよ
>>655 諦めてC言語でもやっとけ
class A { public: const int b; A::A() : b(100){} A::A(int n) : b(n){} };
class A { public: const int b; A() : b(100){} A(int n) : b(n){} }; 鬱
そうだった!どうもありがとう。 他に方法ないようねぇ?
コレでconst_cast/mutableつかうのやつにはカワズ掛け。
>>662 じゃ、こういうのはどうだ?
template <int NUM>
class A
{
public:
enum { b = NUM };
A()
{}
};
A<100> a;
コンパイル時に値が確定してる必要があるけどね。
mutableってのがよくわからんー なんで mutable const int *a; は出来て、 mutable const int a; は出来ないわけ?
const int を指すポインタ a は mutable である。 a は intで const で mutableである。 後者は矛盾しているが、前者は、そうでもない。 mutable int * const a; はエラーになるだろ? (未確認)
>>665 mutable const int *a;
const は int にかかってるけど、mutable は a にかかってるのがミソだね
記憶クラス指定子と同じ扱いだっけ? ごめん、きちっとした規格書会社にしかおいてない。
なんとなく分かったが… ややこしいなぁ。 って、655で言った const int b; の初期化ってmutableでは無理ってこと?? まぁコンストラクタかconst_cast使えば言い訳だけど。
class A{ class B{ }; }; こういうクラス宣言があったとして。 この宣言をしてあるヘッダファイルを読み込まずに他のクラスでclass Bを使う(先行宣言する)の ってできるのかな? class A; //先行宣言 class A::B; //先行宣言? class C{ A* a; //OK A::B* b; //NG };
670 :
デフォルトの名無しさん :01/12/06 09:23
やってみたよ。 const int a; const int *b; mutable int c; mutable int *d; // const mutable int e; const mutable int *f; // const int * mutable g; // mutable int * const h; const int * const i;
671 :
デフォルトの名無しさん :01/12/06 14:18
分かっていない質問で恐縮ですが、 コンストラクタとかデストラクタの定義をクラス外部に置いたとき、 inline付ける意味ってあるのでしょうか。 概念的に付けるのはおかしいのでしょうか。
>>669 だめみたいだね。これに似てるけど、g++ だと、
template<class T> void foo()
{
typedef T::B b;
}
なんてのも、templateのパース時にエラーになってしまう。
VC++ なら通るのに。
>>672 駄目なんかなあ。
その例だけど、
typedef typename T::B b;
ってやったら通らない?
>>671 inline付けないとヘッダ(もちろんクラス定義の外ね)に書けない。複数のオブジェクト大るを
リンクするときに二重定義扱いされてしまう。それだけ。
オブジェクト大る>オブジェクトファイル
>>671 class A{
public:
inline A();
inline ~A();
};
inline A::A()
{
}
inline A::~A()
{
}
って、こんな感じ?全然おっけーなはず。
inline 付ける意味は当然「我はインライン展開を望む」ってなことで、
外部に置くと何が嬉しいかというと、
クラス定義が多少見やすくなるってことかな・・・?
>>676 class A {} の中の方には inline は不要
>>676 > 外部に置くと何が嬉しいかというと、
> クラス定義が多少見やすくなるってことかな・・・?
A のメソッド中で B を使い、B のメソッド中で A を使うようなコードを書ける。
どうもありがとう。
私の目的はまさに
>>676 の最後の行なんですが、
1. クラスの中で定義した内部関数は自動的にinline関数になる。
2. 内部関数をクラス外部で定義する場合はinline関数にならない。
3. 2の場合、定義の方にinlineを付けるとinline関数になる。
だったような気がしていたのですが、最近友人に
『クラスの内部関数は自動的にinline関数になる』(外部で定義しても、という文脈)
と言われて、なにやらこんがらがってしまいました。
それでコンストラクタやデストラクタはどうなんだろうと思い
ウェブ上のソースファイルをいろいろ漁ってみたのですが、
コンストラクタとデストラクタをクラス外で定義して、
さらにinlineを付けているというものは見つけられず、
一般的ではない(無意味な)のかなぁと思っていた次第です。
とりあえず
>>674 を踏まえたら『付けないと駄目』みたいですね。
>>679 inlineキーワードは、inline展開をするかどうか、
コンパイラがヒントとして使う。
つけないとダメかどうかは、コンパイラの性質による。
また、
コンパイラによっては付いていても展開しないし
コンパイラによっては付いていなくても展開する。
付いていても複雑な関数は展開しないし
付いていなくても単純な関数は展開する。
本当にinline展開されるのかどうかは、
つまり、コンパイルをしてみないと分からない、ということだ。
>>677 ども。確信できなかったんで両方に付けてみた。
>>678 あぁ、そうか。そういえばそうだ。指摘サンクス。
でもとりあえず付けておけばコンパイル時に二重定義でエラーが出ることは ないですよね? # 自分の場合、たまたまクラスにtemplateを使っていたので # inlineを付けなくても二重定義のエラーはでませんでした。 # もちろんtemplateがどうやって展開されるかもコンパイラ依存だと思いますが・・・。
>>682 「あれ? 俺何時の間に書いたっけ?」と思たーよ
>とりあえず付けておけば
だぁね。逆にソースの方に書く場合はinline付けない。
>>680 ちなみにMSVCだと__forceinlineてなキーワードもある。コンパイラオプション
でインライン展開の制御もできる。
知ってるが、ここはまあ、一般的なことを話す場ということで
デストラクタにインラインはやめとけ
687 :
デフォルトの名無しさん :01/12/07 09:05
virtualにするから?
>>683 ごめんなさい。
>>682 を書いたのは671です。
>>685 もう一つ疑問が生まれました。
派生クラスを基底クラスとして扱った場合(base_class* base_ptr=new derived_class)、
デストラクタをvirtualにしておかないとうれしくないことが起こる、
というのは分かるのですが、この場合
class A{
virtual ~A();
};
inline A::~A(){}
とするのは可なのでしょうか。
>>680 おいおい、ヘッダ上のクラス外メンバ関数定義には
inlineつけないとダメだろ?リンクエラーじゃん。
付けても付けなくても実際にインライン展開されるかどうかは
コンパイラ次第というのはその通りだけどさ。
>>688 それはヘッダ上の話かい?
ヘッダ上の話として「inline可」かつ「inline必須」だよ。
実際にはインライン展開されることは無いけどな。
でも普通は、class A { virtual ~A() {} }; と書くか、
CPP上に、inlineなしで A::~A() {} と書く。
691 :
デフォルトの名無しさん :01/12/07 10:25
>>690 virtual なデストラクタのインライン展開は、スタティックバインドできる
なら可能なような気がするんだけど、どうでしょうか。
>>690 ヘッダ上の話です。すみません。
とりあえず胸のつかえが取れた気分です。
どうもありがと〜。
>>673 通った! そっかぁ、typename が必要なんだ。
勉強になりました。ありがとう。
694 :
デフォルトの名無しさん :01/12/07 15:54
# include<stdio.h> int aho( int i1 , int i2 , int i3 ); int main(int argc, char* argv[]) { int iRet = 4 ; int iRet2 = 0; int iRet3 = 0; int iVal = aho( iRet , iRet2 , iRet3 ); printf( "iRet = %d \n",iRet ); printf( "iRet2 = %d \n",iRet2 ); printf( "iRet3 = %d \n",iRet3 ); return 0; } int aho( int i1 , int i2 , int i3 ) { i2 = i1 + 1; i3 = i1 + 2; printf( "i1 = %d \n",i1 ); printf( "i2 = %d \n",i2 ); printf( "i3 = %d \n",i3 ); return 0; } で、ahoの第2引数と第3引数に結果をmainに渡したいのだけど、 渡す方法がわかりません。どうすれば引数としてmainに戻せますか? もちろん、戻り値で戻すのは知ってます。引数として値を戻したいん です。
695 :
デフォルトの名無しさん :01/12/07 16:00
>>694 C++なら、int aho(int a, int& b int& c)とすればいいよ。
696 :
デフォルトの名無しさん :01/12/07 16:07
ネタニマジレスカコワルイ
697 :
695じゃないが・・・ :01/12/07 16:23
>>696 おいおい、なんの話だ?694か?ネタ?あれ。
>>691 そだね。スタティックバインド可能な場合は
inlineつけとけばインライン展開される*かも*しれん。
でも、virtualデストラクタとしたクラスは、
普通は基底クラス型のポインタ経由で扱いたいわけで、
それで扱う限り、スタティックバインド可能な機会が無い。
701 :
デフォルトの名無しさん :01/12/08 09:24
かなりしらけたところで技術的な話に戻しましょう
CからC++に移ってconst指定リファレンスはconst指定メソッドしか 呼べないというにハマって一時はめんどくせ〜って思ったけど、 const があるお陰でソースの可読性が飛躍的に上がった。
可読性と同時にショボイミスが減るだろ。
706 :
デフォルトの名無しさん :01/12/09 04:40
class B : public A {}; の B が、シングルトンになるような A は、どう書けばいいんですか?
>>706 A、Bのコンストラクタは隠蔽して、Aにシングルトンインスタンス
用のハンドル置いておいて、Aの代理コンストラクタでBを作るよう
にすれば?
>>707 やってみました。動いてるみたいです。
こんな感じで良いんでしょうか?
できれば、もっと B の負担を減らしたいです。
Windows98 Mingw1.1 で確認しました。
とりあえずエラーチェック無しです。
#include <iostream>
class A
{
public:
virtual ~A () { m_instance = 0; }
protected:
A () {}
static A* getInstance (A* (*newInstance) (void))
{
if (!m_instance)
m_instance = newInstance ();
return m_instance;
}
private:
static A* m_instance;
};
A* A::m_instance = 0;
class B : public A
{
public:
static B* getInstance (void)
{
return dynamic_cast<B*> (A::getInstance (newInstance));
}
const char* getName (void) { return "B"; }
private:
B () {}
static A* newInstance (void) { return new B; }
};
int main (void)
{
B* b = B::getInstance ();
cout << "My name is " << b->getName () << "." << endl;
delete b;
return 0;
}
そのメソッド名キモイ
>>706 私なら template 使って書くかな。
template <typename T>
class Singleton
{
static bool m_IsAlive;
protected:
Singleton()
{
assert(!m_IsAlive);
m_IsAlive = true;
}
~Singleton()
{
assert(m_IsAlive);
m_IsAlive = false;
}
};
template <typename T> bool Singleton <T>::m_IsAlive = false;
template <typename T>
class A : public Singleton<T>
{};
class B : public A<B>
{};
>>706-708 意図がよく分からん。何か、これだと、
B と同じような定義で class C : public A { … }; も定義すると、
C::getInstance();
は、先に生成した B のインスタンスを返してくれちゃうけど。
>>711 いや、dynamic_cast やってるから、NULLだな・・・と、さりげなく突っ込んでみたり。
意図がわからんのは同感。
>>709 get〜 とかですか? instance や name の方が良いんでしょうか?
>>710-712 継承するだけでシングルトンになるクラスがほしかったんです。
>>707 さんの方針に従ってエラーを潰していくうちに、こうなって行ったので、
dynamic_cast とか良く分からないままです。
自分で考えていた時には、コンパイルも通っていませんでした。
複数のクラスで継承できないのは、継承したクラスのほうで dynamic_cast が 0 なら、
例外でも投げようと思っていましたが、出来ないのは変ですね。
template も良くは分かりませんが、何とかしてみます。
ありがとうございました。
>>713 > 継承するだけでシングルトンになるクラスがほしかったんです。
こんなテンプレートでどう?
template<class T> class Singleton : public T {
private:
static T *m_instance;
public:
static T *instance();
};
template<class T> T* Singleton<T>::m_instance = 0;
template<class T> T* Singleton<T>::instance()
{
if (!m_instance)
m_instance = new Singleton<T>;
return m_instance;
}
class B;
int main()
{
B* b = Singleton<B>::instance();
……;
delete b;
return 0;
}
>>714 あれ? なんで new Singleton<T>; にしてたんだろ。
m_instance = new T;
で問題ないよなあ。
>>714 どうも、ありがとうございます。
でも、Singleton<B>::instance() 以外では生成されなくするには、
どうしたら良いのでしょうか?
B のコンストラクタを protected に置いてみたら、
`B::B()' is protected
と怒られました。
>>716 あ、その質問で new Singleton<B>; にしていたわけがわかった (^^;
B のコンストラクタを protected にすると、B 以外 (B の派生クラスも含めて)
のインスタンスからは、明示的に B を生成することは出来なくなるんです。
だから、Singleton<B> からは、new B; はできない。ということで、
new Singleton<B>; にしてたんだな。ようやく思い出した。バカだ > おれ
んで、Singleton<B> のインスタンスとかは必要ないと思うので、Singleton の
デフォルトコンストラクタも private で定義しておくのが吉でしょう。
>>713 > 継承するだけでシングルトンになるクラスがほしかったんです。
じゃあ
>>710 の class Singleton で良いと思うが。
>>717 仰る通りにしてみたら出来ました。
ちょっと思ったんですが、B のデストラクタは virtual にした方が良いんでしょうか?
それとも、Singleton には static なものしかないので、必要無いのでしょうか?
>>718 >>713 の時点で、
>>710 さんのクラスで思った通りの結果が得られました。
ですが、後学のために instance () からポインタを得る方法も、
自力で template を使って実装しようと考えていたんです。
言葉足らずでした。
>>719 > ちょっと思ったんですが、B のデストラクタは virtual にした方が良いんでしょうか?
いいえ。
デストラクタを仮想化する必要があるのは
class A {};
class B : public class A {};
A* p = new B;
delete p; // p は A* 型
こういう、基底クラスへのポインタに派生クラスのインスタンスが入っている場合。このときに
デストラクタが仮想化されていないと「p は A* 型、つまり ~A() 呼べば OK」となって問題が
発生する。
Singleton() の場合には、そもそも Singleton 型のポインタに対して delete を呼ぶことはあり
えない(それを保証するためにデストラクタを protected にしてある)から、デストラクタは非
仮想で OK。
721 :
1 v(^・^)v :01/12/10 12:25
ご機嫌いかがか下僕ども。 Modern C++ Designをもう読んだろうな。 どうやらC++はもはやクラス階層自体をテンプレートで 定義できてしまうようだ。デザインパターンコミュニティを すっかり黙らせて、過去のイディオムをすっかりひっくり返す。 この高級アセンブラもどきが最も進化した言語であるとは皮肉だな。 この点についてご意見を伺おうか。君はC++を畏れるのか。
722 :
デフォルトの名無しさん :01/12/10 12:31
723 :
クロスボウとやら :01/12/10 14:37
質問です。Win32プログラミングにはコールバック関数ってのが 出てきますが、こいつをクラスのメンバ関数にしたいと思います。 一般的(あいまいな定義ですが)にコールバック関数はPrivate、 Publicのどちらに定義した方がいいですか?Private派、Public派 の意見が聞きたいッス。
どうせstaticにすんだろ? publicの方がいいんじゃないの。 オブジェクト指向と関係ないんだし無理するこたあない
725 :
デフォルトの名無しさん :01/12/10 15:54
> 最も進化した 進化のなれの果て、だな。 アンモナイトが絶滅するときに奇形種が さかんに出てきたのだが、ちょうど そういう時期に相当するのだろう
726 :
クロスボウとやら :01/12/10 16:03
>>721 その本は読んでないが、
>どうやらC++はもはやクラス階層自体をテンプレートで
>定義できてしまうようだ
(partial) specialization を駆使する、てことか?
728 :
デフォルトの名無しさん :01/12/10 16:21
>>725 その奇形種とやらがJavaやC#ですがなにか?
729 :
デフォルトの名無しさん :01/12/10 16:26
>>729 Objective-C支持者の方ですか?
質問の意味がわからん。 Objective-Cはキメラじゃないの?
>突然変異 >奇形 コレって主観的評価じゃん。同じだろ。成功すれば突然変異、失敗すれば奇形。
>>722 Modern C++ Design が面白かった、と言いたいのでは? 俺も読んだけど、確かに面白かったよ。
734 :
デフォルトの名無しさん :01/12/10 17:42
>同じだろ。成功すれば突然変異、失敗すれば奇形。 違うよ。成功、失敗というレベルでの分類じゃないもん。
>>734 どういう分類か書いてないから、何ともいえんが。判断基準を明記した方が実のある議論に
なると思われ。(ならくてもいーけど)
突然変異は遺伝するけど、奇形は遺伝しないってイメージがあるなぁ。
んで,その Modern C++ Design って訳本無いの? 探したけど無いっぽい. # 英語読めと言われたらそれまでなんだが…
>>736 そら劣等種は種を残せずに淘汰されるからそもそも遺伝できないだろうよ。
だから歴史の証明を待つまでは主観的評価、歴史の判定が下った後では
客観的評価だ。
C#は、さしづめJavaがC++とVBとObject Pascalに輪姦されてできた私生児って
とこかな 笑
>>738 もうちょっとまともな例えは出来ないのか?
お里が知れるよ
降臨したぞ下僕ども。
・・・なんだこのクソレスは(゚Д゚)y
>>727 以外、言語名の英単語しか言ってないじゃないか貴様ら。
>>737 よ、Modern...は英語簡単なのでがんばって読めよこの(゚Д゚)バカチン。
>>733 なんかまだ全部読んでないだろ!(゚Д゚)
下僕どもは年明けまでにMore Exceptional C++のレビューしておくこと!!
あ、俺はSchemeやってっから。いやほんと。んじゃ。
741 :
デフォルトの名無しさん :01/12/10 22:22
>突然変異は遺伝するけど、奇形は遺伝しないってイメージがあるなぁ。 生物科出身の漏れにはツッコミたいところだらけだが 我慢します。
>740 リョカーいした.簡単なら読んでみよう.でも漏れの英語力も相当低い・・・(蔚 その前に Exceptional C++ も読んだ事無い漏れは厨房か? 日々是勉強だのぅ・・・
>>740 あんた微妙にスレ違いじゃない?
推薦図書スレでやれよ
>743 いや,アソコはすぐ荒れるから C++ 関係の本はこっちでやっもいいんじゃん. ・・・っつーかむしろこっちでやって欲しい・・・
>>739 Java「やめてっお父さん!!!」
C++「ふふふ、怖がることはないよ、安心しなさい...」
VisualBasic「ダンナ、犯っちゃっていいんですかい? ハァハァ」
ObjectPascal「Hejlsbergさんにも感謝しなけりゃな... 変態のおいらは後ろをっと」
Java「いっ痛いッッ!!! synchronizedだなんてッッッ!!」
C++「$unめ、Forteもっと使いやすくしろよ、64ビットだけじゃ満足できねぇんだよオラオラ」
VisualBasic「ぎ、ぎもぢええ〜プロパティプロパティ」
>>743 C++スレでC++の本語らないでな〜にを語るんだこのバカチン(゚Д゚)め!め!
あっちはこっちで紹介されてる本参照してるんだよ!
これは言葉狩りですよみなさん!!
・・・つーかこのスレ立てたの俺だった!(゚Д゚)y
お前は最悪なのでInside OLE読破の刑なー!。なー!
>>746 こんごも、そのコテハンを使いつづけるようにな。ホットゾヌの NG ワードに指定するから。
俺は意外と好きなんだがな…v(^・^)v
"Modern C++ design"は出てすぐに読んだ。 自分がこれほどまでにtemplateの可能性を知らなかったとは、愕然! template好きからtemplateオタクへ
751 :
デフォルトの名無しさん :01/12/11 10:34
752 :
デフォルトの名無しさん :01/12/11 13:29
>>751 値段になっとくいかねー。なんでこんな安いんだ。まっとけばよかった・・
>>751 うっはぁ! ついさっき、amazon で原書を注文しちゃったよ。
キャンセルしてこよー。
754 :
デフォルトの名無しさん :01/12/11 15:42
この本ってプロとしてC++で開発する立場なら読んでおくべき? 「お約束」くらい大事な本?
>>754 娯楽用だと思っておく方がいいと思われ(笑) でないと応用に苦しむ。
756 :
デフォルトの名無しさん :01/12/11 16:29
クラステンプレートの中でテンプレートのフレンド関数を宣言するやり方を 教えてください。たとえば、g++ では、以下のコードをコンパイルできます。 template<class T> class A { friend bool operator==<T>( const A& x, const A& y ); }; template<class T> bool operator==( const A<T>& x, const A<T>& y ) { return true; } int main() { return 0; } しかし、VC++ だと、2行目の operator==<T> の 「<T>」を削除しないと コンパイルできませんでした。ところが、これを削除してしまうと、g++ では、 template_friend.cpp:2: warning: friend declaration `bool operator==(const A<T>&, const A<T>&)' declares a non-template function template_friend.cpp:2: warning: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here) -Wno-non-template-friend disables this warning. というような warning が出ます。前のほうで何かうまいプロトタイプ宣言とかを すればよいのかな?
>>755 おーこれすげーみたいな?
実際の現場で使えるかどうかは別問題って事かな?
>>756 これでは駄目なの?
template<class T> class A {
friend bool operator==(const A<T>& x, const A<T>& y);
};
template<class T> bool operator==(const A<T>& x, const A<T>& y)
{
return true;
}
int main()
{
return 0;
}
>>757 そのうち、この本の手法使ったclass libraryが増えてくるような気がする…
STLport好きな人、教えてください。 STLportを使った自分のプロジェクトに、VC++6標準のSTLを使ったライブラリ(*.libと*.hが利用可能)を 組み込もうとしたんだけど、上手くいかないんですよう。リリースビルド時に例外起こして逝きます。 デバッガで追いかけてみたらdelete時にメモリ破壊してました(debugビルド時は平気)。 ライブラリのヘッダの #include <vector> でSTLportの方のvectorがincludeされてしまい、おそらくそれが原因では無いかと思っておるのですが。
逝ってきます。
ウェー,アブネェ,アブネェ. 危うく原書チャレンジしちまうところだったよ・・・ これでまた俺の英語力は上がらんな(藁
>>758 引数の型の A のところに <T> を付けるわけですね。これもやりましたが、
やはり g++ では warning が出ます。class A の中での friend 宣言なので、
A が T を引数にとるテンプレートであることは、コンパイラにはわかって
いると思われます。
とりあえず、
>>1 で示されているサイトにある標準仕様のドラフトを読んで
みることにします。
>>764 標準仕様に沿わないのがVC++
コレ定説
せめてANSIには準拠して欲しいよなあ・・・
In article
>>765 , デフォルトの名無しさん/sage/765 wrote:
>
>>764 > 標準仕様に沿わないのがVC++
> コレ定説
> せめてANSIには準拠して欲しいよなあ・・・
たとえばどの辺ですか?
In article
>>765 , デフォルトの名無しさん/sage/765 wrote:
>
>>764 > 標準仕様に沿わないのがVC++
> コレ定説
> せめてANSIには準拠して欲しいよなあ・・・
たとえばどの辺ですか?
In article
>>765 , デフォルトの名無しさん/sage/765 wrote:
>
>>764 > 標準仕様に沿わないのがVC++
> コレ定説
> せめてANSIには準拠して欲しいよなあ・・・
たとえばどの辺ですか?
769 :
デフォルトの名無しさん :01/12/12 01:07
>>767 名称が。
確かANSIの規格書にはVisual C++という名前を付けてはいけなかったはず。
eの値を小数点以下100桁まで求めるプログラムと πの値を小数点以下100桁まで求めるプログラムを教えてください。
>>767 for(int i=0; i<N; ++i);
for(int i=0; i<N; ++i);
とか、
template<class T>
class Hoge
{
template<class U>
T method(const U& u);
};
>>771 あとは
void foo();
void bar()
{
return foo();
}
これがコンパイルできないとか。(おかげで bind が微妙に使いづらい)
>>772 要するにスコープから出るときにfoo()を実行したいということか?
bindってなに?
774 :
デフォルトの名無しさん :01/12/12 20:09
質問というか素朴な疑問なのですが、 関数パラメータのデフォルト値に変数が使えない理由を知りたいです。 例えばブール変数をメンバに持ったクラスでトグル用のメンバ関数を定義するとき、 気持ち的には以下のようにしたいのです。 class my_bool { public: bool elem; bool toggle(const bool& b=!elem) { // (*1) // 引数が指定されればelemを引数の値にセット // 引数が指定されなければelemを反転した値にセット elem = b; return elem; } }; もちろんこれは(*1)のところでエラーがでます。 これが可能ならば上のような操作を簡潔に書けてハッピーなのですが、 デフォルト値に変数が使われると何かまずいことがあるのでしょうか?
>>774 class my_bool {
public:
bool elem;
bool toggle(const bool& b) {
return elem = b;
}
bool toggle() {
return elem = !elem;
}
};
776 :
デフォルトの名無しさん :01/12/12 20:59
元VB厨房です(藁 あのう、クラス内で文字列を宣言して、それを定数にする方法ってありますか。 っていうか(あればですが)文字列の定数を宣言する方法がわかりません。 どなたか教えていただけますでしょうか。
>>770 eもπも大学の本読まなくちゃだめだぞ
テーラー展開とかそこらへん探せ
あとアークサインとかアークタンジェントとかも
キーワードだ。あれを整数でやるのはきついかな
>>776 class Hoge{
public:
static const char* const str;
};
const char* const Hoge::str = "string-literal";
>>775 >>774 に書いたのは簡単な例で、実際はトグルした後に長い処理があります。
ですからオーバーライドはしたくないのです。で、今どうやってるかというと、
class my_bool {
public:
bool elem;
bool toggle(const int& i=-1) {
if (i<0) elem = !elem; else elem = (bool)i;
return elem;
}
};
としています。これでもとくに問題はないのですが、
5行面のconst intをboolに変えるところでwarningが出ますし
見た目も良くないなぁと。で
>>774 に書いた疑問を感じたのです。
>>779 >トグルした後に長い処理
その長い処理を関数にすればいいだけじゃないの? それをオーバーライド
してる関数2つに入れればいい。
>bool toggle(const int& i=-1) {
> if (i<0) elem = !elem; else elem = (bool)i;
> return elem;
> }
「引数が指定されれば」という条件はソース書いてる時点で静的に判定
できる条件のはずなのにそれをわざわざ動的に判断する条件に読み替え
ようとしているようで気持ち悪いのだけど。
普通に考えて関数の実引数は関数を使う場所のスコープだよな。
>>776 もしそれが const なインスタンス変数ならば、コンストラクタの
初期設定リストを使わなければ初期値を設定することはできない。
>>779 くだらん。何を悩んでるのかさっぱり。
class my_bool {
public:
bool elem;
bool toggle(const bool& b) {
return elem = b;
}
bool toggle() {
return toggle(!elem);
}
};
784 :
デフォルトの名無しさん :01/12/13 17:39
>>773 いや、そうじゃなくて。
普段 void を返すような関数に対して return foo(); なんて書くことはないんだけど、これがテンプレートを
使ってると良く出てくる。たとえば
class Object
{
public:
virtual void DoSomething() = 0;
};
std::vector<Object*> v;
std::for_each(v.begin(), v.end(), std::mem_fun(&Object::DoSomething)); // *1
とかね。
std::mem_fun から展開される std::mem_fun_t はたいてい
template <typename TRet, typename TParam>
class mem_fun_t
{
TRet operator(TParam* p) { return (p->*func)(); }
};
みたいに定義されているから TRet が void の場合 (上の Object::DoSomething() とか)だと
上の (*1) で VC6 だとコンパイルが通らなくなる。ANSI C++ 的にはコンパイルできるハズ。
> bindってなに?
bind は Boost.org にある boost::bind のこと。これを使うと引数を複数取ったり、参照をとる関
数に対しても関数オブジェクトが作れる。std::mem_fun, std::mem_fun_ret, std::bind2nd 捨て捨
てですよ。
class CTaskBall
{
...
int exec(const IControllerTask& con, DWORD dwTick);
};
class CTaskBalls
{
typedef std::vector<boost::shared_ptr<CTaskBall> > CBallList;
CBallList m_ball;
void exec(IControllerTask& con, DWORD dwTick)
{
std::for_each(m_ball.begin(), m_ball.end(), boost::bind(&CTaskBall::exec, _1, boost::ref(con), dwTick);
}
};
>みたいに定義されているから TRet が void の場合 (上の Object::DoSomething() とか)だと >上の (*1) で VC6 だとコンパイルが通らなくなる。ANSI C++ 的にはコンパイルできるハズ。 ああ、それか〜俺は仕方ないから無意味にtrue返したりとかしてるけどね(笑 どうせ使われて ないのでコンパイラが最適化してくれるのではないかと願って。 イテレータとか、コンパイラが最適化対象として認識できないほどに抽象度が 高い物って少々緩くてもいいんじゃないかという気になってしまうな。 VC++7はテンプレートのウザい警告とか消えてるのかな?
786 :
名無しさん@Vim%Chalice :01/12/13 17:51
bind 初めて知った便利そう age ちーと調べてみるかいのぅ. boost ってあんまいぢってなかったけどいぢってみよーかな.
もう話は終わってますが
> 関数パラメータのデフォルト値に変数が使えない理由を知りたいです。
正確には『クラスのメンバ関数のパラメータのデフォルト値にメンバ変数が使えない』
でした。外部変数ならばデフォルト値にできます。またメンバ変数であってもenum型なら
OKです。しかしconstのメンバ変数(デフォルトコンストラクタで初期化)は駄目でした。
何か理由があるのかないのか・・・。
>>783 悩んでいたのは実装方法とか実装方針についてではなくて、
メンバ関数のデフォルト引数にメンバ変数を与えてはいけないのは
どうしてかという点でした。実装については
>>780 ,
>>783 にあったように
オーバーライドしようと思います。どうもです。
ちゃんとクラス指定してる? そのメンバ関数を使う場所がクラスの外なら クラスを指定しないとメンバ変数にアクセスできないよ?
>>787 デフォルト引数として使えるのは、「宣言の時点でスコープに入っていて、
かつ、実体を特定できる変数、定数、関数などからなる式」と考えれば
よいと思う。
メンバ変数が指定できないのは、宣言の時点ではオブジェクトが存在しない、
つまり実体のないものを指定しているから。クラス変数なら、実体が
確定するのでデフォルト引数として使える。
ってゆうかnewに失敗したくらいで例外投げないでくれない?
>>787 君ねぇ オーバーライドとオーバーロード間違えて覚えてるよ。
基礎から勉強しなおしてみて。
>>771 >for(int i=0; i<N; ++i);
>for(int i=0; i<N; ++i);
このコードは、/Za コンパイルオプションをつければコンパイル
できますけよね。(これがコンパイルでき「ない」のが「言語拡張」、
ってのは、どーかと思うけど)
>>781 スコープを指定してもコンパイルが通らないのでやはり駄目なのだと思います。
>>789 なるほど。『宣言の時点で実体を特定できないものは駄目』というのは
感覚的によく判りました。const指定したとしてもコンストラクタが
呼ばれない限り実体はないので、定数だったらよいというわけでもないんですね。
なぜ実体がなければデフォルト値にできないかという話になると
仕様ということになるのでしょうか。
>>792 どうもです。オーバーロードでした。
名前も働きも似ているのでときどき判らなくなります。
795 :
真・初心者 :01/12/13 22:28
たぶんとても初歩的な問題なんですけど、 「要素数がnであるint型配列xの最小値とその添え字を返却する関数」 を作りたいんですが、最小値は出せたけど添え字の返却がよくわかりません。 誰か教えてもらえないでしょうか?
>>795 阿呆ですか?
最小値ではなくその要素の添え字を返せば、
同時に最小値も取得できるでしょうに。
それとも、その配列とやらは関数内のローカル変数かよ。
DQNにマジレス、鬱氏
>>794 クラス定義の中でメンバ変数のスコープ指定ってどうやるの?
798 :
真・初心者 :01/12/13 22:57
阿呆です。 よくわからんのですが、例えば int X[i]があったとして、 Xは return(X)で返せますよね? iを返したい場合は return(i)じゃ できないっぽいんですが・・・
799 :
真・初心者 :01/12/13 23:01
間違えた。 min=x[i]となっててminは返せるけど iはどうやって出せばいいんですか?
801 :
真・初心者 :01/12/13 23:08
int minof(int x[], int n) { int min = x[0]; for (int i = 1; i < n; i++) if (x[i] < min) min = x[i]; return (min); } よくわからんがこんな感じです。iを出すにはどこをどうすればいいのでしょうか?
>>801 いみわからん
return したいのは x[i]なのか? iなのか?
803 :
真・初心者 :01/12/13 23:15
なんていうか、両方なんですよ。もう一個関数作らないとダメですか? しかし、もう一個をどうやって作ればiが返せるかがわかりませぬ。
>>799 #include <iostream>
#include <vector>
#include <algorithm>
template <typename T>
struct MinIter
{
T* m_index;
MinIter()
: m_index(NULL)
{}
void operator()(T& n)
{
if (m_index == NULL)
m_index = &n;
else if (n < *m_index)
m_index = &n;
}
};
int
main(void)
{
int n[6] = { 10, 18, 3, 35, 1, 5 };
int* p = std::for_each(&n[0], &n[6], MinIter<int>()).m_index;
std::cout << p - &n[0] << std::endl;
return 0;
}
言うまでもないと思うが、最小値は *p で拾える。
>>真・初心者 コテハンウザイ、くだらん質問でageるな。 阿呆なオレに教えてくれ。 出ているエラーは何だ? 使っているコンパイラは何だ? VC++とかいう腐れ環境でなければ、 for(int i=0;;); とやったら、変数iはforの中でのみ有効だ。 forの前で宣言しろ、阿呆。
それ、C++の質問?>真・初心者。 classか構造体作ればできるけど、とても無意味。
ここをC++相談室と認識して聞いているなら、その質問への答えは、 きっとこうだろう。 問題も、「最小値とその添え字を返却する関数」だし。 template <class T> std::pair<int, int> minof(T begin, T end ) { int min=INT_MAX; T min_it; for( T i = begin; i != list.end; i++ ) { if (*i < min) { min = *i; min_it = i; } } return std::pair<int,int>( min, std::distance( begin,min_it ) ); }
810 :
真・初心者 :01/12/13 23:54
C++に間違いないんですけど。まだ関数を学んでる段階でして。 ちなみにVC++のソースファイルを使ってやってます。 なんだかよく理解できないです。すみませんどうもありがとうございました
>>794 クラス定義の中でメンバ変数のスコープ指定ってどうやるの?
できないと思います。自分が駄目元で書いたのは
class my_bool {
bool elem;
bool toggle(const booll& b=!my_bool::elem) { return elem=b; }
};
ですが、当然駄目でした。それで
>>781 さんが言いたかったことは
たぶん別のことなんだと思います。今回は
>>789 さんのアドバイスで
class my_bool {
public:
static bool elem;
bool toggle(const booll& b=!elem) { return elem=b; }
};
bool my_bool::elem=true;
とすれば当初の意図が達成できることが判り、気持ちすっきりしました。
# 実際にはtoggle()を2個用意するか、別にset()を用意しようと思ってます。
>>真・初心者 ゴメン、君面白いんで粘着させて。 > ちなみにVC++のソースファイルを使ってやってます。 私にも下さい、VC++“の”ソース(笑 プログラムの前に、最低限の日本語能力と逸般常識を学んでくれ。 教材としては、809さんが提示されたサイトが良いと思われ。
>>808 まだダメだ
numelic_limit<int>を使え
>>814 逸般で良いよ、IT業界(w)なんてオレも含めてDQNの集合だ。
多くは期待せん、PG/SE間に通じる意識でよし。
というか、真・初心者が一般常識を持つのは無理と思われ。
粘着終了、場を荒らしてすいませんでした。
>>811 でそのstatic版はコンパイル通るということね?
>813 これでどうよ、つか、numeric_limits‥‥ #include <vector> #include <algorithm> #include <limits> template <class U, class T> std::pair<U, ptrdiff_t> minof(T begin , T end ) { U min = std::numeric_limits<U>::max(); T min_it = end; for( T i = begin; i != end; i++ ) { if (*i < min) { min = *i; min_it = i; } } return std::pair<U, ptrdiff_t>( min, std::distance( begin, min_it ) ); }
>>817 フン、まあ許してやるか。
> for( T i = begin; i != end; i++ )
は
> for( T i = begin; i != end; ++i )
とすべきだがナ
820 :
デフォルトの名無しさん :01/12/14 01:57
C系統はプログラム組むのが面倒なんで 型無し汎用型をC++で実現してソースを載せてください。 文字列に対する演算はベーシックみたいのがいいです。
なぜ、よりにもよって、BASICみたいな文字列演算を望むのですか。 どうせ作るなら、正規表現系操作の方がよっぽど便利なのに。 たとえば、std::string str に対して、str.search( RegExp &exp ) みたいな拡張がしたいな、とか。 (RegExp::seach( std::string &str) は思想的にどっか間違ってる気がする。)
>>820 void*
てきとーにキャストして使え。
>>817 わざわざ min を持ってこなくても
T min_it = begin;
for (T i = begin; i != end; ++i)
if (*i < *min_it)
min_it = i;
で良い気がするな。一回多く比較するのはご愛嬌、間接参照が増えるのはコンパイラの
最適化にお任せ、ということで。(これで numeric_limits 定義してない型でも使えるし)
あとイテレータの指す値の方が必要なら iterator_traits<T>::value_type を使った方が良さ
そう。これなら T が int* だろうが vector<int>::iterator だろうが使えるし。
メモリを完全破壊するプログラムを見せてください。
>>826 ビルの窓からPCを投げ落とせ。
10階以上を推奨。
ついでにお前も飛び降りろ。
President_Bush.Push(BlackBox)
Cで思い出したけどさ VC++で拡張子.cだとC++のキーワードでエラーになるね(classとか) GCCは大丈夫みたいだけど
>>830 gcc もエラーになると思うけど。
拡張子によらず強制的に C++ のソースコードとしてコンパイルしたければ
gcc の場合 → g++ を使う、もしくはコンパイルオプション -x c++ を使う
VC6 の場合 → コンパイルオプション /TP を使う
じゃない?
832 :
デフォルトの名無しさん :01/12/14 23:10
>>793 VC++ のオプションに /Za 付けたらテンプレートで
エラー出まくりますが、そういうもんですか?
>>831 ごめん
MakefileでCC = g++してた(w
VC++でもコンパイルスイッチあるんだね
知らなかった有難う
>>831 便乗質問、逆に強制的にcとしてコンパイルするオプションて、
VC++にありますか?
以前に調べた限りでは見つけられなかったので…
VC++スレ逝けとか言わずに、お願い。
>>834 cl /? で調べると 5 秒で見つかると思われ。
/Zaつけると、Windows,h(winnt.h)でもエラー出ますし。
MS の拡張機能を ON にしているときは、 #define for if(0);else for というマクロを定義しておくと少し幸せになれるかもしれません。
839 :
デフォルトの名無しさん :01/12/15 13:40
friend 関数でちょっと混乱してるんだけど、friend 関数の宣言をしたクラス から派生したクラスは、その関数とは friend 関係にはない、という理解でよい? たとえば、 class B; class A { friend void foo( B& ); } class B : public A { private: int x; }; void foo( B& b ) { b.x = 1; // B::x にはアクセスできない } 何だか、「C++ 第3版」の C.13.2 を見ると、上のようなことが出来そうな 気がするんだけど、g++ 3.02 とかで試すかぎり、エラーになる。
840 :
デフォルトの名無しさん :01/12/15 18:24
list<T> lst; fnc(&lst); void fnc(list<T> *lst) {←ここで”構文エラー : 識別子 'list' がシンタックスエラーを起こしました。” ... ... } というように、templateのlstを引数にした関数fncを作りたいのですが、 エラーが出てしまいます。 どこがおかしいのかわかりません。C++むずかしいっす。 どなたか助けて…
>>840 template<typename T>
void fnc(list<T> *lst) {
...
...
}
In article
>>840 , デフォルトの名無しさん/840 wrote:
> list<T> lst;
> fnc(&lst);
>
> void fnc(list<T> *lst) {←ここで”構文(I閑?? : 識別子 'list' が(I杓政現閑?凾タを起こしました。”
> ...
> ...
> }
> というように、templateのlstを引数にした関数fncを作りたいのですが、
っていうか、それ以前の文字化けしてますよ。
>>840 using std;
もしくは、std::list<T>
って事とは違うの?
>>842 文字化けしてんのはあんたの脳味噌
>>843 おっしゃるとおりでした。std::つけないとだめなんですね。
どうもありがとうございます。
>>842 「それ以前の文字化け」ってなんですか?
>>846 >半角カタカナ使っちゃいました。
甘いな、「半角カタカナ使っちゃいました。」と書かなきゃ。
で、もう一度「それ以前の文字化けしてますよ。」とレスが付く。
コレ
>>843 using namespace std;
か?
>>842 >> void fnc(list<T> *lst) {←ここで”構文(I閑・ : 識別子 'list' が(I杓政現閑・ぢを起こしました。”
文字化けしてますYO!
プログラムのプの字も知らない私ですが、 いきなりC++に手を出すのは危険ですか?
>>851 C++を本気で理解するなら、C言語とアセンブリ言語を理解することになります。
危険ですが楽しいですよ、怖がらずにこっちへ来なさい(プ
Modern C++ Desing 買った YO! ハキーリ逝ってSTLに感動してるレベルの漏れには難しいYO! もーちょっとガムバルのDA!
854 :
デフォルトの名無しさん :01/12/15 21:30
参照の仕組みがわからない。 なんとなく使い方は解るんだけど…。 参照をポインターへ変換するプリプロセッサって考えていいんですかね?
プリプロセセッサじゃないだろ。
856 :
デフォルトの名無しさん :01/12/16 00:15
855サラシage
857 :
デフォルトの名無しさん :01/12/16 03:32
>>853 言語以外の内容がほとんど全くないにも関わらず
細かい所を見ていくと現在最も難しい本だと思います。
boostとのアプローチの違いを見たりするとなお面白いと思います。
MSのコンパイラが準拠するのはマジで2004年くらいな予感なので
のんびりやりましょう。
858 :
デフォルトの名無しさん :01/12/16 09:48
main()の正式な書き方を教えてください。 intとvoidどちらをつけるかとか引数とか
>>858 int main( [int argc [, char** argv [, char** envp ] ] ] );
void main( [int argc [, char** argv [, char** envp ] ] ] );
仕様とかマニュアル、本を何故読まないの?
> intとvoidどちらをつけるかとか引数とか
角度とか?
int main() int main(int argc, char**argv) int main(int argc, char*argv[])
>>858 なんか、最近この質問妙にあちこちで見るんだけど。
宿題かしらん?
863 :
デフォルトの名無しさん :01/12/16 22:03
>>857 まだ第2章の途中までしか読んでないけど、すごく面白い本だね。
整数値から型を生成するテンプレートを使って、オーバーロード
された関数を選択する、なんてテクニックにはちょっと感動したよ。
テンプレートの基礎をしっかり押さえておけば、読みこなすのは
そんなに難しくないんじゃないかな、という印象だけど、やはり、
細いところが大変なのかな?
>863 3章はムズいぞー. 継承に再帰を使われると一瞬なんだか分からなくなる(苦笑) まぁヲレが厨房なだけかもしれんが. 一応 Lisp 使ってたから再帰には慣れてたはずなんだけどねー.
良く見たら Design の綴り間違ってた.鬱氏.
>>864 >継承に再帰を使われると
あ、オレ、そういうの大好き(笑)。楽しみ〜。
>866 ヲレも好きは好きなんだよね.だから読んでてオモロイ. でもムズいなーって(苦笑)
なんだか generic programming のスレがほしくなてきたよ。
869 :
デフォルトの名無しさん :01/12/17 01:05
お互いのクラスオブジェクトを参照する関数を含んだ2つのクラスを 別々に2つのファイル(ソース+ヘッダ。ヘッダには宣言のみ)に定義 したのですが、ヘッダ内でお互いをインクルードすると互いのどちらかの 関数宣言が先に来てしまう事になって、宣言されてないクラスを参照している というシンタックスエラーが出ます。解決する方法ありますでしょうか? やっぱり仮想関数というのを使わないといけないんでしょうか。よく分かりません。 関数はこんなカンジのものです。test1メンバがtest2クラス自体を参照します。 void test1::show(test2& t2){}
871 :
デフォルトの名無しさん :01/12/17 01:12
>>870 どこですればいいでしょうか?
2つのヘッダでは、
・相手ヘッダのインクルード
↓
・クラス宣言{
パブリック:
・相手のクラスオブジェクト自体を参照するメンバ関数プロトタイプ
}
となっています。
それはクラス定義。
>>869 宣言
class test2;
定義
class test2 {};
>>872 class test1 ;
でいいでしょうか?
すいません。宣言のしかたが全然分かりません・・・
>>873 すいません。ありがとうございます。定義を宣言と思ってました・・・
876 :
ちょっと。 :01/12/17 01:26
コンストラクタ中での thisポインタの参照って、もしかしてNGですか?
参照というか、thisポインタへのアクセス。
そんなわけない。 ただ、virtual系メソッド呼び出しはNGだったかな
>878 ですよね。あー、ビックリした。
>>880 868 じゃないが、とりあえず新スレ 1 に並べる書籍は
Modern C++ Design
Andrei Alexandrescu, Addison-Wesley, ISBN:0-201-70431-5
Generic Programmin - STL による汎用プログラミング
Matthew H. Austern, ASII, ISBN:4-7561-3441-6
ぐらいか?
882 :
デフォルトの名無しさん :01/12/17 04:24
STLスレ行けよ C++スレ行けよ genericスレ行けよ たらい回しでどこにも誰もいなくなると思われ。
883 :
デフォルトの名無しさん :01/12/17 09:54
g++ 3.0.2 で、 void foo() { throw (int()); } とかやると、throw のところでコンパイルエラーになるんだけど、 これって例外指定だと思ってパースしちゃってるのかな? VC++ だと通るみたいなんだけど。
>>884 いや、int などの組み込み型でもコンストラクタは定義されてる。でないと template ライブラリを
書くときに困るぞ。
>>885 じゃ
int n = 5;
n.();
ってやったらn == 0になったりするの?
間違えた。 int n = 5; n();
>886 operator () と constructorは別種のものだと思うのですが。
>>888 んじゃ、これ?
int n = 5;
n.int();
デストラクタの明示呼出ならやらないことはないと思う
んだけどコンストラクタは...
890 :
デフォルトの名無しさん :01/12/17 15:34
0x00000123456789ab とlong型の変数にセットするにはどうしたらよいでしょうか。 どうしても頭がきれてしまいます。
891 :
いっぱいいっぱい :01/12/17 15:38
mafxcrd.lib : ライブラリが見つかりません というエラーメッセージが出てしまうのですが、どうすればなおるのか わかりません、どなたかご教授くださいお願いします。
>883 gcc 2.95やと、 class test{} void foo(){ throw (test()); } も通らないね‥‥とか思ったら、 void foo(){ throw int(); } だと通った。不思議な話。 >890 ええと、あなたのところでは、longは64bitだったりするのでしょうかね?
893 :
デフォルトの名無しさん :01/12/17 15:50
VC6で const int &n=int(); 通ったよ。
894 :
デフォルトの名無しさん :01/12/17 16:00
>892 32bitです。 0x00000123456789ab という値を構造体のメンバで配列をつかわずに 保持する事はできないのでしょうか?
>864 Q:64bitの数を32bit変数1つに入れるにはどうすればいいでしょうか A:(゚д゚)ハァ? 64bit分の情報を放り込むには、64bit以上の領域が必要だろが。 __int64とか、longlongでもつかっとけ。
896 :
デフォルトの名無しさん :01/12/17 16:09
897 :
デフォルトの名無しさん :01/12/17 16:21
__int64でできました。long longは使えませんでした。 調査不足でした。 ありがとうございます。
>>889 コンストラクタは n.(), n(), n.int() では呼び出せないだろ。入門書読んで出直せ。
int n = int();
int() なんて書いたもんだからいらん混乱を招いちまったみたいだね。
すまん。んで、
>>892 のように、
> void foo(){ throw int(); }
ならコンパイルできるわけです。つまり、throw (int()); と書くと、
void foo() throw( int …
のような例外指定とカンチガイして解析してしまうので、パースエラー
になるのかな、と。
900 :
デフォルトの名無しさん :01/12/18 16:11
>>899 おそらく、throw (int());
はint throw(int (*pf)());という関数宣言と見なされている。
関数名に予約語を使っておりエラーである。
(...int()...)がパラメータリストに見えるのだ。
宣言に見えるものは全て宣言になる。
>>900 10分くらい考えて、8割がたは納得しました。ためしに
return (int());
とやったら、これも同じエラーになりました。一方、
throw (int()+1);
はコンパイルが通ります。ということで、(int()) が
パラメータリストに見える、という説は説得力がありますね。
902 :
デフォルトの名無しさん :01/12/19 06:25
>>901 // 以下は全て同じ意味
int g(double d);
int g(double); // 仮引数名の省略
g(double); // 戻り値型intの省略
//以下は全て同じ意味
int f(int (*pf)()); // 引数は関数ポインタ
int f(int pf()); // 引数はやはり関数ポインタ
int f(int()); // 仮引数名の省略
f(int()); // 戻り値型intの省略
// 宣言と見なせるものは常に宣言
int n(); // 引数なし戻り値型intの関数宣言
では関数名らしきものがキーワードならそれを
宣言と見なすか見なさないかを標準が定めているのか
どうかは知らない
>>902 「8割がた」と書いたのは、戻り値型の省略された宣言は、ISO規格では
許されていなかったと思ったからです。それ以外については了解。
C99 だと、引数の int の省略も許されてなかったような。そうなると解釈が変わるのかな
Cにthrowがあるのですか?
>>901 によると return でもなるという話。
907 :
デフォルトの名無しさん :01/12/19 22:35
>>903 Effective STLによればこれを回避する方法はこれだ。
return ((int()));
が、うまくいかない上にむなしい。
暗黙のintを許しませんと警告するくせに
パーサーは古いままなのだきっと。
throwにも、returnにも、括弧なんかつけないのが一番、 ということでしょうかね。
909 :
デフォルトの名無しさん :01/12/20 10:15
こんな関数が定義されているとして void sub(const string &); 次のコードは正しい? string s; sub(s + s); g++ではOKだけどBorlandのコンパイラではエラーになる。
910 :
デフォルトの名無しさん :01/12/20 10:17
>>909 クラス string の実装にもよると思われ。
912 :
デフォルトの名無しさん :01/12/20 10:24
型のサブタイプって、含まれるインターフェイスを持つ型か、含む型か どちらですか?
913 :
デフォルトの名無しさん :01/12/20 10:26
>>909 ボーランドは
operator +
がconstをかえさないのかな?
>>913 オブションでエラーレベルから警告レベルに変えれたと思ったが・・・
C++は3年くらいご無沙汰してるので忘れた。
915 :
デフォルトの名無しさん :01/12/20 10:39
>>909 ボーランドのコンパイラで試したが、エラー出ないぞ
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
916 :
デフォルトの名無しさん :01/12/20 10:58
>>913 非const から const へのキャストは文法上何の問題もないし。
>>909 #include<string>
したけど、
using namespace std;
を忘れてるとか?
>>914 え!エラー出ない!
実際にエラーが出たのは上のコードではないけど
当然同じだと思って確認してなかった。すまんです。
もっかい確認してエラーが出るコード作りま〜す。
元のソースは3項演算子を使ってました。 これでエラーになります。コンパイラはBorland C++ 5.5.1です。 extern void sub(const std::string &); std::string s; sub(1 ? s : s + s); ちなみにstringでなくても同じエラーは起きます。 文法的に間違ってるでしょうか?
>>918 小さい石に躓いてないで工夫したら?
extern void sub(const std::string &);
std::string s;
std::string s2=1 ? s : s + s;
sub(s2);
とやったらエラー出ないと思うよ。
920 :
デフォルトの名無しさん :01/12/20 12:08
>>918 子どもじゃないだから、エラーメッセージくらい書けよ。
>>919 文法上どうなのかな?って聞きたかっただけです。
>>920 エラーメッセージは以下の通り。subの呼び出し部分でエラー発生。
Q:\>bcc32 test.cpp
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
test.cpp:
エラー E2357 test.cpp 12: 参照は 'string' で初期化されているが 'string' 型の左辺
値が必要(関数 main() )
エラー E2342 test.cpp 12: パラメータ 's' は const string & 型として定義されてい
るので string は渡せない(関数 main() )
*** 2 errors in Compile ***
>>922 あれ、そうだったのね。じゃこの件は終わり。皆さんありがとう。
924 :
デフォルトの名無しさん :01/12/20 16:31
class A{ private: A a; }; がコンパイルできねーYO。 どうしたらいいんすかね? VC++ & Win2000 javaなら速攻動くのにyo
925 :
デフォルトの名無しさん :01/12/20 16:40
>>924 Javaの変数はポインタじゃ。C++は違う。
class A{
private:
A* a;
};
>925 横から御無礼。 924みたいなのってクラス定義、はじめて見たんだけど、 どんなときにこういうクラス定義使うんですか?
>>924 ネタですか?自身を実体メンバとしては持てないよ。
java と同じことをしたいならば、
class A {
A* a;
};
だよ。
ねたじゃないよ。
まじです。
java & perl 厨房だからポインタわからんのです。
そういうことですか。
皆さんありがとう。
>>926 tree構造とか再帰的にデータをもつことができるかなとおもって。
定石かどうかわからないけど、javaだと結構やると思うよ。
おれだけか?
なるほろ
よく考えてみろ。 class A{ private: A a; }; C++の場合。 A a;と宣言したときに a.aも宣言される、またそのときに a.a.aも宣言される、 a.a.a.a a.a.a.a.a a.a.a.a.a.a a.a.a.a.a.a.a a.a.a.a.a.a.a.a 以下無限に続く つまり賢いコンパイラは通らないわけだ。 俺のコンパイラは通るけどスタックオーバーフロー起こすよ。
>>928 > tree構造とか再帰的にデータをもつことができるかなとおもって。
> 定石かどうかわからないけど、javaだと結構やると思うよ。
> おれだけか?
いや、実際よくやるけど、C++ ではすべてポインタになる。Java のクラス型の変数は C++ ではすべてポインタだと考えれば、だいたい問題ない。
Java の
ClassA a = new ClassA();
は C++ では
ClassA* a = new ClassA();
になる。
C++ で普通に
ClassA a;
と書くと、この場合 a は new の必要なく既に存在してることになる。これは int などと同じように、参照ではなく確固たる実体であって、NULL にしたり他のオブジェクトを指したりすることはできない。
C++の場合 class A { A* a; void init(){a=new A();} }; とやるのが普通
933 :
デフォルトの名無しさん :01/12/20 23:03
こういうのならやったことある。 class A { vector<A> child; }; でも通らないコンパイラもある。 テンプレートの実装によるのかも。
なんとなくC的によくある typedef struct node { int nodedata; struct node* next; } NODE; みたいなのはC++ではあんまり見たくないなあ
>>934 C++ では、STL があるから、
基礎データ構造を自前でコーディングする機会がないっすね
>>935 そんなことはない。
バランスしない純粋な二分木とか、言語処理系の中間段階などで良く使う DAG といったデータ
構造は、STL ではサポートされてないもの。確かに C に比べれば、自前でデータ構造を作る機
会は少ないけどね。
937 :
デフォルトの名無しさん :01/12/21 21:50
class vec{ double x,y,z; } class color:public vec{ } クラスvecを継承しているクラスcolorで、 xを別の名前で使いたいのですができるでしょうか? よろしくおねがいします。
938 :
デフォルトの名無しさん :01/12/21 21:55
privateで継承すれば?
なんで別の名前に?
940 :
デフォルトの名無しさん :01/12/21 22:05
>>938 さん
書き間違えましたが、vecのメンバは全てpublicにしています。
>>939 さん
colorクラスでもvecクラスで定義しておいたメンバ関数を使いたいのです。
ただ、普通に継承したらcolor(色)のメンバ変数にアクセスする時に
r,g,bを使いたいのにx,y,zでアクセスすることになり不自然だからです。
941 :
デフォルトの名無しさん :01/12/21 22:07
考えてみたら、やっぱ無理そうですね。あきらめます。
942 :
デフォルトの名無しさん :01/12/21 22:15
class color:public vec{
double &r,&g,&b;
color() : r(x), g(y), b(z) {}
}
…コンパイル通るかどうか全く自信ない。
>>940 しかし、色空間てことなんだろうけど、それでも
vectorからcolorが派生する設計自体が不自然な気がする。
>>940 あ、読み違えてた… 逆だ。
そういう意味なら、class colorのなかで#define r x とかってやればええんでないの?
俺なら r() return x ; r(double value) x=value ; とかやるだろうけど。
944 :
デフォルトの名無しさん :01/12/21 22:20
話が変わって申し訳ないです。 VC6のWin32 Console Applicationでカーソルの位置を変えたり、出力文字のフォントを変えたりするにはどうしたら良いのですか? Cの参考書を読むと「cursesまたはncursesというヘッダファイルをincludeしろ」と書いてあるのですが、ヘッダファイルが見あたりません。 教えて下さい。
>>942 >派生する設計自体が不自然
おれもそう思う。
その設計はやめた方がいいと思う。 穴が2個あるからといって、 マンコと鼻穴を同じベースクラスで表現するようなもの。
まあ、どうしてもその通り設計したいなら union 共用体を使うという手も。
948 :
デフォルトの名無しさん :01/12/21 22:29
>944 VC++のサンプルにあるぞ。 名前はわすれた。 CDの中さがして
追加 curses使うやつじゃなくてね
>>944 その参考書はUNIX用だと思われるので、Windowsでは使えない部分があることを知りましょう。
毛唐か ゴルァァァァァァァ!
うっ! 超誤爆・・・・ スマン・・・・
953 :
デフォルトの名無しさん :01/12/21 22:48
ありがとうございました。 さがしてみます。
954 :
デフォルトの名無しさん :01/12/21 23:34
VisualStudio.NETで、 VC++.NETのプログラムを書きました。 でも、実行しようとすると、現在のユーザー権限では実行 できないと言われました。どうすればいいのですか?
VisualStudioをダウングレードする
プログラムのデバッグの権限が要るとか?
>>954 どっかレジストリいじればいいんじゃなかったっけ。すれ違いだからほかで探せ
C++って多重継承できるけどさ、 よく考えたら 同じ名前の関数をもってるクラスを複数継承したら どれを呼び出すことになるのよ? わけわからんぞ。
>>958 #include <iostream>
class Base1{
public:
void foo(){std::cout << "Base1";}
};
class Base2{
public:
void foo(){std::cout << "Base2";}
};
class Hoge : public Base1, public Base2{
public:
void bar(){foo();}
};
int main(){
Hoge hoge;
hoge.bar();
return 0;
}
//-------------------------------------
>cl d.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.
d.cpp(17) : error C2385: 'Hoge::foo' の派生があいまいです。
d.cpp(17) : warning C4385: 可能性 : 'foo' がベース 'Base1' of class 'Hoge' にあります。
d.cpp(17) : warning C4385: または : 'foo' がベース 'Base2' of class 'Hoge' にあります。
サンクス。
>>959 でも、それだと、同じ関数持ってるやつは複数継承できないってこと?
それじゃ多重継承って使いづらくない?
それともあいまいじゃない指定方法ってある?
>960 オーバーライドすればよい。 またはクラススコープ演算子を使う
962 :
デフォルトの名無しさん :01/12/23 10:34
void bar(){Base1::foo();} でいけるはず
usingでもよいよ
俺にはクリスマスも元旦も カンケーねえ。 ひたすら勉強だ。 みんなだってそうだろ?
>>965 まあ、そういうことだ。おれはいま、Effective STL、Exceptional C++、
マルチパラダイムデザイン、Modern C++ Design を並行して読んでる。
勉強っていうか、それが生きがいになっちゃた。 新スレ行こうか。
968 :
デフォルトの名無しさん :01/12/23 11:39
C++は、勉強するのが非常ーに楽しい言語だが、 仕事より勉強の方が長い場合もあって欝 と、暗いまま年末に突入します More Exceptional C++出たら正月休みに持っていけたのに。
のこり31レスをどうしてくれようか。
じつは、40才になったのを機に C++ をやり始めたのだけど、勉強しがいの ある言語だよね。仕事のためというより、勉強そのものが楽しいっていうか。 まあ、そのうち恐竜みたいになって滅びるのかも知れないけど。
>>970 同感。
一時期流行に流されてJavaの仕事もしたが、やっぱりC++の方がプログラム組んでて100倍楽しい。。
まもなくここは 乂1000取り合戦場乂 となります。 \∧_ヘ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ,,、,、,,, / \〇ノゝ∩ < 1000取り合戦、いくぞゴルァ!! ,,、,、,,, /三√ ゚Д゚) / \____________ ,,、,、,,, /三/| ゚U゚|\ ,,、,、,,, ,,、,、,,, ,,、,、,,, U (:::::::::::) ,,、,、,,, \オーーーーーーーッ!!/ //三/|三|\ ∧_∧∧_∧ ∧_∧∧_∧∧_∧∧_∧ ∪ ∪ ( ) ( ) ( ) ) ,,、,、,,, ,,、,、,,, ∧_∧∧_∧∧_∧ ∧_∧∧_∧∧_∧∧_∧ ,,、,、,,, ( ) ( ) ( ) ( )
999ゲト
1000です。。。
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。