1 :
v(^・^)v :
03/05/11 13:04 C++に関する質問はこちらへどうぞ。
ただし質問の前にFAQに一通り目を通してください。
また、テンプレートライブラリ(STL含む)に関する質問は
専用の別スレへどうぞ。
過去スレ、関連スレ、関連リンクなどはこちら
>>2-10
2 :
v(^・^)v :03/05/11 13:04
3 :
v(^・^)v :03/05/11 13:04
4 :
v(^・^)v :03/05/11 13:05
5 :
v(^・^)v :03/05/11 13:06
6 :
v(^・^)v :03/05/11 13:06
7 :
v(^・^)v :03/05/11 13:07
8 :
v(^・^)v :03/05/11 13:07
9 :
v(^・^)v :03/05/11 13:09
10 :
v(^・^)v :03/05/11 13:10
心擦れ鬱枯れ〜
>>前スレ995 ふむ。訂正します。 インスタンスをnew以外で作成するのを禁止しないと、あぶない。>delete this;
13 :
デフォルトの名無しさん :03/05/11 13:25
C++の機能を有効に使ってプログラムを書きたいんですけど、どこかに これこれこういうプログラムを作れというような問題を提供して、模範 解答みたいなソースもあるサイトないですか?
とりあえず猫でも読んどけ。 問題解くのはそれからだ。
STLつかうと一気に実行ファイルサイズが10倍に?!
>>18 privateコンストラクタ&コピーコンストラクタ+生成用staticメンバ関数
>>17 環境によるだろ。
俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力
ランタイムを使用するようにして使っているが、例えばstd::vectorを
使っても使わない時と比べ10Kほどしか増えない。
>>19 すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。
>20 それを言うならスタティックリンク
C言語にあったNULLというのは標準C++では規定されているので しょうか?小文字のnullっていうのも見たことあるような気がしますが。 しかし0を使うのがいいと何かの本に書いてあった気もします。
されてます。小文字のnullは他の言語です。
25 :
デフォルトの名無しさん :03/05/11 17:48
次スレは?
DLLのためのインポートライブラリは、静的にリンクされますな GW終わったのに香ばしくなってきたぞ
これって恒例行事なの? >17-
静的メンバ関数ってどういう時に使うもの?
CreateObject
いろいろあるけど例えばFactoryパターンとかやるとき。
Singletonのinstance()
BorlandC++BuilderとVisualC++ならどっち覚えるべきですか?
C++覚えれ。
静的メンバ関数のデメリットって何? どういう時に使ってはいけない? 一応動くけどこれはやばいだろ、非効率だろ ってのを教えて欲しい。
Borland C++もVisual C++も製品名。言語ではない。
開発環境より言語を先に覚えろと
だってC++とVCは違うんだ! ってよく怒り出す人いるじゃん。
>>39 怒るのはどうかと思うが、とりあえず違うことに間違いない。
C++覚えた上でVCの標準に準拠してない所を覚えた方が混乱しにくいと思う
Borlandでやってみようかな
>>19 テンプレートライブラリを
ダイナミックリンクできるのか?
vector <int> とかよく使われるものは
DLL から提供できるようにしてたり?
というか、10K も増えてたら
ダイナミックリンクされてないと思うが。
シンボル情報を見てからものをいうべきだろ
たとえていうなら 標準c++ > 標準語 VC > 関西弁 同じ日本語じゃないか!!
生粋の関西人であるVCコンパイラは標準語を理解できません
そのくせお金にはうるさいです
49 :
デフォルトの名無しさん :03/05/12 22:21
iostreamの使い方について詳しく解説しているサイトや書籍をおしえてください 全然触れていなかったり、なぜかCの入出力関数を使ってお茶を濁していたり するのが多くて
やさしいSTL 高橋麻奈・著
iostreamってSTLに含まれるものじゃなかったんだ(恥
>>50 ありがとうございます
っていうか一番目によさげなサイトが。
何を調べていたんだ俺
55 :
デフォルトの名無しさん :03/05/13 11:44
vector<short> stest(200); というのをローカル変数で定義しましたが、値は初期化されてますでしょうか?
shortのデフォルトで初期化済み
57 :
デフォルトの名無しさん :03/05/13 11:59
thanx!
>>56 もしかして、リサイズでは元の値は保持されて追加部分は初期化ですか?
だったらすごい。
クラスの宣言で メンバ変数は最初と最後のどっちに書くのが一般的?
>>57 リサイズでは元の値は保持されて追加部分は初期化です。
ポインタやイテレータは死ぬけど。
>>58 アクセス指定で順番が変わるのが一般的だと思う。
public→protected→privateの順で書けば、インターフェースが見やすい。
で、一般的にメンバ変数は全部private。
なので、最後に書くのが一般的と言えるかもしれない。
>>59 >ポインタやイテレータは死ぬけど。
必ずしも死んでしまうわけではないし、判別も可能だと思うが
>必ずしも死んでしまうわけではないし そういう問題でないでつ。 >判別も可能だと思うが 了解です。 自分的にはもう一回ポインタ取り直すだけで十分かも。
>public→protected→privateの順で書けば、 最初こうしてたけどメンバを直接参照する inline メソッドが 書きにくいんだよな・・・。
>>63 なんで?
まあ宣言が下にあるのに使えるってのは奇妙には感じるか。
>>63 class C{
public:
inline void m();
};
inline void m(){
// ...
}
これでいいやん
>>65 class C{
public:
inline void m() { p_ = 1; }
private:
int p_;
};
これでいいやん
67 :
デフォルトの名無しさん :03/05/13 20:27
クラスを作るときの基準を教えてくれ。 昔は、データと機能をあわせたものとか言ってたけど、 Javaなんかじゃ機能(メソッド)だけのもあるよね。 C++はどうなん?
>>67 それは言語の問題じゃない
オブジェクト指向を勉強したら?
くだらん質問にこたえていただきありがとうございますた。 そっか、publicから書くのが普通だったのか・・・。
俺は変数は一番上に固めてる。
俺はクラス定義内でメンバ関数の定義はしない。
75 :
デフォルトの名無しさん :03/05/14 00:47
俺が昔の職場で策定したソース管理規定の場合(ファイル名は仮称) 原則として、システム全体で共通なインクルード、#defineやtypedefなどは ヘッダファイル sys_common.h に記述。(下層モジュール毎にも設ける) 機能ごとのクラス定義はクラス毎にヘッダファイル my_class.h に記述、 メンバ関数はヘッダファイルに対応するソースファイル my_class.cpp に記述。 これで綺麗に整理できるし、インクリメンタル・コンパイルにも対応できる。
関数オブジェクトとは違うの?
>>73 C++ではメンバ関数のみのクラスはあまり無い。
それならただの関数で十分。 ネームスペースで分けることもできるし。
>>73 メンバ関数のみのクラスは主にインターフェイスとして使うときとか。
メンバ関数を純粋仮想にして
>>78 の言う用途ならstaticなメンバ関数を使うとか
>>78 >>79 マジレスサンキュー。
しかし、そこなんだよね。
俺はC++屋だから、「うーん。これはグローバル関数かな」とか考える。
そのように教育されたから。
ところが、クラスしかないJava屋さんは、そういう発想がない。
とにかく、なんでもクラスにしてるように見える。
そこで、気になるのが、
>>69 の「それは言語の問題じゃない 」みたいな反応なんだよ。
最近の風潮としては、オブジェクト指向が基本だよな。
とすると、Java屋のやってることと俺のやってることがなんで違うんだろう?
もしかして、C++の常識も変わったの?みたいな。
ああ、すまん。言ってて俺もわからなくなったわ。
>>81 Java厨ってC++厨を装いたがるよな。
ナンカコンプレックスあるの?
>>81 実装じゃなく概念を理解しろってことだろ
言語が違うんだから実現方法が違うのは当たり前
関係あるのかないのかわかんないですけど、 よく「オブジェクトは状態を持つ」って言うじゃないですか。 それって、コンストラクタで値を設定するだけで、メンバ関数は ぜんぶconstってクラスはおかしいってことでしょうか。 データを変更できないので、それは「状態」ではないと。 確かに、そういうクラスのメンバ関数は、グローバル関数でも 実現できそうだけど、クラスの組み合わせで考えた方が ずっと楽ですが。
> データを変更できないので、それは「状態」ではないと。 なんでやねん。
人間の性という状態はconst修飾子がついてる。 コンストラクタで設定された後は変えることは出来ない。
無理やりキャストすれば可能だけどね
>>75 >>77 も言ってるが、すべてのファイルがsys_common.hに依存するのは(・A・)イクナイ
>>79 関係ないけど、たまにメンバ変数をそのクラスに入れればいいのに
それを他所のクラスにおいて、staticメンバ関数(パラメータにその変数を使う)だけの
クラスを作るヤシがいて困るw
配列の要素数を得るマクロとか、 デバッグ用マクロ/関数とか、 そういう基本的なのは sys_common.h みたいなのになるのも 仕方が無い気もするが。
91 :
デフォルトの名無しさん :03/05/14 16:02
>>90 はい、スコープが全体に及ぶデバッグ用定義やコンパイルオプション類の
#ifdefなど一元管理上どうしても必要です。
CからC++になって変わった事といえば、設計の仕方や考え方が変わった。
従来は、構造化言語世代主流の「データ・フロー」と「処理手続」のふたつが
軸だった気がする。
オブジェクト指向になってからは、クラスという「データ」と「処理手続」をカプ
セル化したオブジェクトが中心になり、処理のフローもそのオブジェクトの
時系列的な状態遷移で捉える様になった。と思う。
92 :
デフォルトの名無しさん :03/05/14 17:09
MinGw2.0.0でコンパイルするにはなんのexeを使えばいいのですか?
>>90 >配列の要素数を得るマクロとか、
そういうのは使うところでだけincludeすれば。
>>91 >はい、スコープが全体に及ぶデバッグ用定義やコンパイルオプション類の
>#ifdefなど一元管理上どうしても必要です。
コンパイルオプションはコンパイルオプションで処理すればいいし、
デバッグや単体テストは別ビルドにすればいいと思うのだがどうか。
94 :
デフォルトの名無しさん :03/05/14 17:36
>>93 プロジェクトの管理をする立場になってみると考えが少し変わる。
コマンドラインを使用していると、オペミスは証拠が残らないので、
コンパイルオプションのミスに誰も気づかない事があった。
以降、ソース側でオプションスイッチの記述を明確にしていたよ。
俺は現場から離れてン年経つので少し古いやり方かな。
makeでいいじゃん
>>95 >94は「少し古いやり方かな」って書いてるじゃん。
>94が現場を離れたのはmakeが普及するよりも以前なんじゃないの?
# いつだ? 70年代か?
97 :
デフォルトの名無しさん :03/05/14 18:25
C++スレなんだから70年代の話は無しでw
>>96 当時の現場ではコンパイルミス、未コンパイル、リンクミスが頻発していた。
俺が初めてmakeを導入。管理者に使い方を伝授したら神扱いされたw
P.S.
内緒だがその現場は在京大手電機メーカの某事業所。
西の松下、東の●●のライバル方ね。
>>99 make使った上で
>コマンドラインを使用していると、オペミスは証拠が残らないので、
>コンパイルオプションのミスに誰も気づかない事があった。
とは相当な神だなw
>>100 だってMS-DOSのバッチファイルにIF文やラベルを使って条件分岐
の制御が書けるだけでヒーロー、UNIXのコマンドが打てるだけでも
ヒーローだったもんなw。
レベル的に「パーミッションって何ですか?」だぜ?!
タイムマシンでそんな時代に行ってみたいな。さぞかし笑いが とまらないのだろうな。
>>94 は以後無視ということで。
そろそろC++の話に戻ろう。
>>80 どうでもいい。偉い人に従っとけ。
迷ったら、
do {
...
} while(true);
をドゾー
for(; ;) // うえーん! もう無限ループ疲れたよー! { ... }
それで思い出したが、やねうらおのクラス設計ってどうよ?
読んだ事無い。
ゲームにいらなそうな程大仰だなぁ。便利かも知れないけど
111 :
デフォルトの名無しさん :03/05/14 23:50
プログラマーを馬鹿扱いする会社は、 馬鹿なプログラマーしか残らないんだって。 なるほどって思ったよ。
普通の会社はプログラムなんて外注か派遣だからプログラマ自体いないよ。
113 :
デフォルトの名無しさん :03/05/14 23:57
事件は現場で起こっているってことを知らない会社は、いずれつぶれる。
114 :
デフォルトの名無しさん :03/05/14 23:59
結局、受けるところがいなくなれば、自分のところでやるっきゃないと。 そういう器を持っているかいないかの違いはおおきいな。確かに。
社員がこんな会社すぐつぶれると言ってる会社は以外につぶれなかったり。 言ってる奴はリストラになったり。
116 :
デフォルトの名無しさん :03/05/15 00:01
害虫か派遣でも、そこで入れ替わりが激しければ、 技術の蓄積は望めないわな。 人が変われば、また一から教えるぞと。ああ、疲れる・・・
117 :
デフォルトの名無しさん :03/05/15 00:03
そろそろ10階建てのビルくらい建っててもいいかな、 って覗きにいくと、いまだに平屋のプレハブ賃貸だったりすることも。
118 :
デフォルトの名無しさん :03/05/15 00:04
>>115 つぶれる、と言っている社員と優秀な人間は、
必ずしもイコールでは無いからな。
おまえらageてまで雑談すんなよ
いや、ここは、ほら、言語エリートの巣窟だからさ。
121 :
デフォルトの名無しさん :03/05/15 01:02
C++に関してですが、 クラスのオブジェクトへの参照(リファレンスではないです)を返す関数の戻り値の型は、 リファレンスあるいはポインタのどちらがいいんでしょうか? 各々にメリット・デメリットがあれば教えてください。
つか、マ板でやれや
auto_ptrがいいと思います
boost::shared_ptrの方が
>>124 ,
>>125 藻前ら「オブジェクトへの参照(リファレンスではない」の意味がわかったのですか?
俺にはさっぱり・・・
分かっていないからでたらめな回答をしたの
(リファレンスではないです)を無視すればOK
注釈を無視しちゃ駄目だろう
return this と return *this とどっちがいいのかってこと?
>>126 C++ の機能としての「参照(& を使う奴)」ではなく、
「ポインタ(* を使う奴)」と「参照(& を使う奴)」をまとめて表現する
「参照(プログラミング用語一般における)」という意味でしょ。
>>121 動的に確保したのならスマートポインタで返すのがいい。
そうでなければ、それなりに。
参照変数は再初期化できない欠点があるけど、
変な値で初期化する事が難しいという利点がある。
ポインタ変数は再初期化(C++ の用語としての初期化じゃない)できるという利点があるけど、
変な値が比較的入りやすいという欠点がある。
あとはその兼ね合いで...。
>オブジェクトへの参照(リファレンスではないです)
リファレンスと書くとリファレンスならリファレンスで返せよと言われてしまうので、
自己矛盾的な書き方をしたと予想して
>>125 を書きましたが何か
121は釣りですな
あと、オーバーロードした演算子を使う時には 参照の方が使いやすいね。
>>131 の様に思いますた。万が一戻り値無視してもリークしないし
そのためにあるのかなーとか思っている。
137 :
デフォルトの名無しさん :03/05/15 01:46
先生!!質問があります! void kakezan(int a,int b) { } main() { int a = 5; int b = 1; a =kakezan(a); } kakezan(a,b) でa=125 b=5にしたいのですが void kakezan(int a,int b) { } の部分を何て書けばいいのですか??
どっちがいいのかと言われたら、どっちがいいと一概に言えないと答えるしかない ケースバイケース
>>137 a =kakezan(a); をa =kakezan(a,b);とおいて・・・
不可能だと思う。
bを書き換えることができないから。
つーかvoidの関数の戻り値を受けようとするなよ
スマソ間違えてました! a = kakezan(a,b)です。 これでもだめですか??
int kakezan(int a,int b) { return a*b*5; }
>>142 関数の形があれじゃ無理。
多分エラーか警告になる(voidを受けるようなコード書いたことないから分からない)。
int kakezan(int a,int &b) { b=5; return 125; }
int kakezan(int &a,int &b) { b=5; return a=125; }
むしろC相談室?ここでもいいか
その前に宣言なしの関数呼び出しでエラーか
やはり関数がvoidではだめってことですか?? すいませんど素人でペコリ(o_ _)o))
寝よ寝よ
151 :
デフォルトの名無しさん :03/05/15 03:06
>>148 K&Rによれば宣言なしは暗黙でint型宣言されたものと解釈します。
なぜこのスレでK&R…
川合堂ライセンス(´_ゝ`)
>>151 釣りか?ここはC++スレだぞ。
釣りなら分かっていると思うが、C++では宣言なしに関数を呼び出すことはできない。
155 :
デフォルトの名無しさん :03/05/15 13:36
void func(int a,...){ int* pa=&a; } void main(void){ func(0,1,2,3,4,5); } と、したときにfuncの引数の数を数える方法はないですか? int* pa=&a;で先頭が分かるんですが、最後を知る方法を考えつけません。
終端子を決めるか、引数の数を最初に教えるか。
マクロの中身はどうやってやってるんですか?
158 :
ホントはC使い :03/05/15 15:10
>>155 関数コール時の引数の受渡しメカニズムを知ってる?
>>156 の言う通り、スタックフレームを介した引数の渡し方(スタックへの
引数の積まれ方)をヒントにして、func関数へ終端を示す識別も一緒に渡す。
また引数に任意の型を順不同で混在して渡したい場合、型情報と交互に
ポインタ型で渡せば、func関数側では型サイズに関係なく引数を取り出せる。
一緒に渡された型情報を元にswitchで振り分けてキャストを掛ければ良い。
ていうかva_argマクロ使えばいいじゃん
void func(int a){ va_list ap; va_start(ap, a); func(ap, 1, a); va_end(ap); } void func(int a,int b){ va_list ap; va_start(ap, a); func(ap, 2, a); va_end(ap); } void func(int a,int b,int c){ va_list ap; va_start(ap, a); func(ap, 3, a); va_end(ap); } void func(int a,int b,int c,int d){ va_list ap; va_start(ap, a); func(ap, 4, a); va_end(ap); } void func(int a,int b,int c,int d,int e){ va_list ap; va_start(ap, a); func(ap, 5, a); va_end(ap); } void func(va_list ap, int num_of_args, int a){ int* pa=&a; }
または enum {XXX=-1 /*ありえない数値*/}; void func(int a,int b=XXX,int c=XXX,int d=XXX,int e=XXX,int f=XXX) { } どっちにしろ現実的じゃない。 そもそもどういう用途で可変長引数を渡したいのか白状しなさい。 void main(void) { int tbl[] = {1,2,3,4,5,6}; std::vector<int> v(tbl, tbl + sizeof(tbl) / sizeof(tbl[0])); func(v); } void func(std::vector<int> &v) { int n = v.size(); ..... } でいけないわけでもあるのか?
>>160 va_argが無効になるまでループさせてカウントすればいいじゃん
なぜか構造体メンバの.での参照が出来ないんですけど、VC++じゃ直接参照はダメなんですか? わざわざポインタにして->しないとダメなんですか?
167 :
デフォルトの名無しさん :03/05/15 20:40
typedef struct st_Leap{ Face face; //表情 int SYOKU_YOKU ; //食欲 int RENAI; //恋愛度 int KOUFUN; //興奮度 }Leap; ↑グローバル ↓描画関数内 if(Leap.face == NORMAL){ if(rand()%100 !=5) //まばたき TextureData = (GLuint *) TexLayer->ipic; //通常 else TextureData = (GLuint *) TexLayer->next->next->next->ipic; //つむり目 } ギャルゲの心理パラメータなんだけど・・
>Leap.face == NORMAL Face クラスにはちゃんと == 演算子は定義されているんだろうか。
169 :
デフォルトの名無しさん :03/05/15 20:53
Face faceは列挙型です。
170 :
デフォルトの名無しさん :03/05/15 20:54
クラスを作る前は普通に==で出来たんですよー エラー自体は.に出ます。
typedef てことは Leap は型なんじゃない?変数じゃなくて。
え、構造体の宣言は普通はtypedefでやらないですか?
そういうことではなくて typedef struct st_Leap{...} Leap; Leap leap; とした上で if(leap.face == NORMAL) ではないのかな。
Leap a; a.face == NORMAL これなら通りそう。Leap.faceでは何を指すのかわからない…。
struct st_Leap{ Face face; //表情 int SYOKU_YOKU ; //食欲 int IN_YOKU ; //飲欲 int SUIMIN_YOKU; //睡眠欲 int UNDOU_YOKU; //運動欲 int KYUUKEI_YOKU; //休憩欲 int HAKAI_YOKU; //破壊欲 int BUTSU_YOKU; //物欲 int HOUSHI_YOKU; //奉仕欲 int WA_YOKU; //話欲 int SAWARI_YOKU; //触欲 int HP; //体力 int KIGEN; //機嫌 int RENAI; //恋愛度 int KOUFUN; //興奮度 }; st_Leap Leap; if(Leap.face == 〜〜 なら通るんですけど、タグを使って出来ない。。
176 :
ホントはC使い :03/05/15 21:10
<用法> typedef A B; // AからB型を定義する <例1> typedef unsigned int u_int; // unsigned int から u_int 型を定義 u_int a; // unsigned int a; と同じです <例2> typedef struct XXX { // struct XXX から YYY 型を定義 int n; char b[20]; } YYY; YYY yyy; // struct XXX yyy; と同じです yyy.n = 0; strcpy( yyy.b, "(・∀・)イイ!" );
typedef struct TAG { ... } typename; は 構造体名を TAG に別名 typename をつけるだけだったと思うんだけど…。 st_Leap Leap; みたいなことを struct 宣言のところでやるなら struct st_Leap { ... } Leap; で良かったと思う。
>>176 >YYY yyy; // struct XXX yyy; と同じです
ダメでした。
D:\プログラム\Leap\Leap\main.cpp(575) : error C2143: 構文エラー : ')' が '.' の前に必要です。
if(Leap.face == NORMAL){ ←575行目
179 :
ホントはC使い :03/05/15 21:22
>>178 typedef struct st_Leap {
・・・(中略)・・・
} LEAP; // ←LEAP型を定義
LEAP Leap; // ←LEAP型のLeap変数を宣言!
・・・(中略)・・・
if ( Leap.face == NORMAL ) {
・・・(中略)・・・
}
これでどうだ!
>>179 はい、全く同じコードを書いて、それで178のエラーが出たんです。。うぅ。
他の構文には全く間違いはありません。だって175のやり方では動いたんですから。
でも179のやり方ではどうしても動かないんです。。
>>179 C++ならtypedefの必要はないぜ。
同じ人じゃん・・・寝不足か。うつだねよう。
うぅぅ。。万事休す。
先ず、今までの知識から頭を解放する事。 それから、以下のことを覚える事。 struct Point { int x; int y; }; は、Point という構造体型を定義するものである。 ここで定義するのは「型」であって、「変数」ではない。 つまり、この状態ではまだ変数は作られていないわけだ。 そして、この型を持った変数は次のようにして作られる。 struct Point pt; /* C の場合 */ Point pt; /* C++ の場合 */ この時、Point は int と同じように「型」であり、 pt が新しく作られた「変数」である。 これをふまえると、 Point.x = 0; というのはおかしいことが分かる。 なぜなら、Point は型であって変数ではないからである。 pt.x = 0; ならいい。pt は Point 型の構造体変数だからである。
それは知ってますよぅ。。
この状態では C と C++ とで構造体変数の定義の仕方が異なる。 そこで、次のような技巧が使われる事がある。 typedef struct ___Point { int x; int y; } Point; typedef というのは、ある型の「別名」を作るものである。 つまり、そこで作られるのもやはり「型」である。 typedef は普通の変数を定義する時と同じ式のあたまに typedef と書く事で使う。 しかし、できてくるのは「変数」ではなく「型」である。
上の例では、 struct ___Point { int x; int y; } が元の「型」に相当し、Point が「別名」に相当する。 このようにすれば、C でも C++ でも この構造体「型」を struct というのを付けずに Point だけで参照する事ができるようになる。 従って、 Point pt; と書く事ができる。 この時、Point は「型」であり、pt は「変数」である。 Point.x = 0; がおかしいことと、 pt.x = 0; が正しい事はもう言うまでもない事だろう。
C++ のコンパイラでしか扱わないのであれば、 typedef の技巧を使う必要は無い。 あれは C でも struct を付けるのが面倒な場合に さぼれるようにするための技巧。
191 :
ホントはC使い :03/05/15 22:16
>>189 上の
>>187 の構造体定義と型宣言をした後に、
Point pt;
とすれば、Point型のpt変数が宣言される。以降好きなようにメンバへアクセス
すれば良い。
pt.x = 0;
pt.y = 10;
の様に代入も可能だし、
Point pt[] = { { 0, 0 }, { 10, 20 }, { 30, 100 } };
の様に配列の初期化付き宣言も可能である。
単純にどっか ')' 付け忘れてんじゃねーの?
>>190 > あれは C でも struct を付けるのが面倒な場合に
> さぼれるようにするための技巧。
そう言ったらおもいっきり馬鹿にされた。
他にどう違うのかさっぱりわからん・・・・
Faceの定義を晒して
まぁ、C でも C++ でも同じコードが書けるというのがあるが、 ゲーム製作においてそんなに気にする必要があるのか? 少なくとも C++ のみを使ってる人は typedef なんか使わない。 大体バリバリにクラスとかテンプレートとか使うから そもそも C でもコンパイルできることなんか考えない。
といっても間違ってたらコンパイルが通らんか・・・
enum Face {NORMAL,NEMUI,TSUMURI,MABATAKI,KANASHIMI,YOROKOBI }; こんな感じです。
>>195 typedef boost::shared_ptr<Character> CharacterPtr;
typedef std::vector<CharacterPtr> CharacterArray;
とかやらないの?
199 :
ホントはC使い :03/05/15 22:32
>>193 一度、標準ライブラリのヘッダファイル stdio.h の中身を読んでみましょう。
初期に学ぶFILE 構造体も typedef されてるから、FILE *fp; と構造体である
ことを知らずして宣言、使用できる。これがもし、typedef されていなかったら
C言語習得を挫折するものが増えてしまう。
>>193 ,197
C なら Face として使うには
typedef enum ___Face {
NORMAL,
NEMUI,
TSUMURI,
MABATAKI,
KANASHIMI,
YOROKOBI,
} Face;
とするわけだが、
なぜ enum では typedef しなくて良く、
struct では typedef しないといけないのかな?
両方しなくていいんだよ。
C++ ならね。
(ここは C++ 相談室ということも忘れずにね)
>>198 それとこれとは別の話。
typedef を「struct, union, enum をさぼるために使う」のは
C++ ではやらない。
しかし、「別のところ」では typedef はよく使う。
>>199 それは分かっている。俺もそういう使い方しているから。
その構造体に関する関数を使う人が、メンバーにアクセスするかしないかで決めている。
でも、なんでもかんでもtypedefする人が結構いないか?
div_tって構造体であることを知らなければならないはず(メンバーにアクセスするはずだから)なのにtypedefしているよな(ぼそっ)
>>200 そうなんですけど、通らない理由が分からないと、気になって先に進めないです。
普通のg++とかだと通るのになぁ。。
もう一度使ってるところコピペしてみ。
typedef struct st_Leap{ Face face; //表情 int SYOKU_YOKU ; //食欲 int RENAI; //恋愛度 int KOUFUN; //興奮度 }Leap; Leap leap; ↑グローバル ↓描画関数内 if(leap.face == NORMAL){ if(rand()%100 !=5) //まばたき TextureData = (GLuint *) TexLayer->ipic; //通常 else TextureData = (GLuint *) TexLayer->next->next->next->ipic; //つむり目 }
VC5で問題ないんだが・・・ if(leap.face == NORMAL){ のちょっと前あたりに何かあるんじゃ?
関係ないけど、とりあえずLeapのtypedefははずしたら? structだけtypedefしてenumはtypedefしないのは気持ち悪い。
で、出てくるエラーは?
D:\プログラム\Leap\Leap\main.cpp(575) : error C2143: 構文エラー : ')' が '.' の前に必要です。 if(Leap.face == NORMAL){ ←575行目
face以外にはアクセスできるの
Leap.faceなのかleap.faceなのかはっきりしる。
215 :
ホントはC使い :03/05/15 23:00
Cleap 珈琲が旨い・・・
漏れはブラックだが。
217 :
ホントはC使い :03/05/15 23:03
・・・で、Leap.face の話だが、その行以前の何処かで 括弧の対応がズレていないか?
>>218 確かg++では通るとか言っていたんだよなぁ(ログ見る気ない)
あれ?動いた。なんでだろ〜なんでだろ〜こりゃまた失礼♪
うんこ
( ´Д`) Д`)Д`)Д`)Д`)Д`)< え〜〜、やっぱり
ヒトサワガセナ!
( ・∀・) | | ガッ
と ) | |
Y /ノ 人
/ ) < >__Λ∩
_/し' //. V`Д´)/
(_フ彡 / ←
>>370
370の勝ちだな。
なんだこりゃ
229 :
ホントはC使い :03/05/15 23:07
☆ チン マチクタビレタ〜
マチクタビレタ〜
☆ チン 〃 ∧_∧ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
ヽ ___\(\・∀・)<
>>370 の反省会はまだ〜?
\_/⊂ ⊂_)_ \____________
/ ̄ ̄ ̄ ̄ ̄ ̄ ̄/|
|  ̄  ̄ ̄ ̄ ̄ ̄ ̄:| |
| 淡路たまねぎ .|/
Leapをleapにするのに60レスかかりますた。
うんことか言ってないで結局何だったのかおせーろ
言ってやろう。「このドアホが」
タグ名とtypedef名と構造体名のと変数名の区別はつけような
タクサンツレタ(・∀・)
この騒ぎなら言える。「ぬるぽ」と。
238 :
ホントはC使い :03/05/15 23:10
>>225 日本人なので、CleapとCreapの違いが・・・
239 :
ホントはC使い :03/05/15 23:12
ま、終わって良かった・・・。さぁて寝るぞぉ!
このスレのネタ系としてはオチが久し振りに面白かった
370の兄です。
このたびは妹がご迷惑をおかけしました。
そもそも
>>205 で
>もう一度使ってるところコピペしてみ。
といわれて貼った
>>206 がどうして問題ない無いコードだったのか
悔やまれてなりません。
242 :
bloom :03/05/15 23:13
C 言語スレの 370 を見てみてるともっと盛り上がれるかも。
さぁ、気を取り直して次の質問どうぞ〜
C++のクラスをアセンブラで作るにはどうやりますか? 作り方の書いてあるホームページあったら教えてください 直接ここで教えてもいいですよ ちなみにレスはしません
370はネタ師の永久欠番
>>248 意味が分からないです
もっと詳しく教えてください
C++の質問じゃない。
最近未来からの書き込みが多いのは何故?
勉強はじめて 約5時間ですが・・・ #include<iostream.h> int main() { int i; cout<<"表示する回数を指定してください"<<endl; cin>>i; if(i==0){ cout<<"0回はできません"<<endl; } else cout<<i<<"回表示を行います。"<<endl; do{ cout<<"猫ふんじゃった "<<i<<"回目"<<endl; --i; }while(i); return 0; } まだ 自分で考えてこれぐらいしかできません・・・ こんな調子でほんとにいいんでしょうか?・・・ (;´Д`)誰か漏れに光を・・・あとできれば、もっと綺麗に短く書くとどうなるか教えてください。 おながいします・・・・゚・(つД`)・゚・
>>254 いいんじゃないすか?
強いて言えば
#include <iostream>
using namespace std;
とか
いいんでない? ifブロックに{}つかるなら、else以下にもつけとうたほうが 統一されててよいかな。
>>255 、256さん
アドバイスありがとん・・・
using namespace std; がまだなにか解りませんが、
ググってきまつ!(`・ω・´)シャキーン
258 :
デフォルトの名無しさん :03/05/16 02:26
int foo(){ return 0; } void function() { return (void)foo(); } これはC++的にOKですか? gcc,VC++.NETではコンパイルが通るのを確認済み。(VC6は通らないはず)
(´・ω・`)ショボーン・・・ 漏れの書いたやつ 8行目にreturn 0;入れてないから だめでつたね・・・今気がつきました。 でも、がんがります!(`・ω・´)連続カキコスマソ・・・
261 :
デフォルトの名無しさん :03/05/16 08:56
>>258 最近のvoidは「型なし」→「なんでも型」の解釈だっけ?
voidにキャストするとキャストされたものが無効になるんじゃないの?
どんな型でも指せるvoid *と勘違いしているんじゃないの。
265 :
デフォルトの名無しさん :03/05/16 11:03
C言語の質問かもしれませんが、お願いします。 テンプレートで、使うときにポインタを定義して、実態用のメモリを確保しようと思います。 sizeofすると、ポインタ自体の大きさしか分からないんですが、 ポインタから実態の1個分の大きさって取ったりできますか?
double *dp sizeof(*dp)==sizeof(double)
thanx!
>>266 それを使って移動平均ライブラリをC++で作ってみようかとおもいます。
どっかに落ちてたらダウソしたいな。
268 :
デフォルトの名無しさん :03/05/16 11:38
DLLの動的読み込みで、DLL側にクラスの定義をしておいて、そのクラスを 読み込み側で使おうと思うのですが、 ---DLL--- class CA{}; CA* create(){return new CA;} ---main-- template<typename T>void mainside_creater(T* pt){ } void main(void){ mainside_creater(create()); } とするとTにはクラスの型情報が入るんでしょうか?
int a; typeof(a) b;⇒int b; のようになるtypeofって作れるんですかね?? どうやっても思いつかないんですが。
270 :
デフォルトの名無しさん :03/05/16 12:32
便利なのでvoid型のポインタを返す関数を 自作して、受け取り側でキャストしてるんですが、 こういう使い方って、なんか問題あったりします?
>>270 ANSI Cよりも昔のC言語のやりかただなそれ。
せっかくの型付けを捨てるのはもったいない。
正直、C++でもprintf系の書式指定が手放せない。 まあfstreamなんかだと仕方なくマニピュレータ使ってるけど。 みんなはどうしてる? 聞かせて、エロい人!!
boost::any
マニピュレータで浮動小数点の桁指定とかスペースのパディングとか 効率よくきっちり書く方法がいまいちわからんので sprintf
boost::format
>>269 .演算子でtypedefメンバにアクセスできれば良いんだけどねえ。
>>169 templateとかつかうと
template< class T > void foo( T v ) {
T b;
} とか、できるでしょ?
そんでもって、
int a;
foo( a );
とかってやったらええやん。
>>278 fooを呼び出した関数でTを取得したいんだろ。
template <typename T> struct hage{typedef T type;};
template <typename T> hage<T> foo(T){return hage<T>();}
...
int a;
foo(a).type b;//エラー
そいや、最新のclはtypeofサポートしてるのん?
インスタンスにはメンバ関数の本体も丸々含まれるの? それとも本体はあくまでクラス定義のところにのみあるのであって、 インスタンスが持ってるのは単に関数ポインタみたいなものなのかな。 キシュツっぽいのでsageときますが。
含まれない。 インスタンスのthisポインタが関数に暗黙的に渡される int Hoge::foo(int a) { } は実は int foo(Hoge* this,int a) { } 内部では↑に近いことになってる でいいんだっけ?
283 :
デフォルトの名無しさん :03/05/17 01:39
typedef boost::shared_ptr<Hoge> HogePtr; typedef std::vector<MoejpResPtr> HogePtrArray; class HogeManager { private: HogePtrArray hoges_; public: void Foo() { //処理色々 } ・ ・ <A> void Add(HogePtr hoge) { hoges_.push_back(hoge); } <B> void Add(const HogePtr &hoge) { hoges_.push_back(hoge); } }; 上記のような状況の時hoges_に要素を追加するメソッドを作りたい時 <A>と<B>どちらがより良い方法ですか? AでもBでも参照カウントが壊れる事はないですか?
すいません typedef std::vector<MoejpResPtr> HogePtrArray; ↓ typedef std::vector<HogePtr> HogePtrArray; に置き換えて下さい…
>>283 <B>のほうが効率がいい。どっちでも参照カウンタは壊れない。
287 :
デフォルトの名無しさん :03/05/17 03:25
class CHoge { protected: static std::set<CHoge*> s_hoges; public: CHoge(); ~CHoge(); }; -------------- static std::set<CHoge*> CHoge::s_hoges; CHoge::CHoge() { s_hoges.insert(this); } CHoge::~CHoge() { s_hoges.erase(this); } こういう風にして自分のインスタンスの一覧を管理してるプログラムがあるんですが、 CHogeのオブジェクトがグローバル変数だった場合、プログラム終了時に、CHogeの インスタンスよりもs_hogesの方が先に消滅してしまうらしく、CHogeのデストラクタ でアクセスエラーが発生します。どうすりゃええのですか
>>254 endl の正体を調べてみ。けっこう勉強になると思うよ。
// 混乱するかもしらんが
>>287 Modern C++ Design 読んでフェニックスシングルトンだ。
ただしその前に一時間ほど
> CHogeのオブジェクトがグローバル変数
にならないように設計を考えれ。
290 :
デフォルトの名無しさん :03/05/17 10:13
>>289 Modern C++ Designですか、読んで見ます
>> CHogeのオブジェクトがグローバル変数
>にならないように設計を考えれ。
グローバル変数にしなくても、例えばアプリケーションクラスg_Appのメンバにしても同じことが起こってしまうのです
291 :
デフォルトの名無しさん :03/05/17 10:15
最近CからC++に移行を初めて疑問があります。 「クラスの継承をいつ使うか」です。 制限がきつい気がします。で、聞きたいことは 「みなさんは、どんなところで継承を使ってますか?」です。 継承の有効利用法を教えてください。 ちなみに僕は使ってません!!
実装の継承とインターフェースの継承の区別が付いていれば、 使っても使わなくてもいいんじゃないかしら。
Is-Aの関係でなくても、Has-Aの関係にできることも多いから悩みどころだな
>>291 制限って何?
漏れは
オブジェクト間にis-a関係があるときにつかってるが。
Is-A = Has-a+インターフェースの継承+delegate だからなあ。 判断において最も重要なのは、インターフェースの継承が必然かどうか、だろうね。 そうでない場合は、たいがい不要。 どんな言語でもそうだけど、実際のコードでは 言語仕様上仕方なく行うトリックのための継承(&その他)と、 オブジェクト指向的な意味での継承とが 入り混じってるから、初心者は戸惑うだろうねえ。
でもC++でdelegateを手軽にやろうと思ったら継承するしかないんだよぉぉぉおお
delegateって関数ポインタじゃねーの?
299 :
デフォルトの名無しさん :03/05/17 12:34
C++デラゲーツならマクロやテンプレートが使えそう。
>>298 正確にはインスタンス+関数ポインタ。
あと、マルチキャストの機能も含まれている。
boost::functionにthisポインタをbindしろって事?
そういう事やりたいんだったらもうC++使わない方がいいと思う
namespace XXX{ int a; ..... } こんな感じで変数の定義ってnamespaceの 中にいれたりしますか? とすると、このnamespaceをヘッダファイルにして あちこちのファイルでインクルードするとまずいんですよね? ど〜すんでしょ。関数なら宣言と定義わけたりするんですよね。 あとconstなんかも大丈夫なんですよね。ひょっとしてextern?
何言うとるんじゃジジイ
308 :
デフォルトの名無しさん :03/05/17 20:20
CString型インスタンス内にある文字列のポインタを取得するには GetBuffer()を使う以外の方法は無いんでしょうか? あとMFCのリファレンスには、GetBuffer(void)の事が書いてないんですが これってあまり使うべきでない(推奨されない)という事なんでしょうか? 教えてください。
309 :
デフォルトの名無しさん :03/05/17 20:25
訂正 CString型インスタンス内にある文字列の先頭アドレスを取得するには GetBuffer()を使う以外の方法は無いんでしょうか? あとMFCのリファレンスには、GetBuffer(void)の事が書いてないんですが これってあまり使うべきでない(推奨されない)という事なんでしょうか? 教えてください。
CString s; const char *p=s;//OK
311 :
デフォルトの名無しさん :03/05/17 20:51
VC++って最新バージョンは6なの?
7.1(VS2003)
313 :
デフォルトの名無しさん :03/05/17 21:37
Cをマスターしたいんですけどなにからすればいいのでしょうか?
>>313 のようなつまらんネタを書かないことからはじめよう
316 :
デフォルトの名無しさん :03/05/17 22:05
>>310 どうもありがとうございます。
CStringのインスタンス自体は、ただのポインタ変数だったのですか。
もう一つ教えてください。
CStringは、CStringT からインスタンシエートされたクラスなんですか?
だとしたら、どのヘッダファイルの中で typedef されているのでしょうか?
度々すみません。教えてください。
>>316 暗黙の型変換について調べたほうがいいよ
319 :
デフォルトの名無しさん :03/05/17 22:23
int num[3]; のとき、 num[0] = 0; num[1] = 0; num[2] = 0; のように、 配列にすべて0を代入する関数って、標準関数にありますでしょうか。 どなたか教えてください。
320 :
デフォルトの名無しさん :03/05/17 22:25
int num[3]; のとき、 num[0] = 0; num[1] = 0; num[2] = 0; のように、 配列にすべて0を代入する関数って、標準関数にありますでしょうか。 どなたか教えてください。
あ、memsetか
std::fill
std::fill_n
int num[3] = { 0 };
/ヽ /ヽ
/ ヽ / ヽ
______ /U ヽ___/ ヽ
| ____ / U :::::::::::U:\
| | // ___ \ ::::::::::::::|
| | | | | U :::::::::::::|
| | .|U | | ::::::U::::|
>>325 以外吊っとけよ…
| | | ├―-┤ U.....:::::::::::::::::::/
| |____ ヽ .....:::::::::::::::::::::::<
└___/ ̄ ̄ :::::::::::::::::::::::::|
|\ | :::::::::::::::::::::::|
\ \ \___ ::::::
>>326 ハァ?
代入と初期化は異なる演算だとあれほど・・・・
てか、なんで標準関数でやろうとしてんの?
330 :
デフォルトの名無しさん :03/05/18 00:30
class T型を newして、 引数のクラスに、追加した関数テンプレートを作りたいのですが どう作ればいいでしょうか template<class T> T* MakeTask(CTaskMgr& task,DWORD ID) { T* p = new T; task.add(p); ..省略.. return p; } みたいな感じにしたいのですが、 引数にT型がわかる者がないので、上手くいきません。 テンプレートクラス template<class T> class TaskBuilder{ static T* Make(CTaskMgr& task,DWORD ID); }; // TaskBuilder<CTask>::Make(task,id); で使う。 で、静的関数やfriend関数にしても 上手くいかないです。 何か方法ありませんか?
331 :
デフォルトの名無しさん :03/05/18 00:33
何故、CString 型変数を const char* 型変数へ代入する事が出来るのか どうしても分かりません。 どういう原理で、CString 型が LPCSTR と同等と見なされるのですか? 誰か教えてください。
>>331 CString::operator LPCTSTR
>>330 p=MakeTask<ClassName>(task,id);
>>308 ,309,316,331
VisualC++(MFC限定)相談室へいってらっしゃい
>>330 こういうことがしたいの?
class CTask { ... };
class CTaskA : public CTask { ... };
class CTaskB : public CTask { ... };
class CTaskC : public CTask { ... };
class CTaskMgr {
private:
list<CTask*> task_list;
public:
template <typename T>
T* add() {
T* p = new T;
task_list.push_back(p);
return p;
}
...
};
CTaskMgr task;
task.add<CTaskA>();
task.add<CTaskC>();
task.add<CTaskB>();
なんか見た事あるぞそれ。
for(int i = 0; int let = tolower(str[i]); ++i) ... switch(int key = ...) ... if(FILE* fp = fopen(...)) ... ... とか使いますか?
うん
>>332 エラーが出るって意味です。
error LNK2001: 外部シンボル "
"void __cdecl MakeTask(class CTaskMgr &,unsigned long)" (?Make@@YAXAAVCTaskMgr@@K@Z)" は未解決です
みたいな感じです。
>>334 それも、やってみたけど、だめでした。
>>336 試してみたのですが
error C2275: 'CTaskA' : typedef 識別子に、クラス メンバ アクセス演算子 (->) を使用しました。
みたいなエラーが出てしまいます。
->なんて使って無いのに。
環境は、VC++6.0です。Boostでも、理不尽なエラー出るし、無理なのかな。
もうすこし、いろいろと試して見ます。
>>340 template <class T>
struct dummy{};
temp,ate <class T>
T *make(dummty<T>){ return new T; }
make(dummty<ClassName>());
あ・・・ 関数実体を、ヘッダに書かずに、cppに書いてた。 テンプレートの初歩ミスでした。 (´Д`;) ゴメンナサイゴメンナサイ ∨) (( (;´Д`) スミマセンスミマセン ( 八) 〉 〉 (´Д`;)、 コノトオリデス ノノZ乙
ぬるぽ
>>338 それって、新しく定義した変数の値が評価されることになるの?
ちょっと異常な質問なんですが、関数ポインタ型の変数を定義するとき 普通は例えば typedef int (*FC)(int, int); FC p; のようにすると思いますが、これをtypedef使わずに一行で定義する となると、どういう書式になるのでしょうか?
347 :
デフォルトの名無しさん :03/05/18 12:31
質問です。 表示中のメニューの座標(画面の左上端を(0,0)とする)を 取得するには、どうしたら良いでしょうか? CMenu::GetMenuInfo で試みようとしましたが、 それでは座標が所得出来ないので。
348 :
デフォルトの名無しさん :03/05/18 12:33
>>346 int (*p)(int, int);
板は合ってる
>>346 int (*p)(int, int);
つーか、typedef で新しく定義する型名が入る位置
→ typedef int (*ここ)(int, int);
は、直接変数宣言するときに変数名が入る位置。
あ・・・スマソ 質問間違えた。さっきの質問じゃたしかに答え簡単ですよね・・・。 でなくてですね・・・ typedef int (*FC)(int, int); FC func(FC); //関数宣言 これをtypedefなしの一行で・・・。
int (* (*)(int (*)(int,int)))(int,int)
funcが無い時点でおかしいような・・・
すまんこうか。 int (*func(int(*)(int, int)))(int, int);
>>352 func(引数) という式の値は int ( *FC )(int, int) という型。
→ ゆえに int ( *func(引数) )(int, int);
引数は int (*)(int,int) 型
→ 従って int ( *func( int(*)(int,int) )(int, int);
いかん、括弧が1個足りん。
358 :
デフォルトの名無しさん :03/05/18 14:57
初心者の質問ですがお許しください。 int a; char b; cin >> a; cin >> b; 上記で、入力された値が期待された以外のもの、つまりaに整数以外の文字が 入力されたり、bに数字や2文字以上の文字列が入力された場合のエラー処理は どう書けばよいでしょうか?
cin >> a; if (cin.fail()) { 入力がおかしい }
360 :
デフォルトの名無しさん :03/05/18 15:56
template <class _T> class CHogeImpl { ... } class CHoge : public CHogeImpl <CHoge> { ... } こういうのって、どういう意味合いのテクニックを あらわしているんでしょうか?
>>355-
>>357 サンクス。
なんとなくわかった気が。
typedef int (*FC)(int, int);
の式でFCの部分をfunc(引数)で置き換えて、typedef取ればいいのかな?
int (*func(引数))(int, int);
さらに引数も置き換えて
int (*func(int (*)(int, int)))(int, int);
で、もし仮引数名(pとする)もつけるとすると
int (*func(int (*p)(int, int)))(int, int);
ってことでいいのかな?
C/C++の関数ポインタの記述ルールはなんかおかしいからな 素直にtypedefが一番
ライブラリファイルとして使うときとか、公開するときとかって ヘッダファイルどうやってまとめればいいの?
libファイルにして、、、だった。
インターフェースを超洗練してまとめろよ。
(;´Д`)スミマセン、スミマセン・・・C++デ 二乗(べき乗)って ドウヤルンデスカ? ヘルプミテモミツケレマセン・・・ ・゚・(つД`)・゚・ツリジャアリマセン・・・タシケテクダサイ・・・
y = x * x; /* xの二乗 */ y = pow(x, 2.0); /* xの二乗 */
#include <iostream> template <int i,int n> struct static_pow{     enum{         tmp=((n==0)?0:i),         tmp2=((n==0)?0:n-1),         tmp3=((n==0)?1:i),         value=static_pow<tmp,tmp2>::value*tmp3             }; }; struct static_pow<0,0>{     enum{         tmp=0,         tmp2=0,         tmp3=0,         value=1     }; }; int main(int argc, char* argv[]) {     int a[static_pow<2,3>::value];     std::cout << sizeof(a)/sizeof(a[0])<<std::endl;     return 0; }
(;´Д`)スミマセン、スミマセン・・・モイチド、オナジソースカキナオシタラ
コンパイラトオリマシタ・・・ドコカニゼンカクスペースデモハイッテタノデソウカ・・・
・゚・(つД`)・゚・オテスウカケマシタ・・・
>>368 ,369サソアリガトン・・・
そういやC++って配列は無条件で初期値に初期化されるんだっけ? newのときだっけ?(なんかごっちゃになる) Cだと定義スコープによるんだよね、たしか。
>>374 デフォルトコンストラクタは呼ばれるけど、
int とかだと「何もしない」んで値は未定。
ただ、変数が静的だと 0 で初期化される。
これは C と同じ。
あと、1 つでも初期化したら後ろは全部 0 で初期化される。
だから、
int vec[100] = { 0 };
ってやったら全部 0 で初期化される。
これも C と同じ。
int new したときは fill_n でも使って代入汁。
静的じゃないけど main() { map<string, int> test; test["abc"]++; cout << test["abc"] << endl; } で1が出力されるよ。
>>376 map の場合はintのデフォルトコンストラクタ呼ぶ(と言うと正確では無いか
もしれんが要は0で初期化)でしょ。
ただ、VC++ だと、Release モードだと0 に初期化してくれるけど、Debug モー
ドだとしてくれないとかあるっぽいんだよね。
で、余談だけど、前の開発者がヴァカで Debug モードを全然使っていなかった
らしく、全然初期化してない変数がいっぱいあって、Debug モードだと実行出
来ないっちゅー悲惨なコードの保守を任されてヒーヒー言った経験あり。
# これがまたクソコードで・・・と、愚痴はやめときます。ハイ。
第二段落の目的語は「普通のintとかの変数」ね。 つまり、クラスのメンバーに int の変数持ってる場合、 Release モードだとそのメンバーがゼロで勝手に初期化される事もあって、 それによりかかったコードがバラ撒かれてて悲惨な目に合った、と。そういう意味です。
おれゲーム作ってるんだけど、Debugでコンパイルするとスゲー重い。 しょうがないからずっとRelease。 文句在るのか?
staticメンバ関数ってinline化されないよね? staticメンバだけの関数をDLLから使うにはどうしたらええの?
> staticメンバ関数ってinline化されないよね? されますが。
>>379 とある科学計算に使うようなソフトの一部なんだけどね。
オブジェクトのコピーを memcpy 使ってたり、とにかく悲惨なコードで、
deleteを知らんらしくメモリリークもしまくりで、さらには継承、っちゅー
かそれ以前にモジュール化も知らんのかなんなのか同じコードのコピペが至る
所に撒き散らされてて・・・(以下略
> staticメンバだけの関数 関数がメンバ持ってるの?
みなさん、リストを作るときって、 *prevや*nextはpublicにします?protectedにします?
使い道が決まるまではprivate
>>387 コンパイルオプションによっては自動的にインライン展開されるかもしれないが、
DLLとしてエクスポートする指定がコンパイラに伝えることができるなら、
非インラインの実体も残るはず。
伝えることができないなら、DLLの作成に失敗する(たぶんリンクエラーになる)はず。
GCC 3.2.2 なんですけど、 struct A { int a; A() { } }; struct B { int b; B() : b() { } }; int main() { cout << A().a << endl; // 無茶苦茶な値 cout << B().b << endl; // 0 int * p = new int; cout << *p << endl; // 無茶苦茶な値 delete p; p = new int[1]; cout << p[0] << endl; // 無茶苦茶な値 delete [] p; p = new int(); cout << *q << endl; // 0 delete p; } ってなりました。 初期化子入れないとデフォルトコンストラクタが呼ばれる、 と思ってたけど、実際にデフォルトコンストラクタを指定すると挙動が違うんですね。 これって、int とかだと明示的に指定しないと デフォルトコンストラクタが呼ばれないという仕様なんでしょうか?
>>392 intとかの基本データ型は明示的にコンストラクタを呼ぶと0初期化になるが
呼ばないと不定なのは規格通り
なるほど。やっぱそうなんですね。 ありがとうございました。
395 :
デフォルトの名無しさん :03/05/21 01:29
∧_∧ ( ´∀`)<この使い方間違ってるんでしょうか std::stringstream ss1, ss2; while(std::getline(ss1, ss2.str(), '\n')); ←コンパイルエラー error C2180: 制御式に void 型があります。 )
getlineの格納先は非const参照なので、左辺値を渡さないとダメです。 ss.str()は一時オブジェクトで、左辺値になれません。 > error C2180: 制御式に void 型があります。 エラーメッセージが全然関係ないのが気になるけど。
>>377 Debugモードだと初期化しないんじゃなくて、メモリを確保した時点で0xCDで
初期化されるんだよ。デバッガで変数やメモリを見れば初期化し忘れている
ことが一目で分かるようになってる。
ちなみに、ビッグエンディアンの環境だと0xDEADBEEFを同様の目的で使って
たりする。
>>396 了解しました。サンクス。
VC5なんだが、stringstreamのヘルプ見たら
basic_string<E, T, A>& str();
なんて書いてあるもんだからつい。
エラーメッセージは結局謎。コンパイルは出来てもよさそうなんだが・
399 :
デフォルトの名無しさん :03/05/21 12:52
A GetA(); hoge() { A& a = GetA(); } というのは文法的にどうなの? Aがlongだとコンパイルエラー(long からlong&に型変換出来ない)で、 class A {}; だと警告も出ないんだけど。
環境は、VS.NET2002です。
401 :
デフォルトの名無しさん :03/05/21 13:18
ライブラリをインクルード可能にするにはどうしたらいいんですか?
>>399 一次オブジェクトへのリファレンスはconstの場合のみ有効。
const A& a = GetA(); ならばok。
constでない場合はコンパイルエラーは出ないかもしれないが、処理が次の
行に移った時点で既にaの指すオブジェクトが無効になっている可能性がある。
気が利くコンパイラはaのスコープが外れるまで一次オブジェクトの寿命を
延ばしてくれるかもしれないが、そのようなプログラムは実装依存になる。
>>401 まず、次の言葉の意味を知ること
- インクルード
- リンケージ
- ライブラリ
>>402 オブジェクトの寿命の方は問題ないのですが。
実は、このコードだとスタックが破壊されるんですよ。
前後どっちかに100byte程度のバッファを置いてると分かりますけど。
でも、コンパイル時に警告も出ないのでなんでかな?と思ったわけです。
あ、そういう意味か。 一次→一時ですよね。 なるほど const で試してみます。
406 :
デフォルトの名無しさん :03/05/21 15:45
クラスの初期化メソッドで質問です。 作成したインスタンスを初期化するために、下のような初期化メソッドを持たせています。 class CSuper { protected: int m_value; public: CSuper(); ~CSuper(); void Init(int inValue){m_value = inValue}; }; これのサブクラスを作った場合、追加されたメンバ変数も初期化したいので class CSub : public CSuper { protected: int m_value2; public: CSub(); ~CSub(); void Init(int inValue, int inValue2) { Init(inValue); m_value2 = inValue2; }; }; こんな風にしています。でもこれだと、CSubを作るときに間違ってCSuperのInit(int inValue)を呼んでしまうかもしれません。どうすればいいですか。InitSuper(), InitSub()とか名前を変えたほうが良いんでしょうか。 どっちにしても間違った初期化関数を呼んでしまう可能性がありますし、美しくない気がします。
駄目だ、やっぱりスタックが破壊される。
>>406 曖昧さの解決にはスコープ解決演算子を使用する。
409 :
デフォルトの名無しさん :03/05/21 16:47
>>408 CSubのインスタンスに対してCSuper::Init出来てしまうので困っているのです
>>409 CSub sub;
sub.CSuper::init(0); // コンパイル可能
sub.init(0); // エラー
わざわざ CSuper:: を付けないといけないから、
特に問題は起こらないと思うけどな。
412 :
デフォルトの名無しさん :03/05/21 17:17
>>411 いや、それはOKなんですよ
でも今回はCSub::Initは引数が二つに増えてるので、CSuper::Initのオーバーライドはして無いんです。
413 :
デフォルトの名無しさん :03/05/21 17:19
CSub sub; sub.Init(0); sub.Init(0, 1); どっちもOKになるのが困ります
414 :
デフォルトの名無しさん :03/05/21 17:23
すんません間違えてました sub.Init(0);はコンパイルエラーになりました ウワーンハズカシー ていうか何で?
>>414 おかしいと思った。
基底クラスのメンバ関数はオーバーロードされないの。
あなたの危惧していたことを防ぐためにね。
知らんかった
ここでは使えないほうがいいから関係ないが、 両方使えるようにしたいときはusingで引っ張り込めば良いアルネ
418 :
デフォルトの名無しさん :03/05/21 19:17
std::stringをstd::wstringに変換するにはどうしたらいいですか?
>>418 こんな感じかな?
テストはしてないけど。
#include <cstdlib>
void convStrToWStr(const std::string& src, std::wstring& dst) {
const int length = src.length() + 1;
wchar_t* buf = new char[length];
std::mbstowcs(buf, src.c_str(), length);
dst = buf;
delete [] buf;
}
C++BuilderならこれだけでOK static std::wstring str2wstr(const std::string &str) { return std::wstring(WideString(str.c_str()).c_bstr()); }
>>399 なぜそんなトンチンカンなことをしたがるのか、まずは自分の頭を
デバッグした方がいいかと…
422 :
デフォルトの名無しさん :03/05/21 20:42
昔のAthlonの本読んでて、C++での最適化法として書いてあったんだけど コードとデータを双方とも同じ64KB領域に置かないって奴です。 これって具体的にはどういうことなんでしょう? c++でどう書けばコードとデータが近傍に配置されたり されなかったりするんでしょうか?
>>397 そうだったんでつか。知りませんでした。勉強になりました。アリガトウ。
でもどーせなら未初期化のメンバー変数がある場合にはワーニング出てくれれ
ばいいんですけどねぇ・・・Wallでも出ないっすよねぇ・・・
Point クラスとか作る時にゃ未初期化でいいもんな。
g++の-Weffc++オプションはウザイくらいに説教してくれたと思う
426 :
デフォルトの名無しさん :03/05/21 21:52
今俺C++NET インスト中だがインストに必要な時間が1時間20分。 激しく萎えています。 CD-ROMは48倍速だしHDDは最近買った60G(そこそこの速度はある) いったい何をしているんだこのインストーラー(藁 スタジオ(フルセット)だったらどんぐらいかかるの?
>>423 パフォーマンスの関係でメンバを初期化しないってのはよくある話なので
そんなことでいちいちワーニング出されても困るよ。
>>426 HDDがPIOモードになってたりしない?
>>419 逆にwstringをstringにすることってできますか?
char* しか渡せない関数に文字列(wstring)を渡したいのですが・・・
ごめん、ぐぐったらあっさり見つかりました。 そのまんまな名前ですね。(wcstombs)
new char → new wchar_t だっね。
431 :
デフォルトの名無しさん :03/05/21 23:13
今インスト終わりました。
>>427 427さん情報ありがとデバイスまねじゃみたけど、PIOではなかったよ。
でもTHX
21:52-> 23:10 1時間20分
おおよそ時間は正しかったな.....
VC単体(スタンダート)のインストでこれなら フルセットは半日(1日?)かかるなw
実際どうなんだろう。体験者いないかな。
きのこっのこのこげんきのこ えり〜んぎ まいたけ ぶなしめじ
433 :
デフォルトの名無しさん :03/05/22 02:34
↑↑↑ ヘキサゴン見たな(w
434 :
デフォルトの名無しさん :03/05/22 02:44
435 :
デフォルトの名無しさん :03/05/22 03:06
436 :
bloom :03/05/22 03:11
437 :
デフォルトの名無しさん :03/05/22 04:39
class A{}; class B : public A {}; class C : public A {}; int foo( int i ) { // これがうまくいくのに A* p2 = i > 1 ? new B() : new A(); // なんでこれはコンパイルエラーなの? A* p1 = i > 1 ? new B() : new C(); } ~
エラーメッセージは何て言ってるんだ?
gccでもエラーになるけど、-pedanticつけると警告だけでエラーにはならなくなる。 -pedanticで甘くなることもあるもんなの?バグ?
正直AとかBとかいうクラス名は読みにくい。いつもちょっと考え込む。 サンプルコードにはそれっぽい名前をつけてほしいにょ。
>>438 クラス B と C の間に直接の継承関係がないから
条件式の結果を何の型にすればいいのか判断できないんじゃないかな。
共通の基底クラスにしてくれればいいもんだけど、
そうするようにはなってないんだろうね。
というわけで、どちらか(または両方)明示的にキャストすれば大丈夫だね。
A* p1 = i > 1 ? static_cast<A*>(new B()) : new C();
string<->wstringを正しく変換するにはsetlocaleでロケール設定を正しく行わないとダメなようですね。 プラットフォーム非依存なコードを書くにはどうしたらいいのだろうか。 以下だとMS932限定。 void strtowstr(const std::string& src, std::wstring& dst) { setlocale(LC_ALL, ".932"); size_t length = src.length() + 1; wchar_t* buf = new wchar_t[length]; mbstowcs(buf, src.c_str(), length); dst = buf; delete [] buf; setlocale(LC_ALL, ""); }
codecvt?
445 :
デフォルトの名無しさん :03/05/23 11:50
fstreamがファイルのクローズに失敗しても例外飛んでこないのですか? 飛んでくるとしたらデストラクタが例外投げることになるし、 飛んでこないとしたら、ディスクがいっぱいになったりしたときにエラーが検知できないし・・・。
>>439 C*からB*にキャストできねーよ!っつってます。
>>441 スマソ。次から。
>>442 ありがと、そか、かたっぽだけでいいのか....
>>440 まじっすか?不思議だ...つか、規格上は許されるべきものだったのか...mmmm。
447 :
デフォルトの名無しさん :03/05/23 12:20
教えてください。 DAOを使用してvc側でaccessに接続する処理を作りました。 これを関数化して vb側から引数としてmdbファイルのフルパスとテーブル名を渡して 指定したテーブルのデータを戻り値としてvb側で受けたいのですが vc側でデータが見つかる度にvb側に値を返すように作れるでしょうか? その方法としてどのような方法があるでしょうか? コールバック関数という言葉を耳にするのですが、このような処理に 使用できるようなら その技法を教えていただければ助かります。 よろしくお願いします。
DLLからローカルファイルを削除等を出来ないようにしたいのですが、 LoadLibrary()呼び出し側から制御する事は出来ますか?
>>446 -pedantic つけた時の奴は
void* への変換が起こってるっぽいので、
期待する結果は得られないと思う。
>>447 >>449 そういう環境依存の話は C++ 相談室でよりも
それぞれの環境のスレで聞くのが幸せ。
453 :
デフォルトの名無しさん :03/05/23 19:58
アセンブラからクラスをコールする方法と アセンブラでクラスの作り方教えてください
質問です。よろしくお願い致します。 最近CからC++へと移行したのですが、コンパイル時間が長過ぎるのが気になります。<C++ ちょくちょくとコンパイルしつつ進めて行くタイプなのでこれは自分的には非常に困るのです。 そこで何かコンパイル時間を短縮するような方法、工夫等あれば教えて頂けませんでしょうか? 環境はlinux-g++です。
makeは使ってるよね?というのはさておき includeするヘッダファイルを減らすとか・・・ 実際に減ってるか確認しないと意味ないけど。 あとは、gcc-3.4まで待つか、VC++に鞍替えする。
再帰的に呼び出される関数が インライン宣言されているとき、 ちゃんとインライン展開されるのでしょうか? されるなら関数呼び出しオーバーヘッドはないですよね?
されるかされないかは処理系依..(ry
459 :
デフォルトの名無しさん :03/05/23 23:10
>455
レス有難う御座います。
やっぱりこういうものなんですね、 C++での開発というのは。
とりあえずは指摘のようにヘッダファイルを減らしてみます。
precompiled headersって奴ですね。楽しみです。
ttp://gcc.gnu.org/gcc-3.4/changes.html Linuxプラットフォーム向けに開発しているのでVC++に鞍替えするという選択肢はないのです。。。
C++お勉強中の者です。 テキストに画面に文字表示するとき cout >> "ハロー" みたいな感じで書いてあるのですが 仕事でもこれを使うのでしょうか? printfの方が激しく使いやすい気がするのですが。 cinもしかりです。
タイプミスです。逆でした cout << "ハロー"
それで思い出した。 cout で小数を表示する時、 指数表示を強制できるの?
double pi = 3.14159265 cout << precision(3) << pi; とか
setprecision(3) の間違ひ。
小数点以下何桁まで表示するか?のこと? それですとテキストにはこんな感じでごちゃごちゃのってます。 cout << setw(4) << setprecision(2) << setiosflags(ios::right | ios::fixed | ios::showpoint) << 2.5
>>464-466 指数表示だって。
たとえば、その場合だと
3.14e+00
とか
2.5e+00
と表示されてほしいの。
cout.setf(ios::scientific, ios::floatfield);
wstring hoge = "ほげ"; cout << hoge << endl; ができないことに驚いたのですが wstringってどうやって使うために存在するんでしょうか?
wcout
やっぱりcoutって使いにくいですね。 みなさんもそう思いませんか?
Σ(゚Д゚)気が付かなかった。 C++勉強中なので疑問に思ってしまうのですが、 なんで <<演算子のオーバーロードじゃなくて wcoutが用意されているんでしょうか。
>>471 激しく尿意なので、
boost::format でも使うべし。
>>472 C++ のストリームライブラリは、文字の定義を変えることによって、動作を変更できる。
デフォルトで char, wchar_t に対応したストリームが用意されている。
wcout は wchar_t 用に特殊化したストリーム。
ほかにユーザー定義型でも特殊化できる。
(例えば、入出力の単位データ幅を変更できたりする)
うーん・・・どうしようもない馬鹿ですみませんが。 char型変数内の1byteを16進数の文字コードで取り出したいのですがどうすればいいのでしょう・・・
>>478 MFCスレのマルチポスト真性教えて君の中の人ですか?
char s[3]; sprintf(s, "%02X", (char)c); ライブラリを使わない実装は宿題とする
(char)c しても結局 int にされちまわないか?
c の型は char ですよ、と言いたいんじゃないの? もしくは、c が int で、中の値を char の範囲に落としたいとか。
483 :
デフォルトの名無しさん :03/05/24 03:48
char a[3]; sprintf( s, "%02X", (unsigned int)c ); でいいんじゃ?
sprintf( s, "%02X", c & ( ( 1 << CHAR_BIT ) - 1 ) );
const char figures[] = "0123456789ABCDEF"; char str[] = { figures[(c&0xFF)/0x10], figures[c&0x0F], 0 };
char sOut[ 3 ]; char cIn; int iTmp; int iCnt; for( iCnt = 0; iCnt < 2; iCnt ++ ){ iTmp = cIn / 0x10; if( iTmp >= 10 ) sOut[ iCnt ] = 'A' + iTmp % 10; else sOut[ iCnt ] = iTmp; } sOut[ 2 ] = '\0'; これでどーよ?
missった char sOut[ 3 ]; char cIn; int iTmp; int iCnt; for( iCnt = 0; iCnt < 2; iCnt ++ ){ iTmp = ( cIn / ( int )pow( ( double )0x10 , ( double )iCnt ) ) % 0x10; if( iTmp >= 10 ) sOut[ iCnt ] = 'A' + iTmp % 10; else sOut[ iCnt ] = iTmp; } sOut[ 2 ] = '\0'; 吊ってくる
質問ですが、クラスにコンストのメンバってもてないですよね? 初期化ができないと思うんで・・・。
>>488 constメンバ変数はコンストラクタで初期化できる
>>488 class A {
const int n;
A( int i ) : n(i) {}
};
とかって書く。
あ、そのやり方ですか、なるほど・・・。 じゃ、コンストラクタの定義ブロック内では 初期化できないんですね?
コンストラクタのブロック内ではメンバの初期化はできない。 しているというのなら、それは代入だ。
クラスのstaticメンバってありますよね。 あれは、一度どこかで定義しないといけないと思うのですが、 グローバルスコープで定義するとうまくいくのですが、 main関数内で定義すると「再宣言あるいは再定義エラー」に なるのはなぜでしょうか?
関数内でんな事するな。
ちゃんとしたコンパイラならスタティックメンバは定義と初期化が同時に出来ます。
496 :
ピー子について :03/05/24 14:30
次のように記述できるオブジェクトを作りました。 使い道はありますか? aboutPiko() { //description Obj Piko("piko"); //ピー子 Obj Bird("bird"); //鳥 Piko.is(Bird); //ピー子は鳥です。 Obj Sing("sing"), Morning("morning"), Tree("tree"); Bird.does(Sing).when(Morning).where(Tree); Obj ChunChun("chunchun"), Cage("cage"); Piko.does(Sing).how(ChunChun).where(Cage); Obj Wing("wing"), Shoulder("shoulder"), Folding("folding"); Bird.has(Wing).where(Shoulder).how(Folding); //dialogue Anser Ans; Ans<<Is(Piko,Bird); cout<<Ans<<endl; //out=piko is bird Ans<<Has(Piko,Wing); cout<<Ans<<endl; //out=piko has wing Ans<<Where(Has(Piko,Wing)); cout<<Ans<<endl; //out=piko has wing where shoulder Ans<<Where(Does(Piko,Sing)); cout<<Ans<<endl; //out=piko does sing where cage Ans<<How(Has(Piko,Wing)); cout<<Ans<<endl; //out=piko has wing how folding Ans<<When(Does(Piko,Sing)); cout<<Ans<<endl; //out=piko does sing when morning Ans<<Why(Does(Piko,Sing)); cout<<Ans<<endl; //out=unknown }
何じゃこりゃー!
>>496 Prolog風なのかな。
つか...詩?
>>495 privateメンバなら直接初期化はできないんじゃ・・・
class mona { static const int ITTEYOSHI = -2614; }; 通ったよ。bcc5.6.4
>>500 VC++は通らないので注意。
クラス定義の外で
static const int mona::ITTEYOSHI = -2614;
こう定義できる。
ただし、インクルードファイルに書くと多分多重定義で怒られるw
>>501 だから正しいコンパイラなら通るんだって。
VCは標準への準拠度が低いだけ。
VC7.1では通るんじゃない?
>>501 クラス定義の外ならstaticいらんでしょ。
というかstaticつけるとエラーだぜ。
>>502 だれもVCが正しいコンパイラとは言ってない。
某島の信者の中の人も大変だな。
>>495 整数定数ならな。
小数や配列(文字列)、ポインタは不可。
ヘッダファイルで直接定数を定義する場合も整数だけだから注意ナ。
何でこういう仕様になっているかというと、
整数定数の場合はアドレスを要求する必要がないからだ。
言い換えるなら、コード中に直接値を埋め込む事ができるからだ。
ポインタは論外として、
アセンブリ言語やってりゃ分かるが、
小数はコード中に直接値を埋め込む事ができないのが普通だし、
配列も定数を一要素だけ参照する分には問題ないが
変数でインデックスを指定するとどうにもならない。
ということだ。
現行のVC++よりもマシとはいえ、某のコンパイラもまだまだ正しいものとは言えない。
VC7.1でBCCはMSに準拠度で追い抜かれます。 g++,vc++,bccの中でlokiやboost::lambdaが通らないのはbccだけになります。
その頃にはC++Builder7出てるんじゃない?何とも言えんけど。 それと、OpenWatcomとか火星とかは?
>>511 MarsやWatcomは知名度からして負けてます。
g++,vc++,bccが今の3大C++コンパイラと言っていいでしょう。
iccなんて一部の数値計算分野でしか使われないでしょうし。
C++インタプリタのCINTってどの程度動くものなんですか? iostreamやSTLも普通に使えてクラスも定義できるんですか?
私のCodeWarriorが出てこないのはなぜ(ToT)
コード戦死はかなり強力だよね。使ったこと無いけど。
自分で調べたよ。 fstream::~fstream()は基本的に例外を投げないようになってる。 fstream::close()は失敗でsetstate(failbit)する(マスクに応じて例外を投げる)。 つまり、閉じるときのエラーを逃さないようにするためには、 fstream::close()を明示的に呼ばなければならない。 デストラクタに任せてしまうと、閉じるときのエラーは検知できない。 明日からはfstream使った後は明示的にcloseしよう。
CWはCWでクセがあるからなあ・・・
CWってeclipseみたいなツールなの?
CWはIDEとコンパイラのセットだけど VS.NETとはまた違った趣があるね 使いやすいとは思わなかった
>>521 もしかして常識だったのかもしれんが、
漏れはいままでfstream::close()を使ったことがなかった。
523 :
デフォルトの名無しさん :03/05/25 15:18
すません。C++一ヶ月未満の超初心者です struct p { int A; int B; double C; } ... p *pp = new p; p->A= x; 上記のように、ある構造体をnewで生成したのにデバグでアドレスを参照すると0x00000000になってしまいます どうすればいいでしょうか?普通newすると新たなアドレスがセットされると思うのですが・・・ これって、newに失敗したってことなんでしょうか?
デバグでアドレスを参照って、具体的にどうやったの?
525 :
デフォルトの名無しさん :03/05/25 15:38
説明不足で申し訳ないです。 デバグモードで起動させるとそこの処理でエラーになるので 「なんでかなー」と見てみると、newされた変数(?)のポインタが0x0000000になっているので 再度、ブレークポイントを宣言場所にセットして確認しました。 newの命令後はその変数が0x0000000になってしまっているようです。 ウォッチと、変数のウインドウで確認しました。 ためしに別のプロジェクトでちょっとした構造体をnewで生成してみると 普通に新たに生成されたアドレスがセットされました。 どうやら、今使ってるプロジェクトのみに発生する問題のようです。 ちなみに、構造体は線形リスト形式で内部で2つの同一構造体のポインタを保持する形式になっています。 struct Node { int id; int data; Node *prev, *next; }; となっています。
文章変ですね。 デバグモードで起動させるとそこの処理でエラーになるので 「なんでかなー」と見てみると ↓ エラーになるので「なんでかな」と思ってデバグモードで実行すると・・・です
>>525 そこまでの情報ではせいぜいコンパイラは VC6かな、と
コンストラクタで何か起きてるんじゃないか、というぐらいしかわからん
>>527 せいぜいのVC6です。
コンストラクタでの問題ですか。むー困りました
529 :
デフォルトの名無しさん :03/05/25 16:01
>>514 出来るよ。フリーなんだからちょっと使ってみればいいじゃん。
メンバーテンプレートも使えるし、それなりにそれなりかと。
でも、
#define INCLUDEFILE <includefile>
#include INCLUDEFILE
ってのが通らないから boost の config がinclude 出来ないんで
boost使うには結構 boost の方に手を入れる必要がある。
最適化はOFFにしてるよねえ・・・
>>528 もしコンストラクタは書いてないのならとりあえず除外して
(むー困りました、じゃあるのかないのか分からん)
他にあるとしたら
・ヒープ破壊されてたり。ヒープ検査関数をnewの前に呼んでみるとか
・他のメモリ破壊(スタック, レジスタなど)
・本当にメモリが足りないとか
・もしアロケータを自分で書いてるとしたらそこをチェック(笑)
すみません。ふて寝してました よし、こーなったら原因をしっかり理解するまではやめないぞー! さて、 >もしコンストラクタは書いてないのならとりあえず除外して コンストラクタがかかれていないってのも微妙に分からないのですが もちろん、線形リストはオブジェクトではあります。 初期に先頭ノードと最終ノードを生成していますが 今回の問題地点とはちょっと違います。 で、問題の場所は線形リストへのリスト追加用メンバです。 処理としては先の構造体を使って node nをnewで作成。 最終ノードの次ノード(最終ノード->next)ポインタにnのポインタをセット nの前ノード(n->prev)に最終ノードポインタをセット dataに値をセット という処理です。ここで、nがしっかり生成されないのでnの前ノードに最終ノードポインタをセット でメモリ(?)エラーになります。 ヒープ破壊ってのは怖いですね。ヒープ検査関数ってどんなのか「超駄目初心者」の私には検討つきませんが ちと、MSDNでも調べてやってみます。
>>530 最適化・・・えと、どこ見ればいいですかね
本当に何も知らないですみません。
先頭/最終ノードを予め生成するタイプだったら、 最終ノードの直前に挿入するんでないの?
535 :
デフォルトの名無しさん :03/05/25 18:03
えーと、先頭・最終は持っていません。ポインタ変数のみクラスで持っています @(=初期ノードポインタ) prev NULL nextA A prev @ next B B prev A next C C(=最終ノードポインタ) prev B next NULL といった感じになってます。でさらに追加する場合 node *n= new nodeでまず、nを生成して n->prev= (最終ノードポインタ); n->next= NULL; (最終ノードポインタ) = n; 私の(小さな)脳味噌だとこれで最終ノードにnというノードが追加されたと思うのですが・・・。
>>523 えーと、状況把握ですけど、具体的にはppに0x00000000が代入されるってことだよね。
それで、
>>532 失敗するノードって後のほうかな?最初の1個2個はOKで30万個くらいで失敗するとか?
ところで、クラス内に別のクラスのポインタを保持しておくことは可能ですよね? で、実はその先に宣言しているクラスポインタに対してコンストラクタでnew生成しています で、途中で delete [クラスポインタ変数] ←内容をクリアしたいのでいったん開放 [クラスポインタ変数]= new [class] ←再度生成。 でその後、追加命令を出してるんですが、 これが原因くさいなーと思ってきました
538 :
デフォルトの名無しさん :03/05/25 18:07
〜2ちゃんねらの予言〜 北朝鮮の現体制が崩壊したとき、いったい何が起きるか。 2ちゃんねらの一人として、あらかじめ予言しておきます。 1)にわか反体制運動家の出現 それまで金正日体制に取り入ることができずに冷飯を食わされていた人間が、ある日突然 「俺は独裁に反対したためにずっと睨まれていたんだ」と言い出します。まるで金正日の 影響力が安全なレベルに下がるのを待っていたかのように、それまで名前も顔も存在も 知られていなかった「反体制運動家」が雨後のタケノコのごとくあちこちから出現。 体制崩壊の主要因が経済破綻だったにもかかわらず、まるで独裁政治を終焉に導いたのが 自分の手柄であるかのように自慢げに振舞います。 2)みんな「俺は強制されていた」 それまで金正日を将軍様と呼び、進んで独裁体制を支持していた人たちは、体制が後戻り できないところまで破綻したのを見抜くやいなや「自分は騙されていたんだ!」「強制されて いたんです!」と、自分たちも独裁政治の被害者であったことをアピールしはじめます。 まるで恋人に騙された女子高生のようにつぶらな瞳をパチクリさせながら、「純真な自分」が 意に反する支持を独裁者から強制されていたことを世界に向けて訴えます。 3)独裁体制が続いたのは日本のせいだ そして「にわか反体制運動家」と「騙されていた善良な人たち」は口をそろえてこう言い出します。 「あんなひどい独裁体制が21世紀まで続いたのは、日本が経済支援をしたからだ!」 「金正日体制を裏で支えたのは日本だ!」 「北朝鮮に独裁国家があったのは、日本のせいだ!」 「日本は復興を支援して当然だ!」 これ、絶対当たりますから、あちこちに貼っておくといいですよ(笑)。 そのときに「ああ、そんなことは日本では前からネットで予想されてましたよ。」 と言って微笑むためにも、ね
>>536 >えーと、状況把握ですけど、具体的にはppに0x00000000が代入されるってことだよね。
そうです。ppをnewで生成すると、中身が0x00000000のNULLで帰ってきます
デバグヒープで確認しました(newの中身見てても良く分かりませんでしたがw)
>失敗するノードって後のほうかな?最初の1個2個はOKで30万個くらいで失敗するとか?
それだったら、まだあきらめつくんですが。実は生成後1回目(つまりコンストラクタ)での
1つ目(初期ノード)は普通にnewで生成されるんですが、次に追加メンバ関数からnewしようとするとNULLで帰ってきます。
あー。。。同じ場所に普通にクラス宣言するとコンストラクタ上の1回目から エラーが出てきますねー ということは、それ以前の処理でヒープ領域を使い果たしてる!? そんな馬鹿なーw
>>539 > 実は生成後1回目(つまりコンストラクタ)での1つ目(初期ノード)は普通にnewで生成されるんですが、次に追加メンバ関数からnewしようとする
生成がコンストラクタだろ?生成後1回目がなんで「つまりコンストラクタ」なんだ?
生成後の1つめが初期ノードってのもおかしくないか?
「追加メンバ関数」ってなんだ?
わけわからん。
ソース晒せば?
>>539 今のところの事情だと
struct Node{
int id;
int data;
Node *prev, *next;
};
int main(){
Node *n1 = new Node;
Node *n2 = new Node;
}
このn2に0が入ることになるけど、どう?
生成はコンストラクタとはつながらないだろ。C++の基本だ 文章は変だが意味としては クラス宣言後の1つ目の処理=コンストラクタ で使ってるnewは問題ないって言ってるんだろうな たしかに文章力無いなら、ソース晒すのが一番早い
うう。必要ない所削って晒そうかな・・・ 削ってたら動いちゃったりして・・・ どうも、問題ある呼び出し場所からどんなnewを使っても必ず0で帰ってきます
文章力あっても、本人の思惑とコードが全く別物ということがあるので、 ソースを晒さない限りわかるわけがない。
>>544 つーかおまえさ。
そんなことは普通聞く前に最低限することだろ。
デバッグの心構えがなってなくないか?
ブレークポイント設定してデバッグしたりするスキルは十分あるんだからそれは言い訳にはならんだろ。
>問題ある呼び出し場所からどんなnewを使っても必ず0で帰ってきます
内容を見てる限り、問題の個所よりも前で不正処理があると思う
どうでもいいが
削らないとデバグできない
>>546 に問題あると思うけど?
大掛かりなプログラムを1つも組んだこと無いだろ
再現する最小限のコードをさらすこと。 バグ発見依頼するときには当然すべきことだよな。
546だけど。
何ゆえ
> 削らないとデバグできない
>>546 に問題あると思うけど?
という結論が導き出されるのかは知らんが
523は事実削らないでデバッグできてねーんだから削るしかないだろ
>>547 意味がわからん。削るっていうやり方はもう知ってるみたいだから
初心者とか関係ないと思うんだが。
>>552 それもそーだね
(´-`).oO(ズイブンケズッテルナァ)
実は Node::Node() {next = new Node;} という落ちではなかろーか
>>540 VC6みたいだから試しに #include <crtdbg.h>して
アプリの最初で
_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_CHECK
_ALWAYS_DF );
をやるようにしてみると、ヒープ破壊が発生したらその次のメモリ確保か開放のタイミングで
デバッグ情報が出るはず。
デバッガの表示が正しくないだけで問題は全然別の場所にあるって可能性は無いのか?
>556 ヒープの確保に失敗した時点で、次のコンストラクタは呼ばれず、 一回目は正常終了する。むろん、充分スタックが在れば、の話
相談するときは ごちゃごちゃ言うより、ソース一行のほうが漏れは好きだナ。 曖昧な日本語の読解よりCのほうがすっきりしてるってことない?
>>560 まさしく。ソースレベルなら実行してみれば
処理系特有のバグも発見できます。
ソースまだかなー。 って、実は削ってる最中に原因見つかって事故解決しちゃってる罠の確率が高いのでは 初心者をまた一歩成長させましたな。 というか、バグは事故解決しましょう
自分で解決できないでごめんなさい。
でも、確かに削ってみるってのはデバグとしては有効な手段のようですね
本当に無知でごめんなさい
動く状態と動かない状態。どちらも確認できました・・・・が!
その違いは問題のクラスとはまったく関係ない場所でした。
しかも、クラスとは関係ない配列にデータ入れてるだけですし。
もはやまったく理解不能です。でもここまで来たら
>>562 さんが言うように
自分で解決させなければならないと思います。皆さん色々ありがとう。
>>563 配列にデータ入れてるってのがメモリ破壊の典型的な原因行為なんだが。
その配列のために実際に確保されてるサイズを超えて書き込んだんじゃないの?
565 :
デフォルトの名無しさん :03/05/25 22:22
>>564 どうやら、ヅボシです。
コンパイルエラーが発生しないことを良いことに
[struct] A= new [struct]で宣言した変数を
そのまま配列として扱ったのが問題だったようです。
どうも、VBでの癖が抜けなくて、配列を甘く見すぎていたようです。
まぬけすぎでしたね。すみませんでした
566 :
デフォルトの名無しさん :03/05/25 22:53
>>565 VB→C++、か。
だいたんな選択だな。
C抜きで逝こうとは。
悪いことではないが。
std::vector使うといいかも。 もっともサイズ超えて書き込むとだめなのは同じだけど(^^; ただdeleteの手間省ける。(例外に対処するなら必要だろうし)
568 :
デフォルトの名無しさん :03/05/25 23:00
あ、Cはかなり昔ですが基本程度は触ってました でもあくまで入門レベルで終わってました。 やっぱり、VBの方が簡単という理由で使ってましたが 今作っているソフトがインタプリタではちと辛いのでVCに移行ということで とりあえずC++の勉強に励んでます。
ついでに初歩的な質問なのですが newで生成した変数に配列を突っ込むことは駄目なんですよね? たとえば pp *p_1= new pp と宣言しておきながら p_2[10]の配列を p_1= p_2 といった感じで。
>>569 どういう意味でだめだと思ってるのかわからないけど、
ポインタ変数に配列を入れること自体は別にOK、ていうか常套。
p_1の値をどこかにとっておかないと後でdeleteできない、て言う意味ではだめ。
話は違うけど配列をnewで作りたいときは
p_1 = new [サイズ] pp;
解放は
delete [] p_1;//サイズは書かなくていい
もう知ってるかもしれんけど。
>>569 pp * p_1 = new pp; // pp型のオブジェクトを作り、そのアドレスをp_1に入れる
pp p_2[10]; // pp型の要素数10の配列
p_1 = p_2; // p_1が差している先のオブジェクトは放置して、p_1はp_2を指すようにする
この結果は、p_1が先に差していたオブジェクトはどこからも参照されなくなり
メモリリーク状態になる。
またp_1が差しているのはp_2そのものなので
p_1[3]を書き替えると p_2[3]が書き換わる。
うーん、入門書読むべし
572 :
デフォルトの名無しさん :03/05/25 23:50
本当にすみません。
親切にありがとう
つまり、ポインタの書き換えを安易に行うと痛い目にあうということですね。
というか、今もdeleteでエラってしまってるんですが・・・
どうやら、またnewで生成した配列関係が原因のようです
システムを破壊しそうなプログラムを組まないように注意しないといけないですね。
>>567 さんが言っていたstd::vectorをちと見てみます。
C++一ヶ月の人に教えたら余計混乱するだけだと思われ・・・
俺、boostのありがたみがわかったのは C++の勉強初めて1年以上経ってからだったからなぁ。
576 :
デフォルトの名無しさん :03/05/26 13:13
stream系クラスでは、たとえば fstream in(filename); if(!in) ... と書くことができますよね。この if(!in) みたいナノを自分のクラスで実現したいのですがどう書いたらいいんですか?
class FileListener {
virtual Opened() = 0;
}
class File {
File( const char* filename, FileListener* listener ) {
fstream in(filename);
if( ! in ) listener -> Opened();
}
}
>>576 ってことか?
>>576 operator bool() const でも実装しとけばー
>>576 if ( !in ) しか使う気がないなら
bool operator!()const
if ( in ) とか使いたいなら
>578か operator void*()const
ただしデメリットが大きめなのでおすすめできない。
(in + 1 とか void* p = in が通るようになる)
んー、iostreamはよく考えられて作られてるけど、 クラスの見本としては最悪の部類に入るから まねしないでいいよ
581 :
デフォルトの名無しさん :03/05/26 23:34
C:\My Documents\c++\box\box.rc (55): error RC2135 : file not found: 0 こんなエラーが出たんですが、どういう意味なんでしょうか?
ファイルがありません
ファイルがないんじゃないの? プロジェクト(?)にないファイルをincludeしてたりするんじゃない? つーか、どんな処理系を使ったのかを書くと、漏れ以外の詳しい人が説明をくれるよ。 つーか、#include <0>とか#include "0"って書いてない?
C++のクラスでVBのようなプロパティを実装するには どうしたら出来ますかね? オーバーロードとテンプレートを使えば汎用的に 実装できそうな気はするのですが… Get〜Set〜はもう嫌だヽ( `Д´)ノウワァァァァン
えっと、使ってるのはVC++の6.0です。 box.rcファイルはちゃんと存在してます。 フォルダ内のファイルを変に動かしたりしたこともないはずなのですが……
>>584 __declspec(property)
>>586 さん
回答どうもですm(__)m
しかしそれはVC依存ですよね?
同様にBCB依存で__propertyとかもあるみたいですが、
私が知りたいのはC++の機能?を駆使しての実装なんです 汗)
(処理系に依存するのは何か嫌なので)
うぅ聞いてるくせに生意気言ってすいませんです(TT)
class TMyClass { int GetProp(); void SetProp(int Value); class TProp { TMyClass *FThis; public: TPorp(TMyClass *This) : FThis(This) { } operator int () { return FThis.GetProp; } operator = (int Value) { FThis.SetProp(Value); } } friend TProp; public: TProp Prop; TMyClass() : Prop(this) { } } こんな感じ?(コンパイルできるかどうかは確かめてません) #ifdefで__propertyや__declspec(property)に切り替えられるようにしといた方がいいかも。
class TMyClass { int GetProp(); void SetProp(int Value); struct TProp { TMyClass *This; public: TProp(TMyClass *This); operator int () { return This->GetProp(); } void operator = (int Value) { This->SetProp(Value); } }; friend TProp; public: TProp Prop; TMyClass() : Prop(this) { } }; コンパイルできるようにして見た。
もう寝たかな?まあいいか。勝手に続けてます。 ちょっと凝ってみた。 #ifdef __BORLANDC__ #define PROPERTY(T, N) __property T N = { read = get_##N, write = set_##N } #define PROPERTY_INITIALIZATION(T, N) dummy_##N() #define PROPERTY_IMPLEMENTATION(T, N) int dummy_##N[0] #else #define PROPERTY(T, N) property_##N N #define PROPERTY_INITIALIZATION(T, N) N(this) #define PROPERTY_IMPLEMENTATION(T, N) \ struct property_##N \ { \ self_type *_this; \ public: \ property_##N(self_type *t) : _this(t) { } \ operator T () { return _this->Get##N(); } \ void operator = (T v) { _this->Set##N(v); } \ }; \ friend property_##N #endif
template<class T, typename V> class property { public: typedef T class_type; typedef V value_type; typedef const value_type& (T::*get_func_type)(void) const; typedef void (T::*set_func_type)(const value_type&); public: property(class_type* pthis, get_func_type gf, set_func_type sf) : cls_ptr(pthis), get_func(gf), set_func(sf) { } const value_type& get(void) const { return (cls_ptr->*get_func)(); } property<class_type, value_type>& set(const value_type& v) { (cls_ptr->*get_func)(v); return *this; } operator const value_type&() const { return (cls_ptr->*get_func)(); } property<class_type, value_type>& operator =(const value_type& v) { (cls_ptr->*set_func)(v); return *this; } private: class_type* cls_ptr; get_func_type get_func; set_func_type set_func; }; property<class name, value type> prop; コンストラクタで prop(this, &class::getter, &class::setter) 昔何処かでこんなヤツみたんだよなー。とりあえず動いた。 たまに使えないけど、エラーが出たときは()で囲めば大抵通るよ。 それでも通らないときはget,setを直接。
↑の使用例 #include<iostream> class TMyClass { int FProp; int get_Prop() { return FProp; }; void set_Prop(int Value) { FProp = Value; }; typedef TMyClass self_type; PROPERTY_IMPLEMENTATION(int, Prop); public: PROPERTY(int, Prop); TMyClass() : PROPERTY_INITIALIZATION(int, Prop) { } }; int main() { TMyClass o; o.Prop = 1; std::cout << o.Prop; return 0; }
つか、 property<class_type, value_type>& set(const value_type& v) { (cls_ptr->*set_func)(v); return *this; } だな。しかもインデントされてねぇ。
>>592 さん(588さんかな?)
すいません ちょいと手酌で酒飲んでました 汗)
すごい!!正直感動しました。
friendクラス、マクロ、テンプレートの集大成じゃないですか!!
改めて2chプログラム板の実力を見せ付けられた気がします
(むしろ592さんかなw)
ホントもうこのまんま頂戴させていただきます^^;
ありがとうございましたm(__)m
by いつかこんなコードをスラスラ書く事を夢見る584
10年くらい前に似たようなのかいたな excelのシートとかでメンバを管理しといて、 ボタン->VBAでヘッダとcppをはき出すようなのをつくっとくと幸せになれるかも
↓みたいに書いてみた、処理系依存だけど、コンストラクタでの初期化はいらない。 #define property( result_t, class_t, Name ) \ class Name##_t{ \ class_t const* get_parent(void) const{ \ return reinterpret_cast< class_t const* >( reinterpret_cast< char const* >( this ) - \ ( reinterpret_cast< char const* >( &static_cast< class_t* >( 0 )->Name ) - \ reinterpret_cast< char const* >( 0 ) ) ); } \ public: \ operator result_t(void) const{ return get_parent()->get_##Name(); } \ operator result_t(void){ return const_cast< class_t* >( get_parent() )->get_##Name(); } \ template< typename T > Name##_t const& operator=( T const& value ) const{ \ get_parent()->set_##Name( value ); return *this; } \ template< typename T > Name##_t& operator=( T const& value ){ \ const_cast< class_t* >( get_parent() )->set_##Name( value ); return *this; } \ } Name
class A { public: property( int, A, PropInt0 ); property( int, A, PropInt1 ); private: int propInt0_; int get_PropInt0(void) const{ puts( "get PropInt0" ); return propInt0_; } void set_PropInt0( int value ){ puts( "set PropInt0" ); propInt0_ = value; } int get_PropInt1(void) const{ puts( "get PropInt1" ); return 5; } }; int main() { A a; a.PropInt0 = 10; printf( "%d\n", (int)a.PropInt0 ); //a.PropInt1 = 10; // Error: PropInt1 is readonly printf( "%d\n", (int)a.PropInt1 ); }
>>596 >ホントもうこのまんま頂戴させていただきます^^;
何に掲載するの? あなた、ライターか何か?
>>600 >何に掲載するの? あなた、ライターか何か?
どこに掲載するって書いてあるの? あなた、電波か何か?
>>581 やっぱ、55行目付近に何か変なこと書いてあるとしか思えん。
603 :
デフォルトの名無しさん :03/05/27 14:00
enumについて質問なんですが、 enumで宣言した変数は、enumの値もしくはenumの型名でキャストした整数しか代入できないということはわかるのですが、 enum型ではないint型の変数になぜenum型の数値を(たとえばredとか)代入できるのでしょうか?
608 :
デフォルトの名無しさん :03/05/27 17:05
void ShowMyBMP(HWND hWnd, HDC hdc) { HDC hmdc; HBITMAP hBitmap; BITMAP bmp; HINSTANCE hInst; int BMP_W, BMP_H; hInst = (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE); hBitmap = LoadBitmap(hInst, "IDB_BITMAP1"); GetObject(hBitmap, sizeof(BITMAP), &bmp); BMP_W = (int)bmp.bmWidth; BMP_H = (int)bmp.bmHeight; hmdc = CreateCompatibleDC(hdc); SelectObject(hmdc, hBitmap); BitBlt(hdc, 0, 0, BMP_W, BMP_H, hmdc, 0, 0, SRCCOPY); StretchBlt(hdc, 0, BMP_H, BMP_W / 2, BMP_H / 2, hmdc, 0, 0, BMP_W, BMP_H, SRCCOPY); DeleteDC(hmdc); DeleteObject(hBitmap); return; } この関数を呼び出すとすごい勢いで凍り付きます。 IDB_BITMAP1はリソースエディタで作成したBMPです。 何が良くないんでしょうか?
原因かどうかは知らんが、"IDB_BITMAP1" は明らかに間違ってるだろ。 しかしスレ違い。
>>608 "IDB_BITMAP1" → IDB_BITMAP1 が気になる点。
あと、SelectObject する時は戻り値を保存しといて、
あとでそれを SelectObject するべし。
あと、hBitmap と hmdc が正常に得られてるかのエラーチェックくらいはすれ。
あと、すごい勢いでスレ違い。
C だし、環境依存の話題だし。
ついでに言うなら、BMP_H, BMP_W って変数名にするんだったら
型を const int にしなされ。
変数名は大文字では始めないのが普通。
>>609 リソースIDは文字列もいけるよ。
ただし、リソースIDを文字列にしてればだけど。
c++でディレクトリ操作やファイル操作をするのに 何かクラスとかが用意されているのでしょうか? いろいろとぐぐったのですが VC++やBCBなど開発環境に依存するものばかりヒットしてしまいます。 それともcのファイル構造体を使用するのですか?
>>611 ディレクトリ操作は標準ではサポートされていません。
ファイル操作には fstream, ifstream, ofstream が使えます。
>609,610 ありがとうございました、おかげで謎の一部は解けました。 しかしまだ正常に動かないので、C質問スレに逝ってきます
複数の基本クラスの仮想関数を区別して実装したいのですが、 VC++で class BaseA{ virtual void Hoge() = 0; }; class BaseB{ virtual void Hoge() = 0; }; __interface BaseC{ virtual void Hoge() = 0; }; class Derived : public BaseA, public BaseB, public BaseC { virtual void BaseA::Hoge(){} // 出来る virtual void BaseB::Hoge(); virtual void BaseC::Hoge(); }; void Derived::BaseB::Hoge(){} // 出来ない、error C2509 'Hoge' が宣言されていません。 void Derived::BaseC::Hoge(){} // 出来る という風に、クラスの外で定義しようとするとエラーになります。 MS独自の__interfaceなら可能ですが、メンバを持てないので今回の場合使えません。 インラインにして別のメンバ関数にリダイレクトするなど回避方法が無いわけではないのですが、どうにも納得いかないので、もしどなたか解決方法をご存知でしたら教えてください。
>>614 なんでもかんでも仮想関数にすればいいというものではない。
>>615 それはもちろんそうなんですけれど。
今回は別にこれがネックになってプログラムが進められない、ということじゃなくて。
ただ、何ゆえこれがエラーになるのか、エラーにならない正しい方法が無いのかと思いまして。
c++から入る人用の本を探しています。 ちなみに、高校時代に「はじめてのC++」塚越一雄 を教本に勉強しようとしていたのですが そんなに進む前に受験により中断を余儀なくされました。 また始めるに当たり、より良い物があれば、と思い質問しました。
素朴な疑問 あるクラスhogeの実装で hoge fuga(10); とやるとコピーコンストラクタが呼び出されるのはわかるけど int x(10); とやってもきちんとxに10が代入さる コピーコンストラクタは組込み型にはない気がするけどなんでだろう ()演算子のオーバーロード?
>>620 > hoge fuga(10);
> とやるとコピーコンストラクタが呼び出される
呼び出されるのは整数型引数のコンストラクタです。
> コピーコンストラクタは組込み型にはない気がするけど
ある。
>>612 ありがとう
どうりでぐぐっても見つからない訳がわかりました。
>>621 intとかcharにコピーコンストラクタがあったとは知りませんでした
char *re("レスありがとうございました")
ってやろうとしたらさすがに無理でしたが
勉強になりました
>>623 g++でもbccでもdmcでもできたーよ。
一般にポインタ、整数、浮動小数点は暗黙のうちにboolに変換できます。 ただし、処理系によっては期待した結果になりません。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ と本に書いてあったのですが、これは例えば int idt=100; if(idt == true) return 0; のようなことを指しているのでしょうか? それとも他にも処理系によっておかしな動作がすることがあるのでしょうか?
> と本に書いてあったのですが どの本?
ていうか、ポインタや整数や浮動小数点をboolに変換してどういう結果を期待しろと?
非0 == true 0 == false
∧_∧ ピュ.ー ( ^^ ) <これからも僕を応援して下さいね(^^)。 =〔~∪ ̄ ̄〕 = ◎――◎ 山崎渉
プロの人ってどーやってウインドウズアプリ作ってんの? VSUAL C++とかBORLANDC++とか使ってるの? そんなの使ってるよーじゃやっぱプロとしてはやっていけないんですかー?
コンパイラはそんな所
でもすれ違いだね
>>626 暗黙に bool に変換できる型はなかったと思うが。
あと、そいつらは制御文の制御式として使えるけど、
結果は処理系依存にはならない。
キャストした場合も同様。
その本、大丈夫?
はるひこの新C++言語入門ビギナー編だが 80何ページに描いてるよ
林 晴比古キタ━━━━(゚∀゚)━━━━ッ!! 嫌な予感がしていたが! やっぱりそうかッ!!
637 :
デフォルトの名無しさん :03/05/28 20:10
文字列リテラルのポインタがconstでなくてもいいのがいつも歯がゆい。 きっとアレだろうな、0e+15 とか、カスウ部が0でも指数部が非0の時、 trueになったりするんだろうな。
そんなおまえにMLを薦める
639 :
デフォルトの名無しさん :03/05/28 22:27
クラスを引数にとるようなメソッドがあった場合に、スタック上にはそのオブジェクトへの ポインタだけが積まれるのでしょうか? 例えば、class Cがあった場合に、 1. foo(C p); 2. foo(C& p); 3. foo(const C& p); 4. foo(C* p); で、各メソッドをコールした場合にコールスタックへ何がプッシュされますか? 1と3は一時オブジェクトが生成されるのかなぁ。
> クラスを引数にとるようなメソッド クラスは引数にとれません
スタック経由するとは限らないわけだが つーか自分で調べた方が早いだろ、そーいうのって。
>>639 C型の値を引数として渡した場合は
一時オブジェクトがつくられるのは1.だけかと。
サクッとアセンブリコードを出力させるべし。
助言ありがとう。理解できました。
g++で
>>639 の実験をしたら、2〜4は同じものが渡されてました。
void mygetline(ifstream& file){ string s; getline(file, s); cout << s << endl; } みたいなコード書いたらエラーになりました。 理由のわかるかたいますでしょうか。 お願いします。
std::が抜けたとか、<string>、<fstream>をインクルードしてないとか、 そういうことではありません。 この1週間悩みっぱなしです。
エラーメッセージも書けないような人は永遠に悩み続けてください。
648 :
デフォルトの名無しさん :03/05/28 23:51
16桁の2進数を入力して、10進数に変換して 出力するプログラムを書いたのですが(とりあえずエラー処理は無しで) コンパイル時に「不正な左オペランド%です」というエラーが出ます。 下から順にi+1番目の桁の値を取得し、2^iをかけたものを足し合わせているのですが… 原因をと対策を教えてください。お願いします #include <iostream.h> #include <math.h> void main(void){ int n, i, sum=0; cin >> n; for(i=0; i<16; i++) sum = sum + ( ( n / pow(10,i) ) % 10 ) * pow(2,i); cout << sum; }
>>647 すみません。bcc32で、エラーメッセージは
エラー E2285 streamtest.cpp 8: 'getline<_CharT,_Traits,_Alloc>(ifstream,string)'
に一致するものが見つからない(関数 mygetline(ifstream &) )
ちなみに、ifstreamをistreamにすると動きます。
でも、ナマのgetlineはifstreamでもいけたはず。
#include <iostream> #include <string> #include <fstream> using namespace std; void mygetline(ifstream& file){ string s; getline(file, s); cout << s << endl; } main() { ifstream file("hogehoge.txt"); mygetline(file); } です。
>>650 俺の環境(VC++7)ではコンパイルできた、実装依存の問題かも?
istreamで動くんなら、istreamにしてはどうだろう?それほどの支障はなさそうだし。
>>648 本題だけに突っ込むと、
原因:%は整数型にしか使えないが、powの戻り値はdoubleなので、( n / pow(10,i) )もdoubleになるからエラー。
対策:pow(10,i) → static_cast< int >( pow(10,i) )
全体的には、いろいろまずい要素が満載で、基本からやり直すことをお勧めしたい。
そのプログラムが学習中のものなら、参考にしたモノを投げ捨てた方がいいと思われ。
>>651 そうですか。ありがとさんです。
でも、気持ち悪いので、誰か何か知ってたら教えてください。
ついでだから、
>>648 。とても読めませんが、こんなのどう?
(なんか学校の宿題くさいけど、俺も
>>651 にレスしてもらったし。)
#include <iostream.h>
#include <math.h>
void main(void){
int sum = 0;
char binary[17];
cin >> binary;
for(int i = 0; i < 16; i++)
sum += binary[i] == '1' ? pow(2, 15 - i) : 0;
cout << sum << endl;
}
かならず16桁あるという前提で。
>>648 16桁の2進数を入力して、10進数に変換して出力するプログラム
#include <iostream>
#include <bitset>
int main()
{
std::bitset< 16 > bits;
if( std::cin >> bits )
std::cout << bits.to_ulong();
}
655 :
デフォルトの名無しさん :03/05/29 00:58
>> 648 とりあえずint型が表示できる数を調べてみてはいかがでしょう・・・
皆様ありがとうございます。 何とかエラーは消えましたが、同じことしてるはずなのに 653さんのはうまくいって何故か自分のは思う結果が出ない…考えてみます。 ちなみに宿題じゃなくて問題集です…
658 :
デフォルトの名無しさん :03/05/29 01:49
>> 648 #include <iostream> #include <math.h> using namespace std; int main() { char str[17] = "0000000000000000"; int i = 0; int ans = 0; cout << "16桁の2進数を入力して下さい:"; str[16] = '\0'; cin >> str; for(i=0;i<16;i++) { if(str[i] == '\0') str[i] = '0'; ans += (str[i]-48) * pow(2,i); } cout << ans << '\n'; return 0; } 16桁以内なら途中で入力を中断しても演算するようにしています
>>653 処理系が標準に準拠できていないんだろうなあ。
使った処理系は何?
ifstreamはistreamから派生している?
fstreamからの派生になってたりしないか?
>>659 レスありがとうです。
俺が使ってるのはbcc32(Borland C++ 5.5)です。
やっぱり、変ですよね。(俺の頭が、じゃなくて。)
某、好きだったんだけどな。
ただ、派生はちゃんとしてるように見えます。
class _RWSTDExportTemplate basic_ifstream : public basic_istream<charT, traits>
この_RWSTDExportTemplateってのはよくわかりませんが。
キャストしてみるとか。気持悪いけど。 getline(static_cast<istream&>(file), s);
例えば、 namespace HOKJELKDSLKHLKFJHLEBIFBSDIF { class X { public: int x; X() : x(0) { } }; } という名前空間とクラスがあったとします。 この X を使いたい場合に、この長たらしい名前空間を何度も書きたくないので namespace A { using namespace HOKJELKDSLKHLKFJHLEBIFBSDIF; void foo(X x); } と、「ヘッダファイル内に」書いたとします。 すると、 int main() { A::X x; A::foo(x); } のように、仕様上 A::X として使えるようになってしまいます。 エイリアスを使っても、そのエイリアスが外部で使えてしまいます。 A の名前空間を通じて X を参照できないようにし、 なおかつ foo の X などであの長い名前空間を使えないようにする方法って 何かないんでしょうか?
age 忘れ
1つ条件を忘れていました。 A の外で using するのもダメです。
ヘッダに書くなよ
ヘッダでusingしない もしくはusingをまったく使用しない
つまり、やっぱり「どうしようもない」ってことでしょうか?
名前空間をインポートするusingを使っておきながらそれを無効にしたいなどというのは矛盾もいいとこなのでどうしようもない
#define HOKJELKDSLKHLKFJHLEBIFBSDIF A つーか、秦でいいよ。手抜きするな。
ヘッダ書くのは楽したいけど、 インポートしたい訳ではないんです。 ヘッダを書くのを楽するためには using しないといけないけど、 インポートしたくないので using はしたくない、ってことです。 だから何とかしたかったのですが、 #define〜#undef がせいぜいということのようですね。 できればマクロも使いたくないので 大人しく手抜きせずに書く事にします。 その namespace ブロック内でのみ有効な using とかあればいいんですけどね...。 そもそも全部 public なのが(ry
なんか昔「仮想を切る」とかデンパなことを言ってたやつ?
>>671 何ですか? それは。
まぁ、vi しか使えない環境に放り込まれたら
あなたたちもそういう機能が欲しくなりますよ。きっと。
viの置き換え機能で後で一気に長い名前に置き換えればいいじゃん。
>>673 なるほど。それはいいですね。
あとで整形する必要はありますけど。
ところで、長くなってくるとソースが見づらくなると思うんですけど、
みなさんどうしてますか?
>>661 こんな俺を見捨てずにありがとうです。
やってみたらうまくいきました。
それどころか、
void mygetline(ifstream& file){
string s;
getline((ifstream&)file, s);
cout << s << endl;
}
でもコンパイルとおっちゃいました。キャストとるとだめです。
なんじゃこりゃーですが、もう、抵抗するのやめます。
いろいろ教えてくれたみなさん。ほんとに、ありがとです。
>>654 カコイイ!
俺も改良版考えました。
16桁以下ならOK。で、安全。
#include <iostream.h>
void main(void){
char binary[17];
cin.get(binary, 17);
int sum = binary[0] - '0';
for(int i = 1; binary[i] != '\0'; i++){
sum <<= 1;
sum += binary[i] - '0';
}
cout << sum << endl;
}
677 :
デフォルトの名無しさん :03/05/29 23:53
VC++でDWORDとBOOLがコンパイルエラーを吐くんだけど、 DWORDとBOOLってunsigned long(だっけ?)とboolに変えないとだめ?
> VC++でDWORDとBOOLがコンパイルエラーを吐くんだけど、 どんな?
>>678 スマソ。
error C2065: 'BOOL' 定義されていない識別子です。
みたいな感じです。
とりあえず試しに、hello worldを元に #include "stdafx.h" int main(int argc, char* argv[]){ BOOL a; printf("Hello World!\n"); return 0; } って書いてみたんですが、これもコンパイルエラーでした。
>>680 stdafx.h 内で
#include <windows.h>
を
>>662 ↓これじゃだめ?
namespace A {
namespace short_name = HOKJELKDSLKHLKFJHLEBIFBSDIF;
void foo(short_name::X x);
}
684 :
初心者プログラマー :03/05/30 00:54
>>684 ここ含めて5箇所にマルチポスト。
その内2つがスレ立て。
> report2-3.c 頼むから夜中に爆笑させないでくれえ〜。
>>682 A::short_name が外から使えてしまうのが
ちょっと気持ち悪いんです。
>>687 んなこと言ったら、HOKJELKDSLKHLKFJHLEBIFBSDIFが使える時点でダメなんじゃねーの?
>>688 HOKJELKDSLKHLKFJHLEBIFBSDIF::hoge が
A::short_name::hoge としても使えるのは気持ち悪くありませんか?
namespace ___HOK = HOKJELKDSLKHLKFJHLEBIFBSDIF;
とか、「外部で使わないでー」というお願いを込めた名前にする、
というのならまだ使えるかも?
番号間違えました。
>>689 じゃぁboostにちなんでdetailの中でコソコソやっとけ。
>>662 ヘッダファイルでusingを使うのは行儀が悪いのでやめた方がいい。
名前空間の名前を短くするか、そうでなければ全部書いてください。
コピペ使えばどうってことのない手間でしょう。
# どうでもいいが「名前空間の名前」って言い方はちょっと変か……
>>692 レスありがとうございます。
>ヘッダファイルでusingを使うのは行儀が悪いのでやめた方がいい。
非常に同感です。
使ってみて、強く実感しています。
>名前空間の名前を短くするか、そうでなければ全部書いてください。
>コピペ使えばどうってことのない手間でしょう。
エイリアスを使おうが、元の名前を短くしようが、
結局 using を使わない以上何らかの NAMESPACE:: を書かないといけないんですよね。
大人しく書く事にします。
694 :
デフォルトの名無しさん :03/05/30 21:07
下のプログラムを組んでみて疑問がありまする。 基底クラスのインスタンスを渡しているのに、派生クラスにキャストすると 派生クラスのメンバ関数foo2が呼べるのはなぜですか?(最初は落ちるかと思ったんだけど…) #include <iostream> class A { }; class B : public A { public: void foo(A* a) { B *b = static_cast<B*>(a); b->foo2(); } void foo2() { std::cout << "B::hoge()" << std::endl; } }; int main(int argc, char* argv[]) { A a; B b; b.foo(&a); return 0; }
>>694 もしBにメンバ変数の追加があって、そのfoo2がそれを参照してるならやばいよ。
たまたまBで拡張された部分をアクセスしない関数だから大丈夫なだけ
696 :
デフォルトの名無しさん :03/05/31 09:07
std::mapから、要素を完全に取り除きたい場合はどうすればいいですか。 std::map<std::string, long> testMap; testMap["111"] = 111; testMap["222"] = 222; testMap["333"] = 333; testMap.erase("222"); こうやって要素を消しても、iteratorでmapをなめると、"222"をキーに持つ要素が出てきてしまいます。
悪質な釣り師見参
698 :
動画直リン :03/05/31 09:13
すみません。勘違いしてました。 ちょっと別の質問なんですけど、mapの要素に対して[]を使ってアクセスすると、 なぜか要素のコンストラクタが呼ばれるようです(find()では呼ばれない)。 これってどういう事でしょうか。mapの要素に[]でアクセスするのは効率が悪いんですか?
700 :
デフォルトの名無しさん :03/05/31 13:05
700
>>699 > ちょっと別の質問なんですけど、mapの要素に対して[]を使ってアクセスすると、
> なぜか要素のコンストラクタが呼ばれるようです(find()では呼ばれない)。
なぜって、仕様読んだのか?
[]は新しい要素を代入することが出来る。
> これってどういう事でしょうか。mapの要素に[]でアクセスするのは効率が悪いんですか?
効率が悪いとしたら、使い方が間違っとる。
>>701 だから、例えば
std::map<std::string, CMyClass> theMap;
theMap["test"];//追加される
theMap["test"];//参照
theMap["test"];//参照
という感じで、追加されるのは最初の一回目だけで、後は参照するだけ
だと思っていたんですが、二回目以降もCMyClassのコンストラクタが呼ばれてます
theMap["test"]
theMap.find("test");
theMap.find("test");
こういうやり方ならコンストラクタは一回しか呼ばれません
Cを飛ばしていきなりC++始めたいときは、やっぱり「やさしいC++」を読むのがいいんでしょうか?
>>702 operator[] が
return insert( make_pair(key, val()) )->second
で実装されてる環境(VC6,7,Bcc5など)だと二回目以降も
デフォルトコンストラクタがよばれるし、
iterator i = find( key )
return ( i != end() ? return i->second : insert( make_pair(key, val()) )->second);
と実装されてれば(gcc3など)一回しか呼ばれないし。処理系による。
>>706 え!!operator[]ってそうだったの!?
じゃあ確実に参照だけしたいって場合はfind()->secondするのが良いんですね
わかるりましつ
708 :
デフォルトの名無しさん :03/05/31 15:35
wchar_tってのがあるじゃないですか。例えば、 >wchar_t wt[256]; >_wcspcpy(wt, L"あ あ あ"); こういう使い方。 この場合、wtの中身は、UTF-8ですか?UTF-16ですか?
文字コードは処理系や環境に依存すると思うけど・・・
>>708 まずUTF-8みたいなマルチバイトではないだろうが
UTF-16かどうかは実装依存
Visual C++だとUCS-2, glibcだとUCS-4とかじゃなかった?
すげー、レス嬉しい
>>709 >>710 じゃあぁ、コンパイラ調べれば分かりますね。ちなみにBCBでつ。
DBにUNICODE入れようと思うのですが、UTF-8/16混在させたら読むに読めないから怖いですね。
UCSってのが何か良く分からないです。
>>712 あ、そうなんだ。
じゃぁ、DBにはUCS-2で入れといて、
HTMLなんかにするときにUTFに変えればよさげ、
と思ったが自信無い。
UTF-8/UTF-16 使うと、既存の W_Char 用関数が全滅するので、結構大変だよ。 今までは 16bit/2byte 渡せばすむところを、w_char のポインタを渡さなきゃいけなくなったり。
>>714 既存とはCの基本ランタイムwfopenみたなヤシですか?
まじー?
getc あたり、どうなると思う?
wfopenって初耳
wifstream, wofstream のコンストラクタも wstring でファイル名を 受けてくれればいいのに。
正直、UTF8/16/32, UCS-2のどれが良いのかわけわか。
720 :
デフォルトの名無しさん :03/05/31 20:07
結構調べたんですけど、stringstreamのバッファのクリアの仕方がわかりません。 まったくお恥ずかしい限りです。
std::stringstream x; x.str( std::string() );
>>721 アリガd
もう1つ
どうしてx.str( std::string("test") );
はダメなんですか?
>>724 あーーそうかstringstream::str("test")はポインタ進まないのね(汗)
ダメだと思った理由はご想像にお任せします。
関数の引数のデフォルト値を途中だけ設定することが出来ないですが、 何故そういう仕様になってるのかよく分かりませんでした。 int f(int, int = 3, int); と宣言して、 f(3,,4); //OK f(,,4); //デフォルト値なしの引数が省略されているのでエラー となるような仕様では何故駄目なんでしょうか?
>>726 デフォルト引数を利用する場合
基本的には引数を省略する場合が多いんで、
途中に余計なコンマを書くよりは、
何も書かないでいいようにした方が効率的で分かりやすい。
デフォルト引数が複数ある場合には
f(3, , 4); というように指定したいと思う事もあるけど、
コンマの個数が増えてくるとソースが読みにくくなるし、
コンマの個数を間違えるとバグになるというのも困るので、
省略できないのも仕方が無いとも思う。
個人的には、名前付き引数があればええんでないかな、と思うのだが、
まぁ、無いものは仕方が無い、と。
デフォルト引数とオーバーロードを一緒に扱いたかったから、違う?
VC使っていますが、仮に class A { A(int i) {} }; class B { A m_cA[8]; }; としたとき、B::m_cAを初期化するにはどうすればよいでしょうか。
731 :
デフォルトの名無しさん :03/06/01 20:45
>730 なるほど、この構成自体がコンパイル通らないのですか。 情報感謝です。
>>729 配列の各々のオブジェクトに、違った初期化をする方法で
cinからもってくる方法がストラウストラップに載ってるね(p.300-301)。
まぁここまでするのもね。
735 :
デフォルトの名無しさん :03/06/01 21:53
C++の構造体とクラスの差について、 構造体は ・アクセス修飾子が無い。 ・メソッド、コンストラクタ、デストラクタが定義できない。 以外に何かありますか?
> 構造体は > ・アクセス修飾子が無い。 > ・メソッド、コンストラクタ、デストラクタが定義できない。 そんな差は無い。
C++は構造体でもメソッドもコンストラクタもデストラクタは定義できます。 アクセス修飾子もあります。 クラスとの違いはデフォルトの アクセス修飾子がprivateかpublicかの違いのみです。
738 :
デフォルトの名無しさん :03/06/01 21:56
structはCとの互換性を考えてデフォルトをpublicにしているの?
関数オブジェクトを簡単に書けるように
オブジェクト指向的には構造体とクラスは別物。 C++ はほぼ同等の扱いにしてるけど。
何かの本で著者がstructとclassを使いわける俺ルールを書いてて それに共感を覚えたんだけど、どういう決まりだったかすっかり 忘れてしまったな。
構造体はただの複数のデータの塊(のための型)。 変数を一度に沢山定義して、 それを一度に受け渡しするためのものに過ぎない。 一方クラスは具体的にどんなメンバ変数があるかは隠蔽しちゃってて、 使う側からは、どういう種類のデータを扱えて、 どういう機能を持っているかさえ分かっておけばいいようになっている。 つまり、データの抽象化を行ったものがクラスと言える。 メンバ関数を通してデータを扱う場合と言ってもいいかもしれない。 でも、ポリモーフィズムとかも重要な性質だろう。 C の FILE 構造体はクラスみたいな使い方をしてるけど、 これは C にはクラスがなかったからこうしてるだけ。 こういうのは、オブジェクト指向言語ではクラスにすべきだろう。
値として振舞うか、仕組みとして振舞うかの違いもあるよーな気がするのう。
「オブジェクト指向的には」とか言ってるけど、 Cの構造体、C++の構造体、C#の構造体みたいに、 狭い範囲でそれぞれ意味が定義されてるもんじゃないの? オブジェクト指向という括りで通用する構造体の定義ってあるの?
単なるデータストアか、オブジェクトとしての振る舞い(もしくはロール) をもつかで区別すりゃいいんでないかね。
748 :
デフォルトの名無しさん :03/06/02 18:23
#include<stdio.h> #include<math.h> #include<conio.h> main(){ float a,x,b,x1; printf("入力→"); scanf("%f",&x); for(;;){ a=exp(x)-3*x; b=exp(x)-3; x1=x-a/b; if(fabs(x1-x)<0.0000001)break; x=x1; } どこがおかしい?
#include<conio.h>
スレ選び
}が足りない。
#include<stdio.h>#include<conio.h>#include<math.h> main(){ float a1,a2,X=0,x=0,x1=4,x2,s=0,b,i,s1; printf("分割数入力\n");scanf("%f",&b); printf("α0入力→\n");scanf("%f",&a1); printf("α1入力→\n");scanf("%f",&a2); for(i=1; i<=b; i++){x=x+(1/b); x2=(a1*a1)+(x*x)/(1+exp(x)); s1=((x1+x2)*(1/b))/2;x1=x2;s=s1+s; }for(i=1; i<=b; i++){X=X+(1/b);X2=(a2*a2)+(X*X)/(1+exp(X)); S1=((X1+X2)*(1/b))/2;X1=X2;S=S1+S; } ごめん。こっちだった。
プリプロセッサ命令は一行にひとつ
大文字小文字を区別できないお前の頭 とでも言って欲しいのか?
なんか、強力なデムパが… パナウェーブの仕業か!
質問です。 内容としては、ストラウストラップの10章の部分なんですが、 大域・名前空間オブジェクトの順序依存はさけるべきだという 話があって、で初回スイッチというテクニックが紹介されて いました。オブジェクトが0かどうかをチェックしていますが、 これは、どういうことなんでしょうか?0だとどうで、0じゃないと どうなんでしょうか?そもそも順序依存とは、オブジェクトが確保 されたかどうかですか?それとも初期設定されたかどうか?
>>756 読まずにレス。静的なポインタ変数をぬるぽと比較してると見た。
ストラウストラップの10章って何のこと? あの人の書いた本で、ストラウストラップ本とか言われてるのがあるの? # お、ググったら1件だけあった>ストラウストラップ本
>>758 "Stroustrup本"でググったらもうちょっとでてきたぞ
class Hanage { enum hanage_len_t{ LONG, SHORT }; const hanage_len_t length; Hanage( hanage_len_t l ) : length( l ) {} }; こんなクラスがあるんです。このクラスのインスタンスを作るには Hanage hanage(Hanage::LONG); だとか、 Hanage* pHanage = new Hanage( Hanage::SHORT ); なんて書きますよね。 ここで、この Hanage::LONG の Hanage:: の部分が、 Hanageのインスタンスを生成しまくる場面ではすごくめんどくさいのです。 たとえば、 class HanageGenerator { using class Hanage; // ←こんなのを書いて Hanage** Create( int n ) { Hanage** buf = new Hanage*[n]; for( int i = 0; i < n; i++ ) buf[i] = new Hanage( i % 2 ? LONG : SHORT ); // ←これ!Hanage::の省略! return buf; } }; こんな風に書けたら素敵だなぁ、って思うのです。 で、これ-----Hanage::の省略----の実現方法を知ってる人がいたら 教えてくださいませ。
面倒っても、new Hanage(HANAGE_SHORT)とかやるのと大差ないと思うにょ。
>>760 namespace hanage { } で囲み、
enum hanage_len_t はクラスの外でこのnamespace内に移動すれば
using namespace hanageでできないこともないが、美しくはないか
あ、ストラウストラップとはプログラミング言語C++(第3版) のことです。すんません、わかりづらかったようで。 で、その10章のラストにアドバイスとして次のようなことが書かれて います。 ・大域、名前空間内オブジェクトを構築するときには、順番への依存を避けよ。 ・順番への依存を抑えるためには初回スイッチを使え。 この順番への依存とは何の順番なんでしょうか。まぁたとえば静的メンバ をもつクラスが大域スコープで定義された時のように、ある大域オブジェクト が他の大域オブジェクトを参照する時のことなんでしょうが、これは要するに 参照しようとした時に、まだ使えない場合があるということなんですかね。 それとも初期設定がされてるかどうかって話なんでしょうか。 10章で紹介されている初回スイッチ(よく使われる戦略だそうで)ですが、 bool型の静的メンバをもつクラスのメンバ関数で、その静的メンバがfalseか どうかをチェックしています。falseならtrueをセットして初期設定してる ようです。この手法はコンストラクタがない静的オブジェクトが0で初期設定 されることを利用しているということだそうですが、falseの時はどいう時で trueの時はどいう時なんでしょうか?(ってわかりづらくてすんません)
> 順番への依存とは何の順番なんでしょうか 大域オブジェクトの初期化の順番は処理系依存 > 初回スイッチ シングルトンの実装方法を見れば判ると思う
>>763 なんでそんなことも分からないのかが分からない。
初期化してないときがfalseで初期化済みがtrueに決まってるだろ。
bool型の静的メンバの名前が「initialized」だし。
>参照しようとした時に、まだ使えない場合があるということなんですかね。
>それとも初期設定がされてるかどうかって話なんでしょうか。
まだ使えない=初期設定がされてない なので言ってる事がトンチンカン。
レスどうもです。 順番とは初期化のことなんですね。じゃ、とりあえず 初期化されてなくても、参照はできるということは 保証されてるってことですね。うーむ。ということは 大域オブジェクトに何か値をセットするような関り方を している場合、値をセットした後、0にもどされるって 場合があるってこと?こんがらがってきた・・・。 シングルトンですか・・・なんでしょうかそれは。
> 参照はできるということは保証されてるってことですね。 逆。 初期化されていないオブジェクトを参照できるから、危険。 シングルトンはデザインパターンの本を見れば書いてあるよ。
あ、もちろん安全という認識はないんですが、 言ってることは間違ってないですよね? そうですか。ちょっと本を探してみます。 ありがとうございました。
初期化って0クリアのことを指してたの? てっきりコンストラクタ呼び出しのことかと思ってた・・・ それから、初期化時のコンストラクタ呼び出しの順序だけじゃなくて、 mainを抜けた後のデストラクタ呼び出しについても、同様の問題が 起こりうることは覚えておいたほうがいいと思う。
> デストラクタ呼び出しについても、同様の問題が おこらねーだろ。
>>770 デストラクタ呼び出し後のオブジェクトを参照する場合。
Stroustrup本見てみたけど訳分からんね、これじゃ。 理解する気失せるわ。やっぱいろいろと不親切な本や。 Effective C++の47項を見るか、あるいはSingletonパターンでいいと思う。
>>760 とりあえず、 Hanage::hanage_len_t は Hanage::len_t のようにすべき。
で、
inline Hanage* create( Hanage::len_t len ) { return new Hanage( len ); }
こんなやつを定義すると、ナントカ参照という仕様により
Hanage* p = create( Hanage::LONG );
と書ける。
あからさまに冗長な new Hanage( Hanage::LONG ) よりは読んでて気持ちいい。
でも、実用はお勧めできない。
>>766 0クリアはされないかと。
コンストラクタ以前にスタートアップコードのあたりで0クリア済みじゃない?
初期化ってのはコンストラクタが呼ばれること。
0クリア云々のくだりはbool型のinitializedのことで、他のクラスの事じゃない。
false==0ってことは理解してる?
initializedが最初の実行時は必ずfalseだから、それで初期化済みか判定して
いるってこと。
で、例の本にもデストラクタの問題も書いてあって、解決法としてatexit()と
参照カウンタをチョロっと紹介してる。
>>772 あの本はテクニックを解説する本じゃなくて、C++の言語仕様を説明する本だから
Singletonなんてあの程度の解説で十分かと。
逆に言語仕様と関係ない部分ばかり説明されても困る。
ただでさえ分厚い本なんだし。
756が何でこの本を読んでいるのかはちょっと疑問。
これは入門書じゃないぞ。
776 :
デフォルトの名無しさん :03/06/04 23:01
age
オブジェクトをファイルに保存、復元したいんだけどこんなんでいいの? VC++のデバッガでは出来てるっぽくみえたんだけど #include <stdio.h> #include <string.h> class CLS_A{ char m_a[16]; public: CLS_A(){strcpy( m_a, "Test");}; ~CLS_A(){}; }; void main(){ CLS_A *A = new CLS_A; FILE *fp; fp = fopen("TEST.bin", "w"); fprintf( fp, (const char *)A); fclose(fp); delete A; CLS_A *C = new CLS_A; fp = fopen("TEST.bin", "r"); fscanf( fp, (const char *)A); fclose(fp); delete C; }
778 :
デフォルトの名無しさん :03/06/04 23:54
VC++.netでC言語コンパイルできるんでしょうか? C言語の勉強用に買ったんですが、どうやってもコンパイルできません。 VC++を.netで初めて使ったのでかなり試行錯誤してる段階です。 それと.net用の解説書を買いにいったのですが近所のパソコンショップ 数件まわったのですが6.0用のしかありませんでした。 6.0の解説書でも参考になるんでしょうか? 初歩的な質問ですいません。
>>777 fscanf( fp, (const char *)A);
( ´_ゝ`)フーン…
>>778 VC++は知らないけど、
C++なら、Cの殆どのコードはコンパイルできるはず。
というか、「どうやってもコンパイルできません」って書いているけど、
具体的にどうやったんだ?それをまず書け。
781 :
デフォルトの名無しさん :03/06/05 00:22
>>780 rさん
#include <stdio.h>
void main()
{
printf( "〜〜〜〜" );
}
コンソールモード、デバックで開始
するとこれらのプロジェクトは古い形式で構成されてます
と警告気味のコメントがでます。
「はい」をえらぶと6個のエラーがでます
エラーC2018 文字 0x40は認識できませんが3つ
エラーC2018 文字 0x81は認識できませんが3つ
です。
>>781 ん?それコンパイルできるはずだけど・・・。コンソールモードって
プロジェクト立ち上げるときに選ぶやつを言ってるのかな?
まずメニューより[ファイル]→[新規作成]→[プロジェクト]と
進む。[テンプレート]の欄でWin32プロジェクトを選び、
適当なプロジェクト名を入力してOKを押す(保存先変えるなら変える)。
んで[概要]と[アプリケーションの設定]というのがでてくるんで、
[アプリケーションの設定]タブをクリックしてコンソールアプリケーションを
選択して、空のプロジェクトにチェックを付けて完了。
この手順でやってるの?
あ、もしかして printf( "〜〜〜〜" ); って〜〜〜〜の部分をそのまま使ってるんかい(w。 最初はHellow World!って決まってるのに・・・・。 全角じゃなくて半角英数字でも入れてみたら。
Hello が Hellowになってるし(w・・・俺も死んでくる
786 :
デフォルトの名無しさん :03/06/05 00:35
>>782 さん
調べてみたんですが全角スペースは使ってないっす。
解説サイトからひろってきたりしたサンプルソースなども
すべてエラーがでます、、
>781 どう考えても全角スペースぽ >783 べつにそこは〜〜〜でもなんでもよいでわないか。
781のソースはコピペか? だったら全角スペースがみっつ入ってるぞ?
790 :
デフォルトの名無しさん :03/06/05 00:44
>>783 さん
その手順とほとんどおなじっす。
コンソールに変える手順がすこしちがって
左のプロジェクトのプロパティからリンカ→システム
サブシステムから変えてました。
>>784 さん
786でも書いたとおりサンプルソースなど
を貼り付けても全行にわたってエラーがでます。
voidとmainの間が全角スペース printfの前に2つの全角スペースが入ってる
792 :
デフォルトの名無しさん :03/06/05 02:40
クラスの定義する時 class A{ ... } じゃなくて struct A{ ... } にすると何かいい事あるの?
>>792 publicメンバから書きたい場合、public:を省略できる。
>>777 ダメ。
CLS_A の中にファイル書き込み/読み出し用のメンバ関数か
m_a を返すメンバ関数を追加しよう。
あと、
>>779 の言う通り、
fscanf をあーいう風には使えない。
同じく、fprintf もダメ。
fprintf/fscanf じゃなくて fputs/fgets を使おう。
>>781 0x81 0x40 は全角スペースの文字コードです。
確実に全角スペースが原因です。
あと、いきなり実行するのではなく、
ビルドしてから実行しましょう。
797 :
デフォルトの名無しさん :03/06/05 16:32
>>792 俺はソースの可読性
template<typename T>
class trait
{
public:
/**/typedef T result;
};
これより
template<typename T>
struct trait
{
/**/typedef T result;
};
こちらの方がなんか良くない
>>797 漏れは
class C {
int n;
};
よりも
class C {
private:
int n;
};
の方がなんか良いと思ってるから賛同しかねる。
つか、/**/ってなに?
そゆコーディングスタイルなの?
int i=4,o=5; int *_=&i; (*_*o);
ここで聞いて良いのかどうかわかりませんが教えてください。 整数を返す、rand()の代わりになる関数を作ろうとしています。 条件としては、 ・乱数の周期がそれなりに長い。 ・CPUのタイプに依存しない(浮動小数点を使うのは×) ・再現性がある。前回GetRand(5/*key*/) = 123だったときは、次もGetRand(5) = 123である必要がある。 ・iterateしなくてもいい。int GetRand(int inKey)のように、前回の結果が必要でなく、キー(種)さえ与えればいつでも値を得ることが出来る。 乱数発生に詳しい方、お願いします。
boostの乱数ライブラリを使う。
って良く読んだらそういう話じゃないし。
>>802 それって、つまり同じ値は一回づつしかでない、循環する数列を生成するってことかね
int GetRand(int inKey) { srand(inKey); return rand(); } ・再現性がある。前回GetRand(5/*key*/) = 123だったときは、 次もGetRand(5) = 123である必要がある。 ・乱数の周期がそれなりに長い。 この2つが重なるのが全然意味わかんないんだけど。乱数なめてるだろ?
>806 そーゆーGetRandにとって、周期って何の意味があるんだろね? int-intの写像としか思えないが、、
808 :
デフォルトの名無しさん :03/06/05 20:59
>>806 「周期が長い」というのは、
GetRand(0) = 11
GetRand(1) = 22
GetRand(2) = 33
GetRand(3) = 44
GetRand(4) = 11
GetRand(5) = 22
と、簡単に値が繰り返すようでは困る、という意味で書きました。再現性がある、というのは別問題だと思います。
例えば円周率を思い出してください。小数点の値が繰り返しパターンになることはありませんが、少数第2位はいつ見ても「4」です。
何がしたいのかわからん
> 例えば円周率を思い出してください。小数点の値が繰り返しパターンになることはありませんが、少数第2位はいつ見ても「4」です。 当たり前だろ? 円周率を示す数値は一つしか存在しない。
>>806 >srand(inKey);
>return rand();
これで「再現性がある」というキミは天才。
再現性のある周期の長い乱数でキーを選ぶ
昔のBASICの「RANDOMIZE」みたいなことをやりたいんちゃう? C++の乱数にしたってどうせ擬似乱数に過ぎんのだし、 同じようなことは出来るんじゃないの?
>>810 だから、GetRand(5)とすれば、円周率の少数第5位を返すような関数が欲しいんです。
あと処理系依存するのも駄目です。IntelのチップでもAMDのチップでも、同じキーを与えたら同じ答えが返ってくる必要があります。
なので、浮動小数点の計算や、乱数表を使うやり方はいけません。
>>811 ?
#include <iostream>
#include <cmath>
using namespace std;
int GetRand(int inKey)
{
srand(inKey);
return rand();
}
int main()
{
for(int i=0;i<50;i++)
{
cout << GetRand(i%5)+1 << endl;
}
}
これで再現性が無かったらどうやったら再現性がある事になるんだろう…
>>815 コンピュータによって持ってる乱数表が違う。
×cout << GetRand(i%5)+1 << endl; ○cout << GetRand(i%5+1) << endl;
じゃあもう自分で乱数表作るしか
>>816 乱数表持ってる実装のrandがあったら教えて下さい。
>>818 さっきから乱数表とか言ってる香具師は馬鹿ですか?
Portableじゃなきゃいけないなら自分で線形合同実装したら?
int GetRand(int seed)
{
seed = seed * 1103515245 + 12345;
return ((unsigned int)(seed / 65536) % 32768) & 0xff;
}
>>821 自分が馬鹿なのを思い知らされたからってネタに走るのは止めて下さい。
何かいいアイディアありませんか。カオスを使うのは小数点の計算に誤差が出るので使えないんです
>>820 おおっ それは何ですか
ぐぐった時に名前だけは見たんですが>線形合同
それで常に変化する値が取れるんですか
>>824 rand()のソース見たら大抵それが書いてあります。
でもintが何bitかによって結果変わるから完全にPortableではない。
つーか全然C++じゃないだろCスレに帰れよお前ら
そうだな。 レベルの低い話はCスレでやれ。
>>827 Cでもないだろ。アルゴリズム系スレか?
>>828 簡単に釣れたな。つーか理解できないならお前帰れよ。
数学板へ
厨房しかいないなこの時間
>>826 なるほど〜、そうでしたか。動かしてみたんですが、十分変化する値が取れるようになりました
intはまあ、今の所32bitの環境でしか動かす予定が無いのでOKです
ありがとうございまし
た。
MT使え、MT。
>837 その場合、 unsigned long GetRand( unsigned long mt[624]) になってしまうとおもうぞ
そもそも真っ当な乱数アルゴリズムの殆どは > ・乱数の周期がそれなりに長い。 > ・CPUのタイプに依存しない(浮動小数点を使うのは×) > ・再現性がある。前回GetRand(5/*key*/) = 123だったときは、次もGetRand(5) = 123である必要がある。 > ・iterateしなくてもいい。int GetRand(int inKey)のように、前回の結果が必要でなく、キー(種)さえ与えればいつでも値を得ることが出来る。 の条件を既に満たしていると思うんだが。
最後の一項目はアルゴリズム選ぶかな
まさか
>>834 は
>>820 をこういうふうに使うつもりか?
for (i = 0; i < N; i++) {
x = GetRand(i);
;
}
乱数ってローカル時間から作るんじゃないの?
↑多分ネタレス
845 :
デフォルトの名無しさん :03/06/05 23:35
しつもんです。 std::vector<int> vec; vec.push_back(1); vec.push_back(2); vec.push_back(3); int* p = &vec[3]; vec.erase(vec.begin()); こうやった場合、もうpの値は保証されないんですか?
846 :
デフォルトの名無しさん :03/06/05 23:37
× int* p = &vec[3]; ○ int* p = &vec[2];
p == &vec[3] *p == vec[3] は両方とも保証されない。
848 :
デフォルトの名無しさん :03/06/06 00:29
>>848 要素を指すイテレータについての保証は規格化されてるが、
ポインタについては何も保証が無いと思われ。
850 :
デフォルトの名無しさん :03/06/06 00:41
>>849 あらいがとうございます、わかるました。
thx!
>>779 >>795 こんな感じ?
class CLS_A{
char m_a[16];
public:
CLS_A(){strcpy( m_a, "Test");};
~CLS_A(){};
void m_put(FILE *fp);
void m_get(FILE *fp);
};
void CLS_A::m_put(FILE *fp){
fputs( m_a, fp);
}
void CLS_A::m_get(FILE *fp){
fgets( m_a, sizeof(m_a), fp);
}
>>820 seed には unsigned int 使おうよ。
seed * 1103515245 の結果がおかしくなるよ。
>>834 符号なし32bit整数なのを保証するために
typedef unsigned int randseed_t; とか typedef するといいかも。
環境によって定義を切り替えればいい。
尤も、CHAR_BIT が 9 な環境のことまで考えるとアレだけど、
普通はそこまで考える必要はない。
まぁ、それでも seed を毎回 0xFFFFFFFF でマスクすればいいかね。
>>851 そんな感じ。
で、いくつか補足すると、
1. 関数定義の { } の後にセミコロンは付けない。
2. m_a の初期化は
CLS_A() : m_a("Test") { }
とした方が良い。
なぜなら、strcpy だと初期化する文字列を変えてみたときに
m_a のサイズを超えていてもコンパイルできてしまうから。
3. メンバ関数名には普通 m_ を付けない。
>>853 > 3. メンバ関数名には普通 m_ を付けない。
おいおい、こいつどこから紛れ込んだんだ?
>>854 メンバ変数名じゃなくてメンバ関数名だってことに気付いてる?
つけたってええやんけー!
>>856 何のために他のメンバ関数や普通の関数と
名前空間が分かれてるのか分からんやんけー!
いや、メンバ関数は余計だった。 普通の関数と名前空間が分かれてる、の方だけで良かった。
859 :
デフォルトの名無しさん :03/06/06 08:09
俺はクラス設計でメンバー変数にすらm_は付けん.
ビル・ゲ@ツに洗脳された人がm_なんてつけるんだ。
>>858 の言うようにもし必要になったらどうせ限定子つけるから。
エスピーなんとかに洗脳されて メンバ変数のsuffixに_を付けるようになりました。
メンバ関数に付けるのは見たことないなあ メンバ変数はアリだとは思うが、 最近実装しないからどうでもよくなってる・・・
directx9でプログラムを作ってみたのですが d3drm.libというのを開くことができないという エラーがでるのですがなぜでしょうか?
>>849 え、マジっすか?
手元の「C++標準ライブラリ チュートリアル&リファレンス」
って本には
要素の挿入や削除が行われても他の要素のポインタ、参照、反復子は無効にならない。
と書かれているのですが・・・
>>864 vector で実験してみろ。サイズが2倍に拡張された瞬間に死ぬから。
list、連想コンテナなら大丈夫だと思った。
dequeはしらん。
848 名前: デフォルトの名無しさん 投稿日:03/06/06 00:29
>>847 listなら保証されますかね
849 名前: デフォルトの名無しさん 投稿日:03/06/06 00:38
>>848 要素を指すイテレータについての保証は規格化されてるが、
ポインタについては何も保証が無いと思われ。
で、vectorで実験してみろとは如何に?
くだらない質問で悪いけど (0=A、1=B、2=C…)っていうような数字に対応したアルファベットを得たいとき sprintf(buffer, "%c", (char)('A'+num)); で何か不都合な点はある?
sprintを使う意味が見えないが。 *buffer = char('A' + num); じゃダメなのか?
>868 いや、一文字だけでない場合もあるんで… とにかくありがと
#defineの以下のような使い方ってできるのでしょうか? #define Encode(n) (10000 + (n)) #define BEER 1 #define SAKE 2 #define LLBEER Encode(BEER) // ←これ #define LLSAKE Encode(SAKE) // ←これ
>>867 charにキャストしてもintに戻されるね。
>>869 for(int i=0; i<len; i++) {
buffer[i] = char('A' + num[i]);
}
sprintよりこっちの方が速い。
*buffer = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[num]; の方が26倍安全です
>>873 安全性はnumの範囲に依存するんだから同じだろ。
Cスレ状態?
移植の安全性の話をしてるんじゃないの?
877 :
あらしって馬鹿だね :03/06/06 18:21
878 :
デフォルトの名無しさん :03/06/06 18:32
マーチンの法則を用いてπ(円周率)を小数以下10000桁まで求める プログラムをC言語で作成してください。お願いいたします。
>>859 ソースを自分しか見ないのならそれでいいだろうけど
880 :
デフォルトの名無しさん :03/06/06 22:49
for(int i=0;i<10;i++){ str[i] = ""; } という文を書いたのですがエラーがでます 参考書が手元になく、調べることもできません エラーの原因を教えてもらえないでしょうか ちなみにChar型でstr[10]と宣言しています
881 :
デフォルトの名無しさん :03/06/06 22:49
>>880 char *str[10]と定義すればOK
エラーの原因を聞きたかったのか。 Char -> charと置き換えて・・・ str[i]の型はcharでしょ?""(文字列リテラル)が返す型はchar *だから合わない。
883 :
デフォルトの名無しさん :03/06/06 22:53
>>881-882 解説ありがとうございます
課題をやっていたのですが、エラーの原因がわからなくって詰まってました(;´Д`)
これで続きができますヽ(´ー`)ノ
>>883 ひとつ聞くけど、なにをしたいの?
多分881じゃやりたいことを達成できないと思うんだけど。
>>884 デフォルトコンストラクタで配列の中身を初期化しようとしてたのですが
これじゃぁ不十分なのですか?
Cスレ池っと言いたいヤシの数→(∞) std::string使えよ…
>>885 もしかしてCharってcharの間違いじゃなくて、自分でつくったクラス?
888 :
デフォルトの名無しさん :03/06/06 23:02
多分これがやりたいんだろ?ちゃんとCから勉強しろ。 for(int i=0;i<10;i++){ str[i] = '¥0'; }
>>886 C++はじめたばかりなのであまりよくわかってません(;´Д`)スミマセンスミマセン
どういうことなのでしょうか?
>>887 変換ミスです(;´Д`)charです
>>885 memset使え つーか長さ0の文字列にしたいなら先頭str[0]に'\0'を入れればよし。
・・・・全然C++らしくねぇ
891 :
デフォルトの名無しさん :03/06/06 23:47
More exceptinal C++ の マクロの所の ERR_ENTRY ってどう書けばいいんですかね? で、どうやって使うんだろう? 文の意味があんまり読み取れなかったからよくわかんなかったんだけど。
テキストファイルから一行ずつstd::stringに入れて読み込みたいのですが どのようにすればできますか?どなたかポインタだけでもお願いします。
getline
>>892 ポインタというところにツッコみたくてうずうずする。
std::string str;
std::getline(file, str);
>>894 ,895
できますた。ありがとうございました。
>>891 <errcode.h>
#ifndef ERR_ENTRY
#define ERR_ENTRY_BEGIN enum Error {
#define ERR_ENTRY(code, value, str) code = value
#define ERR_ENTRY_END };
#endif
ERR_ENTRY( ERR_OK, 0, "No Error" ),
以下略
<errcode.cpp>
#define ERR_ENTRY_BEGIN
#define ERR_ENTRY(code, value, str) lookup.insert( make_pair(code, (const char*)str) )
#define ERR_ENTRY_END
void init_map() {
#include "errcode.h"
}
ってことじゃないのかと思ってたのだけどどーだろ。
899 :
デフォルトの名無しさん :03/06/07 00:51
シングルdクラスのインスタンスって delete をしていいものなんでつか? しない場合はメモリリークと 考えていいのかな? staticにするやつをオートポインタにしとけばOK? なに言ってるか自分でもよくわからん・・・
>>899 ・onexitを使う。
・インスタンスを静的に生成する
等
パターンハッチングのシングルトンについて語ってる所とか読んでみてね。
>>899 意図してないのにアクセスできなくなり、メモリが無駄になる状況がメモリーリーク。
シングルトンは意図してんだからメモリーリークとは言わないのでは?
いや、まあ言いたいことはなんとなく分かるんだけど。 自分だったら気にせずほっとくかな。
++C
>>899 class Singleton {
Singleton() {}
public:
Singleton* GetInstance() {
static Singleton instance;
return &instance;
}
}
これできちんと削除される。
でもなぜかあんまり推賞されてないみたい。
>>903 昔は i++ を使ってた貧弱な坊やでした。
++i を使うとかっこよく、お金持ちで、モテモテになるよということを聞き、
そんなばかな、と思いつつも、
騙されてもいいかと ++i を使うようにしました。
それがなんと ++i を使うようになってからというもの、
メキメキ筋肉がつくわ、競馬で十万馬券が当たるわ、
彼女は出来るわで、人生変わりました!
みんなも ++i で人生の勝ち組になりましょう!
いや、++ 演算子のオーバーロードとかすると
どっちの方を使う癖をつけるといいかがよく分かるよね。
>>905 何かの本かサイトかで推奨できない理由を見た。
確か、instance の生成がロックされてないので
マルチスレッドで問題になる、というものだったはず。
909 :
デフォルトの名無しさん :03/06/07 01:22
>>900 onexit?
・・・・
初耳だと思い、ぐぐったら、単にOnExitのことか・・
>>903 そうだ。たまに++i を
見かけるがなんでだろうと思ってた。
どっちもいっしょだと思い、好みの問題として放置してた。
それが教育的な理由ってなんなの?
>>909 普通の数だと最適化で一緒になると思うけど、
イテレータとかでは ++it の方が効率的な場合も多い。
it++ だとイテレータを進める前のイテレータを生成して、
それを返すことになるからね。
>>910 こんなイイもんがC言語にあったとは・・
914 :
デフォルトの名無しさん :03/06/07 01:36
いいのか?
>>911 組み込み型とイテレータとで表記変えるのは気持ち悪い。
どちらかに統一するとするならやっぱり ++i だろう。
C ならどっちでも好きな方を使えばいいと思うけどね。
うーん・・・イテレータ使うことないしなぁ。
>>905 すまん。実は、クラスのインスタンスを唯一にしたいのではなく
クラスのプライベートメンバ変数を唯一にしたかった。
そんでstatic つけた。
しかしその変数はとあるユーザ定義型のポインタで
終了処理が必要なものであったと。
やっぱクラスで一枚包んどけばいいだけかな。
終了。
>>916 折角C++なのにコンテナ使わないのは非常に勿体無い
>>911 教育的の真意が読み取れないんだな藻前は。
>>898 レスありがd。
それって結局 map を作っちゃうって事?
そのまま書くのに比べて何が利点なのかな?
俺が考えてたのは
<errorcode.inc>
ERR_ENTRY(ERR_OK, 0, "No Error"),
ERR_ENTRY(ERR_INVALID_PARAM, 1, "<description>"),
-以下略-
<errorcode.h>
#undef ERR_ENTRY
#define ERR_ENTRY(name, value, desc) name = value
enum ERR {
#include "errorcode.inc"
};
extern const char* ERR_NAME_TBL[];
<errorcode.cpp>
#undef ERR_ENTRY
#define ERR_ENTRY(name, value, desc) value
const char* ERR_NAME_TBL[] = {
#include "errorcode.inc"
};
<foobarbaz.cpp>
#include "errorcode.h"
int main() {
std::cout << ERR_NAME_TBL[ERR_OK] << std::endl;
return 0;
}
こんな感じかなぁと思ったんだけど、結局配列作っちゃうからマクロな意味が
あんまりないかなと思って。コンパイル時にすべてが解決されるような
いい方法があるのかなぁ?
>>920 本の文脈からすると利点は
ERR_OK = 0 と ERR_OK => "No Error" って対応を
分けて2箇所に書くのは面倒だし間違いやすいから、マクロ使ってコンパイル時に
ソース構造を自動生成させることで、1箇所にまとめることもできる
って意味かと。
エラー値は実行時まで決まらない(コンパイル時定数じゃない)から、
> コンパイル時にすべてが解決される
は無理。
>>905 みたいな方法でのシングルトンはグローバルにインスタンス置くのと何が違うの?
途中で削除できるわけでも無いし、起動時に生成されて終了時に削除されるのも同じだし。
>>922 あの方法では、起動時ではなく、
GetInstance()が初めて呼ばれたときにに生成されるはず
ソースファイル分割した時の初期化順番の影響とかある。 グローバル変数のコンストラクタからメンバー関数呼んでるとまずいことになる可能性があったり。
925 :
デフォルトの名無しさん :03/06/07 21:19
ptrdiff_tはC++独自?Cにはないの?
あるよ
BASE64のエンコード・デコードクラスってないすかねぇ… それらしきものを自分で作ってみましたが、どうも設計がいけてない
928 :
デフォルトの名無しさん :03/06/07 23:40
namespace で特定の関数を見えないようにする方法があれば教えて下さい。
>>928 classのprivate/protected相当ってことだよね。
ない。
.cppだけに書くかさらにnamespace作って混ざらないようにするくらい。
>>930 そうなんです。クラスにしたら全てがstaticな関数になったんで
namespace の方が簡単でいいかな、っと。
ありがとうございました。
iostreamとかのライブラリーって中のクラスがどうなってるみれるの?
>>931 .cpp 内で無名 namespace 内で定義したものは
別の .cpp 内からは参照できない。
static 関数の C++ 版だね。
935 :
デフォルトの名無しさん :03/06/08 00:44
自分のアドレスを返すのってどうすればいいですかね。 この2種類の方法で試みたのですが、エラー出てしまいますい。 SampClass* SampClass::GetAddress(){ return &this; } void SampClass::GetAddress(SampClass* samp){ samp = &this; }
&はいらんだろ
iostreamのクラスがどうやって作られてるか知りたいので ソースがみたいのです
>>937 STLport見ろ。
ただし、規格と実装を混同するなよ。
>>934 やっと理解できました。
ありがとうございました。
940 :
デフォルトの名無しさん :03/06/08 03:08
int main() { A<int> a; } ↑↑Test.cpp↑↑ ↓↓A.h↓↓ #pragma once template<class T> class A { public: A(void); ~A(void); }; ↑↑A.h↑↑
↓↓A.cpp↓↓ #include "A.h" template <class T> A<T>::A(void) { } template <class T> A<T>::~A(void) { } ↑↑A.cpp↑↑ Test error LNK2019: 未解決の外部シンボル "public: __thiscall A<int>::~A<int>(void)" (??1?$A@H@@QAE@XZ) が関数 _main で参照されました。 Test error LNK2019: 未解決の外部シンボル "public: __thiscall A<int>::A<int>(void)" (??0?$A@H@@QAE@XZ) が関数 _main で参照されました。 Test fatal error LNK1120: 外部参照 2 が未解決です。 どうすればいいですか?
テンプレート関数の定義が使用するコンパイル単位に含まれるようにすればいい。
テンプレートつきクラスのメソッドを、クラス定義の外に書くときは、 exportだっけなぁ。なんかキーワードが必要だったとおもうなぁ。
そういやSTL無関係に自前でtemplateなんて使ったことないな
テンプレートはヘッダに全部書くがよろし。
テンプレートつきクラスの場合ヘッダーに実装を書くの普通なんですか?
いまのところ、exportをサポートしているコンパイラが少ないので、普通。
そうですか ヘッダーに書くことにします みなさまありがとうございました
>>938 STLportは古いコンパイラに対応するために色々無理を
しているから、さすがに読ませるのはどうかと思うぞ。
gccのlibstdc++くらいでいいんじゃないか?
ところどころ実装が汚いor間違っている部分があるけど。
(例外まわりとか)
(^^)(^^)(^^)(^^)(^^)(^^) (^^)(^^)(^^)(^^)(^^)(^^) (^^)(^^)(^^)(^^)(^^)(^^) (^^)(^^)(^^)(^^)(^^)(^^) (^^)(^^)(^^)(^^)(^^)(^^) (^^)(^^)(^^)(^^)(^^)(^^) 山崎渉
951 :
デフォルトの名無しさん :03/06/08 17:29
castしないでひょうげんしてみて。 std::istringstream ist(static_cast<std::string>(std::string( (std::istreambuf_iterator<char>(std::cin)),std::istreambuf_iterator<char>()))); もちろんstringを別にしないでだよ。
952 :
デフォルトの名無しさん :03/06/08 18:07
失礼しますた。 VC7コンパイルとおりました。 g++はダメだったもので。
☆ チン マチクタビレタ〜 マチクタビレタ〜 ☆ チン 〃 Λ_Λ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ヽ ___\(\・∀・) < 次スレまだ〜? \_/⊂ ⊂_ ) \_____________ / ̄ ̄ ̄ ̄ ̄ ̄ /| | ̄ ̄ ̄ ̄ ̄ ̄ ̄| | | 愛媛みかん |/
☆ チンチン マチクビタレタ〜 マチクビタレタ〜 ☆ チンチン 〃 Λ_Λ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ヽ ___\(\・∀・) < みかんっておっぱいに似てるよね〜? \_/⊂ ⊂_ ) \_____________ / ̄ ̄ ̄ ̄ ̄ ̄ /| | ̄ ̄ ̄ ̄ ̄ ̄ ̄| | | 愛媛みかん |/
int fun() { vector<int> a; } とか宣言したときにaのデストラクタを明示的に呼べますか? ブロック抜けた時じゃなくて。
a.~vector();じゃなくて?
958 :
デフォルトの名無しさん :03/06/09 06:52
>>955 ちなみそれは宣言ではなく定義ちゅ―のでは。
extern int a; ←宣言というのはこういうのじゃない?
>957だとデストラクタ2回呼ばれると思うので素直に int func() {     vector <int> t1;     {         vector <int> t2;     }    return 0; } とか
だから実体参照にはセミコロンをつけろと(ry
vector<int>& a = *new vector<int>; で、 delete &a;
964 :
デフォルトの名無しさん :03/06/09 16:00
static std::vector<int>* pv; void func(){ pv = new std::vector<int>; pv->push_back(int(10)); } void destroy(){ pv->~vector<int>(); }
こんなことしちゃいけないよ newはdeleteで対応が常識。
966 :
デフォルトの名無しさん :03/06/09 16:17
(´-`).。oO(こういう業者って儲かってるんだろうか…)
968 :
デフォルトの名無しさん :03/06/09 16:38
>>966 みたよ〜♪
ぼくねーグッズ持ってるからねいらないやー。
ちなみにおしり入れるやつね。
儲かってないから手段を選んでいないに決まってるだろう。
カーソル移動の定義のやり方を教えてください(;´Д`)人スンマセン
#define カーソル移動
>>970 カーソル移動ということはカーソルが無くてはいけないな。
このスレは環境依存の話はナシだからきっと自作なのだろう。
ということで、藻前の作ったカーソルを見せてくれ。話はそれからだ。
struct Cursor { POINT pos; // 位置 int bShow; // 表示フラグ }
975 :
デフォルトの名無しさん :03/06/09 18:21
次スレは? ないなら立てるけど。
977 :
v(^・^)v :03/06/09 18:30
>>976 あー、、、やっぱりだめだった。YBBじゃ無理か。でしゃばってスマソ
978 :
デフォルトの名無しさん :03/06/09 18:40
C++ってもう進歩しないの? 言語仕様やライブラリの点で。
979 :
デフォルトの名無しさん :03/06/09 18:49
ちんぽったらそれはC++じゃねーよ
仕様を完全に満たすようにコンパイラに進歩してもらわんとな。 言語仕様いじる以前の問題っぽ。
ライブラリは進歩している。 OWLやらMFCやらQtやらwxWindowsやら、 ただし標準にならないだけ。 おかげでいつまでたってもライブラリ覚えなおすはめに。
そろそろ新しいC++の仕様を策定すべきだね。
もうそろそろCUIライブラリだけじゃなくGUIライブラリを標準に入れたらどうだ?
>>982 ぱっと見た感じ、要するに、boost, loki, C99 辺りの
ライブラリの一部が標準に追加されそうってことかな?
早くtypeofを標準化汁。
早い床shared_ptrを標準に入れてホスィ。
標準化より次スレが先だ。
989 :
デフォルトの名無しさん :03/06/09 21:32
そんまえになぜに標準化にこだわるか 漏れにはわからん。使えるんだから別にいいべ。
>>989 同意
ライブラリなんかどうでもいいからtypeofを速く
ひとえにポータビリティ
typeofハァハァ… ↓次スレは任せた
↑了解だ兄者。
標準に入ってるだけで使いやすさが団地だべ。
標準ソケットクラス作れよ。
MFCを標準規格に入れてくれないかな。
999 :
デフォルトの名無しさん :03/06/09 21:48
いまさらなによ!!!!!!!!!
1000 :
デフォルトの名無しさん :03/06/09 21:48
1
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。