1 :
デフォルトの名無しさん :
2005/04/16(土) 10:54:30 ※回答する人も、質問する人も必ず読んでください これらに当てはまる人のための質問スレです。 1.Cはだいたい理解している。 2.最近C++を始めたばかり 3.入門書を読んでも、Googleで検索しても、いまいち理解できない人 【 回答してくださる方 】 ・ できるだけ優しく質問に答えてあげてください。 ・ 優しく教えるのが嫌でしたら、解決するためのヒントだけでも結構です。 「ググれ」以外の回答でおながいします。 ・ 神ですら理解不能な質問は無視して下さい。 【 質問する香具師 】 ・ どんな事で躓いているのか明確にしる。 ・ 長くならないなら躓いている部分のコードを晒してみれ。 ・ 解決した場合、お礼を言うのは当然だが、何をどうしたら解決したかを明確に書け。
>>1 普通にC++のスレで聞けばいいだろ?
甘えた態度はよろしくないな。
3 :
デフォルトの名無しさん :2005/04/16(土) 12:59:03
3ちしげ3ゆ3様が電光石火の3ゲットなの!
>>1 番かわいいのはさゆなの!
ノノハヽヽ〃ノハヾ /)
>>2 じ本はハゲすぎなの!
後
>>10 は落ち目すぎなの! ∩*・ 。.・)从*・ 。.・)/ミ
〃ノハヾノノハヽヽノノハヽヽつ い
>>4 川は黒すぎなの!
矢
>>9 ちもフケすぎなの!⊂(。.・从(・ 。.・*∩ノノノハ 。.・)ノハヽ
(( (\ゝノノノハノハ〃ハ v)っ彡*・ 。.・)
あ
>>8 やはフケすぎなの! ⊂`ヽ从*・ 。.・)・ 。.・))ノノノハヽつ ))
>>5 んのは顔ふくれすぎなの!
大の大人が
>>7 っちとか(プ⊂\ ⊂ ) _つ从*・ 。.・)
(/( /∪∪ヽ)ヽ)/ U つ モー
>>6 すは売れなさすぎなの!
∪ ̄(/ ̄\) ゝし'⌒∪
>>11-1000 さゆのかわいさの前にひれ伏すの!
4 :
デフォルトの名無しさん :2005/04/16(土) 13:11:28
とりあえず、コメントをC++に移行しますた
1. C++では変数宣言がブロックの先頭に縛られないからなるべく使用するところで宣言するようにしろ。 宣言と同時に初期化できるのならそうするとなお良い。forで使うカウンタもfor内で宣言できる。for (int i = 0; i < N; i++) 2. フラグにはboolとtrue/falseを使え。 3. #defineは使わなくても済むなら消せ。 const使えば定数になる。つまり配列の添え字にも使える。 関数にinlineを付ければ(inline int f()など)コンパイル時にインライン展開される。 4. void *からその他のポインタ型への変換にはキャストが必要になった。(逆はC++でも平気) mallocなどには注意。 5. キャストもC++形式にしろ。今までのキャストは次のどれかに分類できる。(いくつか複合している場合もあるが) const_cast(const外し)、reinterpret_cast(ポインタ←→整数など)、static_cast(その他一般) static_castはdouble←→intとかvoid *→その他のポインタ型とかそういうときに使う。 6. malloc/freeの代わりにnew/delete new[]/delete[]を使え。
インライン展開は、確実性がないぞ。
そりゃそうだが気にするな。 7. 構造体変数を引数にする場合(関数内でそれを書き替えない場合)はconst参照にしろ。値渡ししたかのように . でメンバへアクセスできる。 関数内で書き替える場合はconstじゃない参照にすれば良いのだが、 (呼び出し側で&を書くことで)書き換えることを明示できるとポインタにする人もいる。 コーディングスタイルの問題なので言い出すとキリが無くなる。(俺は参照に出来るときは常に参照派) 参照ではNULLを表現できないからNULLを指定しても良いときは当然ポインタを使うしかない(わけではないが)。 これはクラスにも当てはまる。 8. std::stringを使うときにはメンバのc_str()を使うとconst char *型の文字列へのポインタを手に入れられる。const_castするなよ。 9. malloc/freeの代替としてはstd::vectorもある。realloc相当のことをしたければnew/deleteは使えないしな。 10. usingディレクティブ(using namespace 〜;)は使用禁止。namespaseを使う意味がなくなるじゃないか。 using宣言(using std::cout;)ならOK。
>>10 んなこたない。
名前が衝突するときだけ修飾名を使えばいい。
それもコーディングスタイルの問題なので言い出すとキリが無くなる。 とりあえず代わりにこっちを追加。 10.1. ヘッダファイル内ではグローバル名前空間でのusing禁止(ディレクティブ・宣言共に)。 8.1. 逆にconst char *→std::stringにはstatic_castが使える。 でもそういうときは一時オブジェクト作成のstd::string(p)の形式を使う人のほうが多い(と思う)。 11. C++では関数プロトタイプ宣言がないと関数を使えなくなった。 12. int f()とint f(void)は等価になった。int f()はCだと引数不定を意味するのは知っているよな。
(´・ω・`)しらんがな
11 :
デフォルトの名無しさん :2005/04/17(日) 21:45:57
どこで聞いたらいいのかわからないので、ここで質問させてください。 C++ は signed char と unsigned char と char を別の型として扱うとの ことですが、なぜこのようなことをしたのですか? int と signed int は同じとして扱うのに char だけなんでなのでしょう??
Cは char を signed char として扱うか、 unsigned char として 扱うかは処理系により、よって、char は signed char か unsigned char と同等なる、みたいな記述が今もっている本にあります. なぜだろか
なぜかというと、signedとかunsignedとか決めてしまうと、CPUの
種別によっては文字の扱いが遅くなる、しかしCやC++の文化では
それは許容できない。だからcharと書くとそのCPUでの「自然な」
(実行が速い)解釈を処理系が選べるように言語仕様を決めている。
ところで
>>11 はCからC++に移行とは何の関係もない質問なのね。
いやはや、大変お勉強になりました。ありがとうございます。 //関係ない質問だったならば、申し訳ないです。自分がC++に移行中だったもので
16 :
デフォルトの名無しさん :2005/04/23(土) 12:45:17
VCやBCCについてくるソースなどを見ると、多くの場所で#defineを使っていますが、なぜconstを使用しないのでしょうか?
17 :
デフォルトの名無しさん :2005/04/23(土) 12:45:49
VCやBCCについてくるソースなどを見ると、多くの場所で#defineを使っていますが、なぜconstを使用しないのでしょうか?
18 :
デフォルトの名無しさん :2005/04/23(土) 12:46:28
VCやBCCについてくるソースなどを見ると、多くの場所で#defineを使っていますが、なぜconstを使用しないのでしょうか?
19 :
16 :2005/04/23(土) 12:47:17
ごめんなさい
>>16-19 Cではconst付けても定数にならないから。
いちいちCとC++で切り替えるように作るのも面倒くさいだろうし。
const変数は外部参照させるためにあります。 別のCファイルから読めるようになります。 数式の中に入れると最適化を阻みます。 プリプロセスが汚いト思うならenum定数。 Cでもenum定数で宣言しても良かったはずですが 柔軟性を残すために#defineにしてあるのではないでしょうか。
>>21 >const変数は外部参照させるためにあります。
>別のCファイルから読めるようになります。
>数式の中に入れると最適化を阻みます。
………
言いたいことははっきり言わないと伝わらんよ。
>>21 > const変数は外部参照させるためにあります。
ちがいます。定数を定義するためにあります。
> 別のCファイルから読めるようになります。
それは const による効果ではありません。
> 数式の中に入れると最適化を阻みます。
コンパイラは値が定数であることを知ることができるので、
最適化を助けることはあっても阻むことはありません。
defineだとデバッグ時に分かりにくいんだよね
>>21 柔軟性が理由ではないね。enum定数という習慣がないだけだ。
enumを整数として扱うなよ
28 :
デフォルトの名無しさん :2005/04/24(日) 17:49:25
newでメモリを確保できなかった場合、ポインタにはNULLが入りますが、 deleteで削除した場合、ポインタはNULLになるのでしょうか?
29 :
上田 :2005/04/24(日) 17:51:08
なぜ試さないのか
>>28 > newでメモリを確保できなかった場合、ポインタにはNULLが入りますが、
そうとは限りません
> deleteで削除した場合、ポインタはNULLになるのでしょうか?
いいえ
>>28 > newでメモリを確保できなかった場合、ポインタにはNULLが入りますが
ちがうよ。 std::bad_alloc が飛んでくるんだよ。
ヌルが返るのは std::nothrow 使ったときだけ。
昔はNULLが返ったものじゃったがのう
>>24 extern constなんてのもCLSID/IIDでは使われているがな。
35 :
デフォルトの名無しさん :2005/04/24(日) 22:13:37
>>31 それは try{} した場合だろ。
適当な回答者ばっかだなここ。
>>35 tryで囲っていなくてもstd::bad_allocが投げられる。
terminate()などが呼ばれるのも例外を投げられた(けどtryで囲っていないからcatchされない)結果。
tryする/しないで挙動が変わるの?初耳
>>35 はゆとり教育の犠牲者なので煽らないであげてください
プログラマにゆとり教育も糞もあるか。
41 :
デフォルトの名無しさん :2005/04/25(月) 01:59:40
newでコンストラクタを呼び出す機序がわからん。 例えば、グローバルスコープで void* new( size_t size ) { return malloc( size ); } で new をオーバーロードしてもちゃんとコンストラクタが呼び出される。 なんで?
>>41 そりゃクラス内でオーバーロードしてないからだろ。
43 :
デフォルトの名無しさん :2005/04/25(月) 02:27:22
>>42 いや、トレースするとちゃんと malloc()を使っている方が呼び出されているし。
new と delete ってとても特殊なキーワードなんだろうか?
オーバーロードされててもされてなくとも、new, delete があれば、アロケーたー
呼出し後に必ずコンストラクタ呼び出しするコードをコンパイラが埋めこんでいる
としか思えん。
44 :
41 :2005/04/25(月) 02:31:24
オーバーロードしている new が、 template < class T > T* new( size_t size ) { T* p = malloc( size ); p->T(); } だったら判るんだけどね。そうじゃないからどうしてかなと。
>>41 関数(operator)形式のnewと演算子のnewの違いを調べろ
46 :
デフォルトの名無しさん :2005/04/25(月) 02:51:26
ごめん、間違えてた。こうやってたんだ。 void* operator new( size_t size ) { return malloc( size ); } 話を整理すると、これをグローバルスコープで宣言してやると、 コンストラクタを呼んでないので new したclassのコンストラクタは 呼ばれない気がするんだけど、呼ばれるのはどうしてかなと。 例えば、bool T::operator == ( T& right ) { return T::compare( *this, right ); } の compare を実行した後に、コンパイラが勝手に組み込みの == 比較演算をするのは 意味不明なわけじゃないですか。
>>46 new = operator new + constructor
48 :
デフォルトの名無しさん :2005/04/25(月) 03:06:58
>>47 operator new, deleteのオーバーロードは特殊で、そういうもんだということですね?
>>48 operator new, deleteは全然特殊じゃない。
特殊なのは演算子のnew,delete。
50 :
デフォルトの名無しさん :2005/04/25(月) 03:10:24
>>49 なら、なぜコンストラクタ呼び出しをするのでしょうか?
だから何度も言っているように、 コンストラクタを呼ぶのは演算子のnewなの。 operator newだけを呼びたいなら 例えば void* m = operator new(sizeof(int));。
52 :
デフォルトの名無しさん :2005/04/25(月) 03:38:34
実際にはコンパイラが newというアイデンティファーを見つけると、 push dword ptr [size] call operator_new mov ecx, [new されたポインタ] call T::T のようなクラスのコンストラクターを呼び出すコードを 挿入するだけだと思います。 でないなら、オペレーターオーバーロードの機構からいって、 オーバーロードされた演算子の newがクラスのコンストラクタを 呼び出すのは不可能ですし。
53 :
51 :2005/04/25(月) 03:48:54
>>52 = 50?
大体そんなところ。
一応付け加えておくと、
>>51 で言ってる演算子のnewってのは
opeartor new のことじゃなく、new-expressionのことね。
いつも自分でクラス作るとキモイクラスになってしまいます だでがだぢげで
友達につくってもらえ
>>54 きもいと言う認識があるだけまし。
実際にどんなクラスを作ったのか晒してみ。
57 :
デフォルトの名無しさん :2005/04/25(月) 12:31:58
58 :
デフォルトの名無しさん :2005/04/25(月) 14:08:06
char a[100]の文字列をstring strにコピーするにはどうしたらよいのでしょうか。 str=a;はエラーになってしまいました。
60 :
デフォルトの名無しさん :2005/04/25(月) 16:43:18
クラスのメンバ変数をconstにしたい場合どうすればよいのでしょうか?
>>60 普通にconstつけろ。
で、初期化子で初期化しろ。
62 :
デフォルトの名無しさん :2005/04/26(火) 00:21:38
>>60 class A
{
const int n;
public:
A( const int k ) : n( k ) {}
};
63 :
デフォルトの名無しさん :2005/04/26(火) 00:23:00
もしくは、 class A { const int n; public: A() : n( 100 /* 定数 */ ) {} };
>>62 わかって書いてるのかもしれないが、引数の const は不要だぞ。
>>63 そこに定数を書くなら、さらに static も付けて
宣言と定義を同時に書いてしまうのがいいだろう。
コピーコンストラクタの使い方が 未だによくわからん....誰か教えて
>>66 それって使い方じゃないだろ。訳わからんこと書くな
>>67 使い方だと思うが。
>66のようなコードを書くと、FOOクラスのコピーコンストラクタが呼ばれるのだから。
>>68 66のコードだとコピーコンストラクタは呼ばれず、operator =()が呼ばれる。
用途は同じようなものだけど。
70 :
67 :2005/04/27(水) 20:55:29
ごめん間違えた。こっちか。 FOO a; FOO b = a;
FOO a; FOO b(a);
バカの72が来ましたよ。
74 :
デフォルトの名無しさん :2005/04/30(土) 22:05:34
C++でlongjmpを使いたいのですが、 longjmp巻き戻り時にスタック上にあるオブジェクトのデストラクタの起動は 保障されますか? それともlongjmpよりthrowの方が良いですか?
>>74 throwって言いたいけど、なんだか例外と言えなさそうな状況である気配がするな……。
メモリリーク回避なら スマートポインタをお勧めしておく。
まあ74もそんなことは判ってると思うがね。 おれも昔、C/C++でSchemeの継続みたいなことしたいと思ったけど、 結局再帰は使わず処理の方を自前のスタックに押し込んで管理した。 理由は仕事だったから。
>>74 VCはなんかSEHの構造的に保障されてるみたいだけど、
実際は環境・処理系依存っぽい。
どうしても使うならthrowが手段としては安全じゃないかな。
>>77 みたいに関数のネスト自体をなくしてしまうという設計の仕方もある。
管理は多少大変だけど確実ではある。
79 :
デフォルトの名無しさん :2005/04/30(土) 22:32:02
ありがとうございます。 とりあえずthrowで作ってみて、時間があったら設計を見直してみます。 一応処理の内容は、ワーカースレッド内でフォルダを再帰的に辿る 処理があって、その途中でGUIからユーザーがキャンセルしたときの 中断をどうするかというものでした。
80 :
デフォルトの名無しさん :2005/05/02(月) 17:17:10
クラスをnewしなくてもよべるメソッドって作れましたっけ? Delphiで言うClass Functionみたいな。
>>80 > クラスをnewしなくてもよべるメソッドって作れましたっけ?
確実に間違った認識をしてるようだけど、たぶんstaticメソッドがそれに該当する。
>>81 メソッドと言うな。静的メンバ関数と言え。
CからC++へは「移行」すべきものなのかいな。 C言語のプログラム技術は維持しながら、C++というもう一つの技術を学習して、 選択肢を増やすのが正しい道だと思うんだが。 C++の本は、Cのやり方を否定的に書いてるのが多いのが気になるんだが。 そして、まだ完全にCを学んだわけではないのに、C++を学んだからと言って、 あたかもCを卒業したかのように考えるのもおかしいと思うんだが。
>76 ( ´_ゝ`)スマポ
>>83 「Cのやり方」にはより良い代替手段が用意された部分が多い。
・ブロック先頭での未初期化変数定義 → 使用箇所での初期化付き定義
・忘れないように気をつけて初期化、破棄 → コンストラクタ、デストラクタ
・関数ポインタ+void*+キャスト → 仮想関数
・なんでもできる危険なキャスト → 限定的、明示的なキャスト
・型チェックの働かないマクロ → テンプレート
・名前のプリフィックス → 名前空間
・戻り値によるエラーチェック → 例外のスロー、キャッチ
この状況でそれぞれの前者が否定的に見られるのは自然。
C++コンパイラが問題なく動作する環境なら、
これらのより良い手段を使うためにC++に移行するのも自然。
Cによるライブラリを使うためとか、C++が使えない環境でも生きていけるように、
また、C++の仕様に対する理解を深めるためにも、
C言語のプログラム技術を学ぶことには大きな意義がある。
Cを卒業したかのように考えるのはただの勘違い。明らかにおかしい。
c/c++ってまとめられるとちょっと困っちゃいますよね。 c++には自信あるけどcには自信なかったり。
まぁいまどきstring.hで宣言されてるような危険な関数群の使いかたなんか覚えたくもないわな。
88 :
デフォルトの名無しさん :2005/05/03(火) 04:52:43
>>83 とは言え、俺はCを否定したい。
たかが定数やインライン関数ごときに#define使ったり、
classもnamespaceもないから関数名に汚いプリフィックスつけたり、
あんな糞環境は一刻も早く消し去るべきだ。
インライン関数にdefine...?
>>91 #defineの関数形式マクロのことだろう。
>>93 しかし定数ではないから、たとえば配列変数を宣言するときの要素数に使えない。
C99だとできなかったっけ?気のせい?
可変長配列はどこでも使えるわけではありません。 可変長配列が使えるのは、ブロックの中か関数引数/プロトタイプの中だけで、 グローバル変数として宣言したり、struct や union の中のメンバとして宣言したり することはできません。加えて、static や extern 付きの配列は、可変長配列に できません。
99 :
デフォルトの名無しさん :2005/05/08(日) 10:00:25
クラス名ってどのようにつけていますか? やはりC〜とすることが多いのでしょうか?
俺はCはつけていない。 関数名みたいに単語の頭を大文字にしているだけ。
半角英字の大文字始まりとし、半角英数文字のみで半角英字の大文字区切りとします
型は全部〜_t クラスも〜_t
103 :
デフォルトの名無しさん :2005/05/09(月) 03:10:28
class A { int x; public: void InitX( void ) { x = 0; } } というクラスAを, void func( const A& r ) { r.InitX(); } と引数で constの参照で取るとA::InitX()が const の関数でないので エラーになるじゃないですか。この引数を、"const A& r" → "A& r"と変更することなしに 対処する方法はないですか? あくまでも func()が直接 class Aを書き換えるわけではないので 納得いかないんですが。
エラーにはならないと思う。
>>103 Aと言うクラスの、引き数rとして渡された参照先をInitX()で書き換えるんだからエラーが出て当然。
納得いかないのは学習不足を棚に上げた所為。
106 :
デフォルトの名無しさん :2005/05/09(月) 04:08:56
>>105 「あくまでも func()が直接 class Aを書き換えるわけではないので 」
って書いてんだろ。意味わかんねーのか?
なんでそんな偉そうなわけ?
107 :
デフォルトの名無しさん :2005/05/09(月) 04:12:04
>>105 じゃあついでに質問してやるが、
allocator::construct(pointer p, const T& val)
の実装をせよ。
108 :
107 :2005/05/09(月) 04:32:21
質問を取り消します。 どうもすみませんでした。
109 :
105 :2005/05/09(月) 04:43:11
「納得いかないのは学習不足を棚に上げた所為。 」なんて放言するのは
自分の学習不足を棚に上げた所為でした。107様には、心よりお詫び申し上げます。
>>108 で成りすましをしてごまかそうとしましたが、自分はなんて卑劣な人間なんだろうかと
今、恥ずかしくて死にたい心境です。これより精進し、allocator::construct
位普通に実装できるような普通のPGにならなければならないと反省しております。
>>104 class A {
int x;
public:
void InitX( void ) { x = 0; } // 定義(1):OK
static void InitXS( const A& r) { x = 0; } // 定義(2):NG(constは変更できない)
};
static void func( const A& r ) {
r.InitX(); // (1)の呼び出し:NG (たぶんthisはconstであるべきではない)
r.InitXS(r); // (2)の呼び出し:OK
}
int main() {
A a;
const A& ar = a;
func(ar);
}
// (1)の呼び出し:NG (たぶんthisはconstであるべきではない) とは、class Aのメソッド InitX のシグネーチャが、 ○ void A:InitX(A& this); × void A:InitX(const A& this); ということ
112 :
デフォルトの名無しさん :2005/05/09(月) 04:56:37
夜食の唐揚うまうま
113 :
デフォルトの名無しさん :2005/05/09(月) 05:13:47
114 :
デフォルトの名無しさん :2005/05/10(火) 04:17:19
なんだ、返事もできねぇ屑か
perlでいうCPANみたいなのってC++にはありますか?
ない
オーバーロード実験 void func(const char* str) { cout <<"const"<<endl; } void func(char* str) { cout << "not const" << endl; } /*できなかったもの void func(const char* const str); void func(char* const str); */ int func2(int i) { } //int func2(const int i);はできなかった。 func("moji")ではconstは表示されない。 tukareta・・・おやすみなさい
118 :
デフォルトの名無しさん :2005/05/10(火) 05:18:19
>>117 void func(const T foo);
と
void func(T foo);
は呼び出し側にとっては区別がつかないのでオーバーロードできない。
従って同様に、
void func(char * str)とvoid func(char * const str)、
void func(const char * str)とvoid func(const char * const str)
はそれぞれオーバーロードできない。
120 :
デフォルトの名無しさん :2005/06/04(土) 14:34:37
C++約束事が多すぎて ムズイ・・。
まー、憶えることは多岩魚。 いきなり詰め込んでも身にならない。 使ってみて、「あ、これ使うと、こーゆーことができるんだー」ってのに気がつけば習得したといえる。 C++に限らん話。
多岩魚?? ・・まあいいか ^^ 単純に、構造体をクラスに置き換えればC++だと思って、 軽い気持ちで始めようとしたら、練習本が500ページもありやがる orz 一週間で余裕だぜ!とか思ってた自分が恥ずかしい。。
>>122 > 単純に、構造体をクラスに置き換えればC++だと思って
いるうちは恐らくC++は使いこなせない。
Cを構造化言語として使っていたのなら数回の劇的なパラダイムシフトを繰り返して
ようやっとC++の言語としての機能を全部使いこなせるようになるですよ。
一年くらいかけてゆっくりそして確実に行くのが良いかと存ずる。
「多岩魚」 = 「おおいわな」かーー!!
っと。
>>123 >使いこなせない・・
そうですか。あぁ orz
取り合えず、500ページ終わらせてみます。
てゆか、500ページ終わる頃には
最初の200ページ分ぐらい完全に忘れてて、
途方にくれる予感もビシビシしてるんですけどねえ。。
現在137ページ。
参照仮引数引渡しとか、、もう全部ポインタ渡しでいいやん (´・ω・`)
参照がないと演算子オーバーロードとかをエレガントに実装できんのよ
オーバーロードって、関数の多重定義ってやつですよね? あー、参照となんの関係があるのかわかんねー orz うへへ、500までがんばりまっす (`・ω・´)
>>126 C++やそれより後の言語には演算子オーバーロードというものが存在する。
例えばstd::cout << 〜;というのも<<演算子のオーバーロード。
std::coutはstd::basic_ostreamクラスのオブジェクトであるが、std::basic_ostreamのメンバには
basic_ostream& operator <<(int n);
basic_ostream& operator <<(const char *);
と言った具合に並んでいる。
そしてstd::cout << 5 << "個";という式は(cout << 5) << "個";と解釈されまず5を引数にしてoperator <<が呼ばれる。
この戻り値は元のオブジェクト自身への参照を返すので次にcout << "個"ということになる。
>>127 だから、<<出力演算子や>>入力演算子が適用される度に(inlineで
なければ)毎回関数CALLが起きるわけで、ここら辺がCのprintf()、scanf()
に比べて弱点だと言われてるけど、逆に言えば出力(入力)書式はコンパイル時
に既に決定しているので、解析する必要がない。
Cでもprintf/scanfは動作が重い関数の内に入る。C++になって、俺は入出力
が遅くなるという理由で<< >>を使わなかった事はない。
>>127-128 >>126 です。丁寧な説明感謝です。
とりあえず、
int g_a;
int & func()
{ return g_a; }
ってやって、
main()
{ func() = 10; }
で、func()の返したアドレスの場所に
値が代入できることまではわかったのですが、
これをどううまく使えるのかがわからず・・
私のレベルでは無理なようなので、引き続きお勉強しまっす。
ありがとうございました m(__)m
>>129 あと関数の仮引数ではポインタ渡しに比べて呼ぶ側がいちいち変数に&をつける必要がなくなる。
特に今までクラス・構造体のconstポインタ渡しだったものをconst参照にすると、
呼ぶ側も呼ばれる側もポインタ渡しを意識する必要がなく、あたかも組み込み型の値渡しのように扱える。
クラス・構造体・組み込み型いずれにも当てはまるけど、 ポインタにはNULLポインタが存在するが、参照にはそのようなものは存在せず、 常に何かを指していると思って扱えるのでいちいちポインタ引数のNULLチェックをする手間も無くせる。
>>130-131 なるほど。使う側の混乱をちょっと抑えられるかもですね。
てことは、Cでポインタ渡ししてた場面でも、
C++では参照渡しを積極的に使ったほうがいいんでしょうか?
組み込みのポインタ VS 参照 なら、NULLを渡さなくていい時は参照を使うべきだと思う。 ポインタは 参照 と イテレータ っていう2つの役割がごっちゃになってる物だから、ポインタの負担は軽くしてあげたほうがコードが読みやすくもなるはずだ。 実際にはそのうちオブジェクトの所有権とか考え出すとスマートポインタとかを使う場面が多くなると思うので そんなに気にしなくてもいいと思うけど。 簡単にまとめると「参照で困らないときは参照を使え」だな。
>>133 どうもありがとー。
私が今お勉強してる本には、
参照とは、基本的には暗黙的なポインタ定数の事で、実質的には
ほかの変数または引数の別名として使うことができます。
参照仮引数を使う利点として、引数のコピーが作成されない
ということが挙げられます。
と、ありました。
コピーが作成されないってことは、
速度的にも問題なさそうですね。
速度はポインタと同じかな?
うし、これからバリバリ使うことにしまっす (`・ω・´)
スマートポインタとか、イテレータってのは
なんのことかわからずww
>>134 ポインタ「定数」ってのはおかしいな。参照は変数だ。
参照は結局内部ではポインタで実装されている.
これは間違っていない。そうでない処理系なんて聞いたことない。
参照先を変えられないconstポインタに近いものであるという意味で ポインタ定数と書いたのではなかろうか
double g; で作ったgを Function(g, 〜) で void Function(float g ,〜〜〜) の方にワーニングなしで送れるってのはVCの仕様ですか?
>>137 警告Lvを上げたら警告されると思うのだが。
あー、C++覚えること多い〜 (ToT) もうコンストラクタとデストラクタは無くていいよ これがあるせいで、ややこしいこと多すぎー
>>139 少なくともコンストラクタ・デストラクタは大したことないと思うけど。
ローカル変数を宣言した or newしたときにコンストラクタが呼ばれて、
ローカル変数のスコープを抜けたとき or newしたポインタに対してdeleteを呼んだときにデストラクタが呼ばれる。
ようするにそんだけでしょ。たった2行。
例えばうまく使った例では
std::auto_ptrクラスはコンストラクタでnewしたポインタを受け取り、デストラクタでdeleteを呼んでくれる。
だからdeleteし忘れによるメモリリークを防ぐ手当てになる。
>>140 わかりやすい説明どうもです。
コピーコンストラクタの説明でちょっとキレちゃって ^^
オブジェクトを引数にしたり、
戻り値にして代入しようとしたりすると
呼ばれるとか呼ばれないとか言われて、、あああー!
コンストラクタは暗黙の型変換で呼ばれたりするので注意汁 C++ではそのようにしてテンポラリのオブジェクトが作られることも良くある
>>141 つまりこういうこと?
class hoge {};
int main()
{
hoge a, b; //aとbに対してそれぞれコンストラクタが呼ばれる。
hoge c = a; //cに対してコピーコンストラクタが(aを引数にして)呼ばれる。
b = a; //bは今ここで変数宣言したわけではないのでコピーコンストラクタは呼ばれない。
} //もちろんここでa, b, cのデストラクタが呼ばれる。
>>143 そですね。
あと、
myclass func ();
って関数つくって、
myclass ob1;
ob1 = func();
というふうに戻り値を代入したときとか、
void func (myclass ob);
って宣言して、
myclass ob1;
func(ob1);
てな感じで引数にしたときなんかも
呼ばれるみたいです
まだほかにもありそうだし・・勘弁して欲しいよ。
>>144 関数の戻り値は結局143の話と同じ。変数が関数の戻り値に置き換わっただけ。
関数定義の時、仮引数はブロックの頭で宣言された変数という扱いで、そこへ実引数を元にコピーコンストラクタが起こる。
あんまり神経質にならなくてもコピーコンストラクタかoperator =()のどっちかが呼ばれると思っておけばいい。
>>145 どもです。
実際使い始めたら、後からクラスに付け足した変数とか
コピーコンストラクタに入れ忘れたりしそうで怖いよお。
operatorってのは、まだお勉強中なのでわかりません。
そこまで行ったら、また違う景色が見えるのだろうか。
>>146 operator =()ってのは
>>143-144 の例でコピーコンストラクタが呼ばれないときに呼ばれる関数。
そのうち出てくると思うけど。
最初のころから出てくる<<もoperatorじゃないの?
演算子のオーバーロードまで キタ━(゚∀゚)━!!!!!
>>127 さんの書き込みが、やっと少しだけ理解できるようになったよー。
てゆか、こんなん自分で定義しまくったら、組んだ人以外
ワケワカメになりそうだけどなあ。
>>151 うまく使えば便利。
例えば文字列クラスに+=や+とか不等号演算子での比較
複素数や多倍長整数に四則演算など、配列クラスに[]
リストの全要素へのアクセスにポインタっぽく演算子をオーバーロードしたクラスを使ったり
便利だからといって、文字列クラスに-オペレータとか/オペレータとかで 抽出とか分割をやり始めると自分でも混乱する羽目に陥る罠。
まあなんだ、いらんのなら別に演算子オーバーロードを使う必要はない訳だが 1) operator=はデフォルトで作られてしまうから、その動作でまずい場合は 正しい実装をするか、単にprivateにする 2) STLなどのテンプレートライブラリでクラスを使う場合、特定のoperatorの 存在が必要になる場合がある ってとこかな。
わけわかんなくなりそうっていうか、 何でもやっちゃうクラスやら 何でもできちゃうインターフェイス(プロトコルクラス)を作ったら 実際、わけわかんなくなる。 クラスの役割と責任をしっかり考えて分離すれば問題ない。
質問です。 int func(string& str)やfunc(string str)に対して、 func(string("str"))は通るのですが、 func(int i, string& str)やfunc(int i,string str)に 対して同様のことを行うと func(int,string)に相当する関数が見つからない という感じのエラーが出てしまいます。 理由がわかりません。 それから、これ( class名+() )の名称か何かを見かけ た気がするのですが、メモとり忘れてて、調べように も調べることができません。 よろしくお願いします。
>>156 エラーになったコードを見せてくれないと答えようがない。
型名()ってのは一時オブジェクト作成とか関数スタイルキャストとかコンストラクタ呼び出しなどと言われる。
クラスに限らず、intなどの組み込み型や構造体などにも使える。
その前に、 int func(string& str); に、func(string("str")); は通らん。右辺値じゃないか。
VC++だと通っちゃうんだよね、それ VC++の独自拡張だけど
へえ、通るんだ。でも、一時オブジェクトを参照引数に渡したら、ユーザの 想定外の挙動になるよな まあ本来const リファレンスにすべきものであったなら、問題は なかろうが。
結果を捨てるだけだから問題ないっしょ。
>>161 long& に値を返す関数に int 変数を渡したときとか、死ねる予感。
ダメだこりゃ
皆さん有り難うございます。(遅くなってすいません) えーと、、、何故かエラーが再現不能になりました。 本当にすいません。 BCB5を使用しているのですが、 string func(string& a, string& b){a+=b;b+=a;return b;} に対して cout << func(string("ma"),string("to")) << endl; cout << func("111","222") << endl; としても、「一時変数を作成する」という警告(多分string)が二つだけで 通るようです。 これはやはり問題有りなのでしょうか。
>>164 string c = "ho", d = "ge";
func(c, d);
こういう風にでもすれば実引数が書き換えられているのを確かめられるが、
164コードではにするとそれができないという警告。規格でも駄目ということになっているし。
>>164 標準に準拠したコンパイラでエラーになるという問題が有る。
>>165-166 結局のところ164のように書くべきではないみたいですね。
有り難うございました。
>>151 です。いまだに演算子のオーバーロードをやってるのですが、
文字列の連結やコピーをする↓のクラスをつくってみました。
http://www.vipper.org/vip30009.txt operator += はたぶんできたのですが、
operator + のとこで悩んでいます。
cStrType & cStrType::operator + (const cStrType &ob)
{
cStrType temp;
strcat(str, ob,str) // 文字くっつける
strcpy(temp.str, str); // くっつけた文字をtempに入れる
・
・
return temp;
}
↑みたいにやりたかったのですが、
cStrTypeクラスには、文字列がもう一個あって、
それはオブジェクト自体の名前が入ってるんです。
↑のようにtempを返してしまうと、代入先のオブジェクトの名前が
変更されてしまうのですが、
こういう場合はどうすればいいんでしょうか?
わかりにくいプログラムですみませんが、どなたかお願いします m(__)m
>168 ソースはよく見てないが、 += が出来たのなら cStrType & cStrType::operator + (const cStrType &ob) { return cStrType(*this) += ob; } でいいような気がする。 ソースを見たらコピーコンストラクタ無かったっぽいから、それを定義するか、 cStrType tmp; tmp = *this; tmp += ob; return tmp; だな。 + と += みたいなのは1つ定義したらそれを使って他を定義するのが基本だと思う。
間違えたというか見落としてたが、 operator + が返すのは参照じゃなくて実体だから、 戻り値の型は cStrType& じゃなく cStrType な。
operator +()を
>>169 のように実装するのは定石だよ。
operator !=をoperator ==の戻り値を ! で反転させて作るのもよくやる。
172 :
168 :2005/06/14(火) 19:25:55
>>169-171 おー、それは楽ちんな感じですね。
似たやつは即利用できるのか。
ちょっと質問とはかけはなれてるっぽいんですが、
凄い便利そうなので、明日あたり
>>168 のを簡略化して、
>>169-171 を組み込んでみまっす!
クラスって、自分で始めて本とか極力見ないで組んでみたんですが、
普通の構造体とかと違って、作る前に考えなくちゃ
いい動きするヤツはできないっぽいですね。。
>>168 のを作ってる途中、何回か破綻して、
つくり直しましたよ ^^
あー、早く使いこなせるようになりたい。
れすさんくすです。
173 :
168 :2005/06/15(水) 18:07:05
できました。
モロ
>>169 と一緒になっちゃったんですが
http://www.vipper.org/vip31149.txt どもです m(__)m
それで、あの、ちょっと質問なんですが、
return cStrType(*this) += ob;
↑でもいけるようなのですが、
これはなにをやってるんでしょうか?
return *this += ob;
↑だと *this の値にも影響を与えちゃうんでダメなのですが、
return cStrType(*this) += ob;
↑だとOKってことは、、、、、なんだろ??
>>173 cStrType(*this)でオブジェクトを生成している。
お、即レスさんくすです。 return cStrType temp = *this += ob; みたいな感じなんでしょか? うーん、新しい。
>>175 微妙に違う。それでは*thisが変更されてしまう。
むしろ、
cStrType temp = *this;
temp += ob;
return temp;
>>176 あー、そっか ^^
でも、変数名すら決めてないオブジェクトが
返るなんて、不思議っちゅーか、便利っちゅーか
使いこなせる自信はないですな・・。
>>177 podと同じように考えたら?
ex.
double func(int v) {return double(v);}
あー、その記述のしかたも初めて見ました。 型キャストとも違いますよね return (double)v 普通のC言語からあったんでしょうか。 pod と ex. ってのも、意味不明なんですけど (T_T)
>>180 ご親切に、どもです。
ex.の方は把握。
plain old data の方は、
なんとか日本の解説ページを探してみます。
お手数をかけてしまって、マジすみません orz
182 :
デフォルトの名無しさん :2005/06/15(水) 20:23:42
#include<stdio.h> void main(void) { while(1) printf("ぬるぽ\n"); }
>>183 全部先頭で宣言してたら発狂しそうになって困るだろ
>>184 途中で宣言すると「iって宣言したっけなぁ」とか分かんなくなるので、
先頭で宣言すること多いんだけど、明確な理由があればスタイルを
変えようと思っております。(そもそもそんな長い関数書くなは置いと
いて)
186 :
デフォルトの名無しさん :2005/06/15(水) 21:32:23
void f(bool flag) { if(!flag) return; socket x("127.0.0.1, 80); // 先頭においても初期化に時間がかかるが全くつかわれない vector<string> y(10000); // これも重い } すべて先頭で宣言すると、重いクラスやら、時間食うクラスなんかの不必要な 初期化コストがかかってしまい、宣言しても使わないのなら無意味に重くなるのだそうな。
>>181 PODはようするにCでもそのまま使える構造体・クラス・共用体のこと。
参照型メンバ変数・operator =()・デストラクタ・非PODメンバ変数の存在しない構造体・クラス・共用体が該当する。
>>185 先頭で宣言するスタイルを C++ で貫こうとすると、
・初期化をしないことが珍しくなくなるので、初期化忘れの危険が増える。
・コンストラクタで重要な処理を行うクラスが扱いにくくなる。
・クラス作成時に意味無くデフォルトコンストラクタが要求される。
・初期値が決まったタイミングで「代入」が必要になるので、
・「代入」できない型では通用しない。
・ローカル変数に const を付けることが不可能になる。
デメリットしかないな。
クラスについて質問させて下さい #include "CMyChar.h" class CMyWeapon { public: CMyWeapon();//コンストラクタ virtual ~CMyWeapon();//デストラクタ void Init();/●初期化● void Process(CMyChar* pMyChar);//★メイン処理★ }; このProcessで [error C2061: 構文エラー : 識別子 'CMyChar' がシンタックスエラーを起こしました。] となってしまいます。 includeしてますし・・構造体のようには使えないんでしょうか? ちなみに参照を使っても同じエラーが出ます レスをよろしくお願いします
>>189 >void Init();/●初期化●
これは何かの冗談か?
192 :
189 :2005/06/16(木) 12:42:40
>>190 #include <d3d9.h>
#include <d3dx9.h>
#include "Global.h"
#include "CMyWeapon.h"
class CMyChar
{
private:
int w;//キャラ幅
int h;//キャラ高さ
public:
float x;//自キャラ 左上座標 X
float y;//自キャラ 左上座標 Y
float vy;//VX
float vx;//VY
〜変数宣言が続きます〜
CMyChar(float xpos,float ypos,float vecx,float vecy,int width,int height,int tex,int tey);
virtual ~CMyChar();
void Init();//●初期化●
void Process();//★メイン処理★
void Move();//移動と移動の制限
void Scroll();//スクロール管理
〜以下関数が続きます〜
};
です privateをpublicにしてみましたが同じエラーが出ました
>>191 すいません /を1個削りすぎましたw
>>192 > #include "CMyWeapon.h"
これだろ。要らないなら消せ。
194 :
189 :2005/06/16(木) 12:55:46
ありがとうございます!!通りました! 前にincludeしたのをそのままにしてました・・・スレ汚しすいませんでした
>>194 (今回のとはちょっとずれるが)
VC使いなら#pragma once使え。
使う理由も考えてな。
196 :
189 :2005/06/16(木) 20:00:08
はい 使ってます クラスはいつも右クリしてクラスを作成してますのでデフォルトでついてます。
なるほどIDEに甘やかされて育つとこうなるのか
しかし、関数の先頭で変数を宣言をしないプログラムなんか、だらしのない書き方 のような気もする。そして、初期化忘れの危険もあるかも知れないが、そこらへん は、しっかりしていて不注意を犯さない人間であるという前提でコーディングでき るようでないとだめじゃないかとも思うし。 VBは手続きや関数の先頭以外でも宣言できるのは知ってるが、先頭でしか宣言した ことがない。 また、その一方で、Cでは関数の先頭で変数の宣言をしているものばかりで、関数より も内側のブロック内の先頭で宣言するのは、あまり一般的ではないようで、俺自身は まだそういうソースコードを目にしたことはない。メモリやパフォーマンスで問題 になるときなど、場合によっては、それを使わない手はないと思うが、世の中には、 ちゃんとそういうソースコードもあるのかな。
>>198 >>188 をちゃんと読んだのか?「だらしない」とかそういう問題じゃないんだよ
C++では。
コンストラクタというものが存在しないCのような言語では関係のない話だがな。
まあ俺はポインタを宣言して、newとdeleteしてるけどな。
>>200 そういうコードは例外安全じゃないんで現在のC++プログラミングでは
推奨されない。
>>201 「newとdeleteしてる」だけで「例外安全じゃない」と言えるの?
>>203 まあ言えないかもしれないわなあ
*大抵は*例外安全じゃないけど
>>198 Cでブロック内部での変数定義を余り見掛けないのは、まさしくあんたみたいな技術者が多いから。
ましてCommonCの時代の人間は変数の使い回しも含めて、まさにマクロアセンブラ的に書く。
逆に、C++慣れしているプログラマはCでもブロック内で定義している。
>>205 ブロック内定義はソースの見通しという意味でも漏れもCであっても積極的に使っているけど、
使いまわし変数の不要な文脈依存性が減って
オプティマイズもかかりやすくなるような気がするがどうなんだろう。
207 :
205 :2005/06/17(金) 12:24:52
>>206 私もそう思う。昔のコンパイラの例だが、レジスタへの割り当て方が随分違った記憶がある。
すいません、最近c++を勉強し始めたのですが クラスを使うメリットがよくわかりません。誰かわかりやすく教えてくださいお願いします
int i; int arr[10000]; for(i=0;i<10000;i++){ int *p=&arr[i]; } こんなのはどうなんだろ。最適化してくれるのかな
>>209 一番エキセントリックな最適化をさせると、おおよそ次のようなコードと同等に最適化すると思われ。
int i = 10000;
int arr[10000];
>>210 すまん例が悪かった
int i;
int arr[10000];
for(i=0;i<10000;i++){
int *p=&arr[i];
dosomething(p);
}
とした時にループする毎にint *pをスタックにpushして使い終わったらpopして・・
とかバカ正直にしないだろうなと思って
やっぱり関数入り口でいっぺんに確保して使いまわすのかなとか
212 :
208 :2005/06/17(金) 15:45:39
誰かさっさと教えてください
変数の使い回しって・・・それがタブーでない人がいるのか
>>212 ヒント:オブジェクト指向プログラミング
調べてもなおメリットが感じられないのならば、Cを使い続けろ。
215 :
208 :2005/06/17(金) 16:13:17
オブジェクトっつーかただ何の変数使ってるかわかりやすくなるだけだろ。 調べても、とかほざいてるあたりお前はただ適当に使ってるだけなんだろうな
>>215 情報(この場合はおまいの理解)小出しにするなよ、アフォ。
何が分からないのか書かない限り答えられねーだろ。
おまいの理解が「ただ何の変数使ってるか分かりやすくなるだけ」
程度のものだったら、なおさら「オブジェクト指向」とは何たるかを勉強しろボケ。
結局のところ、効率を取るか安全を取るかって話で、 多くの人はデフォルトで安全をとる。それだけのことじゃん。
218 :
208 :2005/06/17(金) 16:25:22
219 :
208 :2005/06/17(金) 16:28:01
結局は「自分で調べろや」そこら辺に書いてある受け売りのように「オブジェクト指向勉強しろ」だもんなwwwwwww ちゃんちゃら可笑しいぜwwwwwww結局はお前が一番理解してないから説明できないだけだろうがwwwwwカスがでしゃばんなよタコ
晒し上げ
>>211 コンパイラは一般的に、ブロック内変数を関数ローカルのスタックに確保する。
但し、レジスタで事が足りたり最適化で消える場合はその限りではない。
そのロジックではループ部は恐らく、
for (i = 0; i < 10000; ++i) {
dosomehing(& arr[i]);
}
と同等のコードになる。
いずれにしても、ブロックの出入りでスタック操作することはない。
>>213 10年以上制御系に携わってきた人のC++のコードの実例(抜粋)
for (char * tret = (char *) -1; tret != NULL; i++) {
tret = fgets(..., fp);
...;
if (...) {
tret = NULL;
}
}
...;
if (...) {
tret = (char *) -1;
}
...;
if (tret == NULL) {
...;
}
>208=>215なら釣りか。
222 :
208 :2005/06/17(金) 16:40:50
まぁ馬鹿が説明できないから釣りとしかいいようがないか。所詮このスレの資質はこんなもんよな
>221
あー、forループのブロックの位置がおかしい気がする。
まぁ、適当に。
>>222 そのスレの資質未満が何言ってんだか。
224 :
208 :2005/06/17(金) 16:54:09
わざわざ数字コテにして自分の存在をアピールしても 他と同様、カスであることに変わりはないんだから無理すんなwww
>>223 >>221 はとてもC++のコードには見えないなぁ。
fgets()はいいとしても、Cスタイルのキャストとか。
そもそもまともなC++コンパイラだと
>>221 はコンパイル通らないよね。
(forブロックの位置が違うというのはそのこと?)
というか、このソース晒しのポイントはどこにありまつか?
なんつーか宗教戦争してますね。 いい加減余所でやってくれんかな…。
>>226 >221のfor以下のコード全体がforブロックね。
で、ループ継続条件はそれようにbool変数でも用意すればいいのに
わざわざここまでポインタ変数使い回す辺りが気色悪いと言う話。
#char *に-1を代入するなんてねぇ。
すみません。 Cのスレからやってきました。 suffixarrayのC++Verなのだそうですが C++が少ししか分かりません。 どなたかCに書き換えていただけませんでしょうか vector<int> make_suffixarray(const string& str) { vector< pair<string, int> > v; for (int i = 0; i < str.size(); ++i) v.push_back(pair<string, int>(str.substr(i), i)); sort(v.begin(), v.end()); // sort by first elements vector<int> suffixarray; for (int i = 0; i < v.size(); ++i) suffixarray.push_back(v[i].second); return suffixarray; }
>>229 #include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct pair { const char *s; int n; };
int cmp(const void *a, const void *b)
{
const struct pair *aa = a;
const struct pair *bb = b;
return strcmp(aa->s, bb->s);
}
size_t make_suffixarray(const char *str, int *array)
{
size_t i;
size_t len = strlen(str);
struct pair *holder = malloc(sizeof(struct pair) * len);
for (i = 0; i < len; ++i) {
holder[i].s = str + i;
holder[i].n = i;
}
qsort(holder, len, sizeof(struct pair), cmp);
for (i = 0; i < len; ++i)
array[i] = holder[i].n;
free(holder);
return len;
}
232 :
デフォルトの名無しさん :2005/06/17(金) 20:17:43
>>231 ありがとうございます。
勉強したいと思います
クラスの定義の中に関数の実体を直接書くとインライン関数になるそうですがクラス定義の外に関数の実体を書いたときにインライン関数にするにはどうすればいいのでしょうか
inlineでいいんじゃね?
235 :
233 :2005/06/18(土) 02:10:48
>>234 その場合クラス定義の中身のみ 関数の実体部のみ 両方 のどれでしょうか?
全て試したのですがどれもエラーも警告も出なかったのでどれが正しいのか分からなくなりました
ちょっと上の最適化の話もそうだが、 なぜ、コンパイルされた後どういうコードになってるか調べないかの〜。 IDE上だと.sファイル作らないからかの〜。 ちょっと年取りすぎたかの〜。
>>236 読めないんだよ、きっと。
VC++だってプロジェクトの設定などで設定できるんだけどね。
>>233 inline指定はヒントにしかならないので要注意。
#確かbccだと「インラインにできない」警告が出たと思うが。
>>237 BCCのinlineにできない警告はメンバ関数を外に書くだけでは出ない。
繰り返しとかswitchとかクラスなどを値渡ししたりとかそういうことをすると出てくるものだったはず。
239 :
237 :2005/06/18(土) 09:18:57
言葉足らずだった。 ヒントにしかならないから、inline化できないことがある。 ということで。
>236 ある特定の環境下での実際問題な話だけなら良いが、 言語自体について語るなら、それじゃ困るって事じゃねーの? さすがに必要ならやれる人だっているだろ。
>>240 言語自体について語るなら、inlineキーワードはただのヒントであって
実際にインライン化されるかどうかは実装系による、ということで
終了な訳だが。
同じ関数でも場所によって インライン呼び出しされたりされなかったりするから、 全ての読み出し箇所を調べる必要がある。
>>235 どれでも間違いじゃない。ただ、両方に書くのは冗長。
インライン関数であるかどうかが実装の詳細である
という見方をすれば、宣言に書かずに定義に書くのがいいだろう。
逆にインライン関数であることが重要なのであれば、宣言に書くことも考えられる。
後者の場合はクラス定義内で関数定義することで済ませるのが一般的。
1つの関数の呼び出しに、同じ inline 関数を複数回使ったときに その inline 関数が static なデータを使っているときに、おかしな答になるので要注意 bc は、そんな inline 関数は inline にはしないのでだいじょうぶなのだが。。 vc は自分で注意する必要あり。
質問です。 引数iが0以外のときはファイルに文字を出力したいのですが、 あまりいいのが思いつきません。 bool func(int i=0){ ostream * const out = (i)? new ofstream("out.txt"):&cout; /*ファイル開く失敗の処理がわからない*/ if (ファイル開けない) return false; 文字とかを出力したりする。 *out << ..... if (out!=&cout) delete out;//この部分が見苦しい気がする。 return true; } それと、 new ofstream(1)とかできるものもあるようですが、この場合 デリートしても大丈夫なのでしょうか。 お願いします。
>>246 引数をstd::ostream&で受けるようにしたらどう?
あとファイルオープンが失敗したかどうかにはgood()がある。
参照の配列が宣言できないってことは・・・関数に渡す時はポインタにしてループさせないといけないんですか?
>>247 レス有り難うございます。試してみました。
bool func(const string& str=string("no string"),ostream& out=fstream("out.txt"))
{
if (out.good())
{
out <<str << endl;
}
else{cerr << "ふあいるあかない"<< endl;return false;}
return true;
}
こんな感じでよいのでしょうか。
それと!fstreamというのを見つけました。これはgood()とほぼ同じなのでしょうか。
bad()というのがあるようですが、good()と反対の機能でしょうか。
(fstream(1)としてファイルに出力する場合のみclose()してopen("out.txt")したかったの
ですが、これはうまくいきませんでした。)
>>248 参照の配列はないけれど配列の参照はある
3重ポインタを使い、熱伝導方程式を解こうと思いました 5×5×5の立方体型配列のうち、表面にある要素は1.0、 内側にある要素は0.0として、適当なアルゴリズムに従い 内側に熱が伝わっていくようなものです。 それで、まずC言語で int i,j,k; int count=0; double a[5][5][5]; double ***s; s= (double***)malloc(125*sizeof(double**)); for(i=0;i<5;i++) { s[i]=(double**)malloc(25*sizeof(double*)); for(j=0;j<5;j++) { s[i][j]=(double*)malloc(5*sizeof(double)); for(k=0;k<5;k++) { if(i==0 || j==0 || k==0 || i==4 || j==4 || k==4) { s[i][j][k]=a[i][j][k]; } } } } などとして、sを計算結果を一時的に溜める配列にするのは成功しました
252 :
251 :2005/06/19(日) 04:31:54
しかしその真似をして、C++で int i,j,k; double a[5][5][5]; double ***s; double ***s=new double **[5]; for(i=0;i<5;i++) { double **s=new double*[5]; for(j=0;j<5;j++) { double *s=new double[5]; } } for(i=0;i<5;i++) { for(j=0;j<5;j++) { for(k=0;k<5;k++) { if(i==0 || j==0 || k==0 || i==4 || j==4 || k==4) { s[i][j][k]=a[i][j][k]; } } } } などとしても、最初のdouble *s=new double[5];の部分で「sに代入した値は使われない」 というエラーが出てしまいます
253 :
251 :2005/06/19(日) 04:33:56
最初のmallocではどうにか動いたので、C++でもやるかと思って 同じ形式で作ったら動かずショックでした。 2重ポインタまでは参考資料を見ながらCでもC++でも 出来たのですが、3重ポインタをC++で使う段階で困っております どのようにして解決できるでしょうか。ご教示お願いします
よく分からんが、固定サイズの配列であるのなら、なぜわざわざ 動的に確保するの?
ブロック内宣言は
>>252 それじゃC++とCとでまったく別物になっているが……。
あとなぜ125個やら25個も確保しているのかわからん。
s= (double***)malloc(5*sizeof(double**)); → s = new double **[5];
s[i]=(double**)malloc(5*sizeof(double*)); → s[i] = new double *[5];
s[i][j]=(double*)malloc(5*sizeof(double)); → s[i][j] = new double[5];
257 :
251 :2005/06/19(日) 09:03:09
>>256 さん、無事動くようになりました。
本当にありがとうございました。助かりました
仮想関数で陥りやすい罠なんかを紹介しているサイトはないですかね? まさに今自分がハマったっぽくて、 ソースをうpしたいところなんですけど、ちょっと長いんで。。。
>>258 ソースを詰めるいい訓練だと思って。
つーか、案外その過程で罠が見つかるかも知れんし。
260 :
258 :2005/06/19(日) 13:50:08
事故解決しますた。
ハマってた問題は、
派生クラスの仮想関数は問題なく呼べるのに、
基底クラスの仮想関数を呼ぶとAccess Violation、
というものだったのですが、
基底クラスのコンストラクタの
memset(this,0,sizeof(*this));
が原因ですた。
classって謎のメンバ変数を勝手に付け加えるんですね。
自分で定義したメンバ変数はint型のが5つで20バイトのはずなのに、
sizeof(*this)が24バイトなんですもの。
C++訳わかんね。('A` )
あ、
>>259 さんありがとう。
>>260 memset はいかんね。
vtable でも知れば、納得できるようにはなるだろう。
void CEnemy::Init() { for(int i=0; i<MAX_ENEMY; i++) { x = 100+i*20.0f //とりえあえずずらして表示; y = 100+i*20.0f; //同上 w = 64; h = 64; tx = 0; ty = 0; //pEnemy++; のような感じで次の番号に行きたい } } っていうのは void CEnemy::Init(CEnemy* pEnemy) { for(int i=0; i<MAX_ENEMY; i++) { pEnemy->x = 100+i*50.0f; pEnemy->y = 100+i*50.0f; pEnemy->w = 64; pEnemy->h = 64; pEnemy->tx = 0; pEnemy->ty = 0; pEnemy->fAct = ACT; pEnemy++;//次の番号に行きたい } } こうするしかないんでしょうか? ++とかで配列の次の番地にアクセスできないんですかね?
>>262 配列なら ++ で次の要素にアクセスできるよ。配列ならね。
newで確保したのを「配列のように」使ってる場合も ++; で次の要素にアクセスできるんですか?
>>264 確保した個数を越えなければ別に問題はないだろうけど、クラス設計としてはなんだかなぁ……
>>264 「配列のように」なんて曖昧な言い方されても意味がわからん。
配列を new で確保したのなら大丈夫。
267 :
262 :2005/06/19(日) 14:43:46
>>267 単純な話。
CEnemyが敵個体を表すクラスならば、そのメンバであるInit()はそのメンバ変数を初期化するに留めるのが普通の発想。
関数に渡すなら ・配列とそのサイズを引数で渡す ・サイズをメンバに持たせたクラスをつくる ・STLのコンテナを使う
>>267 何がしたいのかわからないと、設計なんかできませんよ。
自分以外の人が読むことを考えて書き込みましょう。
271 :
262 :2005/06/19(日) 15:03:00
>>270 CEnemy* pEnemy = new CEnemy[MAX_ENEMY]; で宣言して
BOOL Initialize(HINSTANCE hInst,HWND hWnd,CMyChar& rMyChar,CMyWeapon& rMyWeapon, CEnemy* pEnemy)
に送り そこから pEnemy->Init();か pEnemy->Init(pEnemy); で初期化をしようとしています
全てを初期化するには・・・ 中でループを回そうと思ってるんです
そこで・・・ pEnemy->Init();の場合だと 次の要素にアクセスできない?ので困ってます
アホかい。 敵複数を初期化する関数から、個別に初期化する関数を呼ぶって発想はできないんか? もう少し突き詰めて考えてみよう。 どうやらInit()で書いていることから察するに、敵個体間には初期状態で一定の間隔を置いて配置したいのだろう? それは、敵個体の特性か? それとも敵複数の特性か? #或いはフィールドの特性の可能性もありそうだが。 それを敵個体の特性と位置付けてしまうと、敵の配置を変えた新しいフィールドを作るたびに設計変更になるぞ。
274 :
262 :2005/06/19(日) 15:18:15
>>272 , 273 あ そうですね 敵を初期化する関数っていうワンクッション置いてから個別に初期化するのがいい方法でしたか・・・ rCMyChar.Init();で自キャラは全て初期化してますし
同じようにやりたかったので 外ではループを回したくなかったんですよ
ワンクッション置いてやってみることにします
敵個体の特性っていうのはどういったことですか?・・よく解りませんorz
初期化はできるだけコンストラクタを使うようにしてください。
>>274 敵個体の座標というのは敵個体の特性(言い方悪かったなぁ属性というべきだったか)だろ。
敵個体の初期位置というのは敵個体の特性かどうかを考えよ、と言ってる。
多対一の対戦を行なうゲームか何かだと思うが、何が何でも敵を全体として扱うのはナンセンスだ。
大雑把に考えると、
敵全体
├敵1
├敵2
:
└敵n
と言う関係にあるだろうから、
ゲーム全体の初期化
├→自キャラの初期化
└→敵全体の初期化
├→敵1の初期化
├→敵2の初期化
:
└→敵nの初期化
となることに別に問題はなかろう。
277 :
262 :2005/06/19(日) 15:38:31
>>276 おぉ ありがとうございます。 ものすごい解りやすい・・・
私は今アクションゲームを作ってまして、ものすごい参考になります
ありがとうございました。
これで敵が群れになって移動してくるなら、 敵全体 +敵グループ1 +敵1 +敵2 +敵グループ2 +敵1 とかになるわけだなw
そこで Compisitパターンですよ
280 :
262 :2005/06/23(木) 23:41:54
すいません ちょっとつまづいたので教えて下さい グローバル変数で CEnemy* pEnemy = new CEnemy[MAX_ENEMY]; という風に敵を作ってます。 それで今から敵を追加していくところなのですが 敵の種類を宣言時に持たせたいため CEnemy* pEnemy(1) = new CEnemy[MAX_ENEMY]; ↑敵の種類 (コンストラクタでCEnemyのメンバのkindに代入) というようにしたいと思ったのですが これはできないみたいで・・ どのようにしたら解決できますでしょうか・・
>>280 やはりそこにきたか。
[ ] による配列では各要素のコンストラクタを制御するのは不可能。
すべてデフォルトコンストラクタが使用される。
基本的な代替は以下のふたつ。
// ポインタの配列
// - いっこずつ生成するのが面倒
// - アクセスが面倒
// - delete が面倒
CEnemy* enemies[MAX_ENEMY];
enemies[0] = new CEnemy(1);
// std::vector
// - いっこずつ生成するのが面倒
// - CEnemy のコピーコンストラクタ、代入演算子を確認する必要がある
std::vector<CEnemy> enemies;
enemies.push_back(CEnemy(1));
282 :
262 :2005/06/24(金) 00:14:47
なるほど・・・ int a(5)とかがあるなら配列の初期化としてつけてもいい機能ですよねぇ ポインタの配列でやってみます。。。しかしながら他に方法はないのかと思ってしまいますw
>>281 ポインタの配列なら、
std::auto_ptr<CEnemy> enemies[MAX_ENEMY];
にすると、「delete が面倒」という問題は解消される。
ただし std::vector<std::auto_ptr<CEnemy> > は不正だ
ということを理解していないのなら使わないことをお勧めする。
>>280-281 関係ないが、「〜の数」を MAX_〜 にするのはどこの文化だ?
いろんなところであたりまえのように見るが、激しくキモイ。
285 :
262 :2005/06/24(金) 00:29:13
>>283 そこらへん全くもって解りません・・・ 学校ではいつも
#include <iostream>
using namespace std; を使ってますが理由っていうか効果が解ってませんしw
「〜の最大数」をMAXで表現しないでどうするの? 相手を理解しようとしないでキモイと言うのは如何なものかと
チョンだなw
イタタタw
289 :
284 :2005/06/24(金) 00:41:14
>>286 MAX_〜 は「最大〜」という意味なのに、「〜の数」の意味まで含むようになってるのがキモイ。
「敵の最大数」が MAX_NUM_ENEMIES じゃなくて MAX_ENEMY なのがキモイって話。
キモイを連発してまで本筋でないところにツッコミ入れている 輩のほうがよっぽど(ry
292 :
デフォルトの名無しさん :2005/06/24(金) 00:44:38
ほんとに関係ないな
MAXとかNUMとか略してるのはキモくないのかw
>>293 もうね、そんなレベルじゃない。
俺の思想以外は全部キモイw
もう書き込まずには居られない。
MAXIMUM_ENEMY とかって強そうだな
THE_MAXIMUM_NUMBER_OF_ENEMYS
どうでもいいようなことまでケチつけるから、 ソース公開する人が減るんだと言っt
ごめん、ENEMYSだけは許せない
うはwwオレ、ENEMY_S だwww
MOBS でいいじゃん
302 :
262 :2005/06/24(金) 21:23:31
あ〜 解りません・・・未だにつまづいてるのでご教授お願いします CEnemy* pEnemies[MAX_ENEMY]; pEnemies[0] = new CEnemy(1); として宣言しようとすると[error C2466: サイズが 0 の配列を割当てまたは宣言しようとしました] が出てきます。 あと中身についてなんですが pEnemies[0] = new CEnemy(1);というのは1個だけしか生成されませんよね? ってことは同じ種類の敵を複数出す時は pEnemies[1] = new CEnemy(1); pEnemies[2] = new CEnemy(1); pEnemies[3] = new CEnemy(1); みたいにするんですかね?・ ホントに初歩的?なところだと思うんですがよろしくお願いします
303 :
262 :2005/06/24(金) 21:25:10
あとdeleteが面倒というのは delete[] pEnemies[1]; delete[] pEnemies[2]; delete[] pEnemies[3]; のように1個づつ解放しないといけないってことですか?
>>302 MAX_ENEMYがおかしいんじゃないの?
>>303 newで割り当てているからdelete、delete[]ではない。
そう1つずつやらなくともforとかforeachとかが使える。
deleteが面倒とか言ってる奴は ポインタ使うな。 C言語使うな。 C++使うな。 javaなりC#なりに行って帰ってくんな。
#include <iostream> using namespace std; class CEnemy { int a; public: CEnemy(int x) : a(x){ cout << "construct" << endl;} ~CEnemy(){cout << "destruct" << endl;} }; #define MAX_ENEMY 5 int main() { CEnemy *p = new CEnemy[MAX_ENEMY](1); delete[] p; return 0; } [実行結果] construct construct construct construct construct destruct destruct destruct destruct destruct おや、コンストラクタ、デストラクタちゃんと呼ばれてるな。 gnu gcc 3.3.3 (cygwin)
>>306 元は要素のコンストラクタにはそれぞれ別々の引数を渡したいという話だったと思うが。
factory class でもつくれ。
こうだな。 class CEnemy { float x,y,w,h,tx,ty; public: CEnemy() : x(0.0),y(0.0),w(64.0),h(64.0),ty(0.0),tx(0.0){} void SetPos(float xpos, float ypos){ x = xpos; y = ypos;} }; #define MAX_ENEMY 10 int main() { CEnemy *p = new CEnemy[MAX_ENEMY]; for(int i = 0; i < MAX_ENEMY; ++i) { float f = 100.0f + i * 20.0f; p[i].SetPos(f, f); } // delete[] p; return 0; }
310 :
262 :2005/06/24(金) 23:19:58
うーん BOOL Init_Enemy(CEnemy* pEnemy, int no) という関数を作り if(no==1){ 敵1の初期化 } とした方がいいですかね アイテムも同じように作るつもりなので、あまり関数が複雑化するのは避けた方がいいですよね
std::vector<CEnemy>にしてpush_back()で詰め込んでいくってのは駄目?
>>311 CEnemyから派生させたいからダメ
std::vector<boost::shared_ptr<CEnemy> >
ならおけ
>>310 その説明じゃ、やりたいことが全然わからん。
複雑でもないと思うし、複雑化をそんなに厭う意味もない。
複雑な処理は関数化して、いつでも使いまわせるようにするのが、
構造化なりオブジェクト指向なりなわけだから。
314 :
262 :2005/06/25(土) 00:19:28
あ はい、すいません 宣言は CEnemy* pEn1 = new CEnemy[MAX_ENEMY]; CEnemy* pEn2 = new CEnemy[MAX_ENEMY]; とし初期化する関数へは pEn1->Init(pEn1,1); pEn2->Init(pEn2,2); とするということです
それじゃ、それぞれのオブジェクトが別々の配列にはいっちゃって キモチよく一緒につかえないだろ
Initの中では何をするの?
317 :
262 :2005/06/25(土) 00:42:30
それが難点で・・。。。 ゲームを作ってる方々はどのように管理してるんですかねぇ それと ゲームを作る際におおまかな関数の作り方が載ってるサイトとかありませんかね? 私は 初期化 処理 表示に分けて 更に 初期化 - テキスト読み込み - 画像読み込み 処理 - 移動 - 攻撃 表示 - 表示 といった感じにして 当たり判定は別個に作ってます・・ 就職用作品なのでできればソースを綺麗にしたいのでよろしくお願いします
コードを書く前に、なにがやりたいのか伝える訓練が必要だな。
そして面接ではそちらの方が重視されたりもする
キャラクターのクラス情報は共有してフライトウィジパターンにする。 インスタンス情報の初期化はループをまわして、全員スタンスに対して行う。
321 :
デフォルトの名無しさん :2005/06/26(日) 06:15:58
普段、関数などを調べる際に新ANSIC言語辞典(平林)を使用しているのですが、 C++でそれに似たようなものはないでしょうか?
googleマジレス
>>321 オライリーから出てる
C++ランゲージクイックリファレンス/C++ライブラリクイックリファレンス
平林は「ANSI C/C++辞典」も出してたよ
このスレ読んでて思ったけど、やっぱりEffectiveシリーズのような推薦図書スレで 挙げられてる必読書って読む価値あるんだな〜。 あれを読まずにC++でいきなりクラスを実装できる人っているんだろうか
>>325 半年くらい試行錯誤しながらクラスを作っていたら、
その間に身につけたノウハウが全てEffectiveC++に書かれていた。
いきなりEffective読んでも、実感がわきにくいからな。
とりあえずいきなりジェネリッククラスから。 再利用可能なコンポーネントは美しい とりあえずWTLのオーナーデータリストビューとかに生かしている
C++ではコンストラクタを持ったクラスを 共用体のメンバとして持つことは不可能なのでしょうか?
>>329 できない。逆にできたら困る。
ただし、もしかしたらboost::variantが代わりになるかもしれない。
>>330 やはりできませんか。。。
よく考えたら確かに2つ以上のクラスが
ある場合とかだと大問題ですね。
boost::variant調べてみます。
ありがとうございました。
C++でプログラムをするには、クラスを作らなければならないから、面倒だな。 クラスを作ってる間に、Cで目的のプログラムを作れてしまいそうだ。 クラスを作ることそのものが目的で、学習のためならともかく、実用ではなかなか 使う機会がないんだが。
小規模なプログラムならクラスは別に必要ない
>>332 クラスを作らなくてもプログラムは動くだろ。
好きにすればいい。
>>332 別にクラスつっても、ライブラリについてるようなフル装備の
汎用的な型にする必要はないからな
そんなに構える必要は無い
どのみちJavaやC#なら、全部クラスなんだから
フル装備の汎用型てww
>>336 クラス作る際にstd::stringやSTLコンテナみたいな気合の入った設計を
毎度毎度する必要は無いよ、という程度の意味。
そもそもCの書き方も使えるというのもC++の売りの1つ。 Better Cとしてもそれなりに使う価値はあるよ。
C++は、他人の作ったライブラリを使うなり、 自分でライブラリをそこそこ作り上げてからが本番な気がする。 行数とかで比較すりゃ全体的にはどうやったってC++の方が多くなるからな。
C++にはSTLがあるから、そんだけで 格段に短く書けることが多いぞ まあ簡単なプログラムなら手続き+STL利用 ぐらいで全然かまわんわなあ。
>>332 クラスを作るのが面倒って、構造体を作るのと手間は変わらんと思うんだけど。
>>341 自分が理解できてないことに対する言い訳だろ。
>>342 構造体もまともに設計できていないなら兎も角、きちんと構造体を設計できるなら
クラスの設計も概ね巧くいくと思うぞ。
まぁ、継承まで考え始めれば話は別だが。
GUIはCよりC++の方が楽だろう。 コレクションもC++の強みだな。 この二つだけのためだけでもC++は使う価値がある。
>>343 Cの構造体設計とクラス設計をごっちゃにするのは流石にどうかと。
構造体はただのデータの入れ物であって、ADTではないから
その演算や振る舞いを考える必要は無い。
>>345 「継承まで考え始めれば話は別」って書いてるのに何言ってるの?
継承以外にも考えるべき要素はあるだろ
はー、重箱
ハァ?
質問。 メンバにユーザー定義型が入った構造体でテーブル作ろうとすると、 初期化のときに該当するメンバじゃなくて構造体に代入しようとするのは なんでですか? メンバが組み込み型なら普通に構造体のメンバに代入してくれるのに。 例: typder struct { CString str; int i; } foo; foo Arrayfoo[] = { {"abc", 1} ,{"efg", 2} } ↑ "abc"をfoo[].strに代入してるつもりなんだけど fooにキャストとしようとして失敗する。
そういう仕様だから。 そして深くは考えない。 structはデフォでメンバがpublicなクラス (ただしコンストラクタを持たないstructはC構造体互換といえる) ちなみにCStringはコンストラクタを持つので、C構造体スタイルの初期化には対応して無い、と。
>>351 こんな遅い時間にレスどーもです。
fooをstructからclassにしてみてもダメでした。
要はテーブル作るときは組み込み型に限定するか、
諦めて他に代わりのデータ構造を考える、と。
あまり深く考えず、覚えてしまうことにします。ありがとうございました。
>>350 ,352
まずC++だからtypedef struct {} foo; などと書かずに素直に struct foo {}
と書けばよろしい(Cだとしても構造体のタグ名は定義しておいたほうが
いいことが多いが)。
で、この場合は、素直にfooにコンストラクタを定義すればいいんじゃないの。
そうすれば、
foo Arrayfoo[] = { foo("abc", 1), foo("efg", 2), ... };
と書ける。
354 :
350 :2005/06/30(木) 03:27:57
>>353 なるほど、今の仕事で見てるソースではtypedefしてない人もいたから
もしやと思ってたけど、C++だとstructつけなくても構造体変数の定義ができるんですね。
>>foo Arrayfoo[] = { foo("abc", 1), foo("efg", 2), ... };
これは自分では思いつきませんでした。参考になります。
>>354 念のため書いておくが、別にCでもtypedefは必須というわけではない。
struct foo {};
でよい。ただしこの場合、使うときにはいつも
"struct"を付ける必要があり面倒だからtypedefする人が
多いというだけだ。
C++ではstructに対するそういう差別は無い。
なんだ。VC6か。
>>341 クラスを作るほうがかなり面倒だ。
>>343 理解できてようが、クラスを作るのが目的ではなく、また、必要としないときにわざわざクラスを作るのは無意味だ。
>>358 >クラスを作るほうがかなり面倒だ。
理解できてない証左だ。
>>359 class と struct の機能がほとんど同じだからといって
クラスと構造体を同じように実装するとでも考えてるのか?
データ型としての性格が強ければ構造体、 メソッドパッケージとしての性格が強ければクラス、 きっちり線引きできるもんじゃないっしょ?
俺は基本的にクラス使う方向だな。 struct Point { int x, y; }; みたいに単純なのは構造体にしたくなるってのもあるけど、拡張しようと思ったら結局クラスにしたくなるし。 よっぽど使い捨てにしか使わない自信があって且つpublicと書くのが面倒な時は気まぐれで構造体使うかも。
1. とりあえずstructで書く。 2. コンストラクタやメンバ関数を追加してみる。 3. 折角なのでアクセサ付けてメンバ変数をprivateにしてみる。 4. 「…アレ?」
5 structをclassへ書き換える。
>>358 クラスなんぞつかわんでも
要するにCだけでカーネルもエディタもコンパイラも組めるから
「必要としないときに……」
と言ってしまうと、ほぼ常に「必要でない」と言えてしまう。
その方がラクかどうか、対象をより適切に見通しよくモデル化できるかどうか、
といった視点も必要だろう。
なくても作れる≠必要としない
>>367 彫刻を掘る時、ノミではなくミシン針でやってやれないことはない。
= 無くても作れる = 必要としない
とすると、ノミ = ミシン針
ということになるが、逆に、ノミで裁縫することは不可能である。よって矛盾する。
従って、なくても作れる != 必要としない。
>>368 それは
A) 彫刻を彫るにはノミは必要じゃない
という命題から
B) 裁縫するにはミシン針は必要じゃない
という命題は導出できないと言ってるだけで、
Aそのものを否定していることにはならない。
必要でない -> 必ず要るわけではない これに対し「なくても作れる」はなくてもよい事象を作るに限定したものである。 ∴なくても作れる≠必要としない
>>370 だから、反例を述べよといっておるのだ。
その「なくてもよい事例」に該当しない例を上げよ、と。
まあ、「C++専用ライブラリを使うプログラム」とかは C++じゃないと書けないわけだが そんなんを例といわれても僕困っちゃうわけだが
>>371 逆に質問するが みかん≠スイカ の反例を述べよ。
君の質問はこれに等しい。
よくわからんなあ。 クラスが無くても作れるとしたら、そのときにクラスは必要じゃなかったんだと 思うのだが。 無くても作れるけど、必要、という状態の例って、どんなだ?
>>374 バニラアイスクリーム作りにおけるバニラエッセンスのようなもんでないの?
なくても作れるけど、完全なバニラアイスではないよ、完全なものを作るにはどうしても必要だよ、と。
んで反例だけど、Cでプログラム書くのに、Pascalのコンパイラ環境はなくても作れるし、そもそも必要
ないってことでFA?
完全て、どんなだ(w
LinuxカーネルはCでかかれているから不完全なのであって、
C++なら完全なものにできた、とでも言いたいのか(w
俺の主張は
>>365 だ。後ろの二行。
ちなみにその反例は、反例になってない気がする。
1) クラスがないと作れない、という例
2) クラスがなくても作れるが、クラスは必要、という例
を俺は問うているんだが。
>>376 日本語理解できるか?
「無くても作れるけど、必要、という状態」の一般的な例を挙げただけで、誰もLinuxだのC++だの
固有名詞は挙げてないぞ。
後は知らん。
くだらん論理学的な遊びはよそでやってくれ、ここのスレタイ読めてるか? もっと実際的な話をしろよ
>>377 なるほど、そういう文意だったのは理解したが、
その例は正しくないな。
バニラエッセンスがなければ、バニラエッセンスつきのバニラアイスは
作れない
んだから。
それは「作れている」とは言えない。
正直スマンカッタ。 暇で暇で、むしゃくしゃしていた。どのスレでもよかった。今は反省して(ry
おもしろいから、もっと議論してくれ。
事実:バイナリエディタさえあればプログラムは作れる。 →では、ありとあらゆる高級言語は「必要ない」のか?
>>382 そういうことは実際ある程度の規模のプログラムをバイナリエディタで
組んでみてから言ってくれ。
理論的に出来る、だけなら作れないと言ってるのと同じ。
できなければ、高級言語はあんたには、「必要」なんだ。
おそらく、384は誤解をしてるようだ。 382は、384の言うようなことを喚起するような意図で、問題を投げかけたのだと 思われる。
386 :
デフォルトの名無しさん :2005/07/02(土) 20:05:05
高級言語から入ったプログラマでも、やはり言語というものが 発展してきた歴史を学ぶことは必要だね。
俺は今更FORTRANだのCOBOLだの触りたくないぞ
まさに不毛ですな
既存のクラスを利用するだけなら、まだいいが、いつもクラスをわざわざ作るのが、あたかも 必須であるかのような考えには疑問を抱く。 俺の場合は、プログラムは大規模にはならず、クラスを作ることはどうでもよく、それよりもまずは、 目的の処理を実現するアルゴリズムを考えることに頭を使わなければならないことが多い。 C++をやるなら、クラス設計よりも、STLをうまく使いこなせるようになるほうが重要だと思ってる。
>>389 > C++をやるなら、クラス設計よりも、STLをうまく使いこなせるようになるほうが重要だと思ってる。
うむ、確かにそうだな。いいこと言った。が、
> 俺の場合は、プログラムは大規模にはならず、クラスを作ることはどうでもよく、それよりもまずは、
> 目的の処理を実現するアルゴリズムを考えることに頭を使わなければならないことが多い。
まずデータ構造(クラス)を定義したほうが、アルゴリズムに頭を悩まされる負担が減るってもんだ。
とは言っても俺も
> いつもクラスをわざわざ作るのが、あたかも
> 必須であるかのような考え
ではないので、この部分も同意。
ところで
>>389 のこの話、やや唐突だなw
どこにレスしたんだ?
>>390 >ところで
>>389 のこの話、やや唐突だなw
>どこにレスしたんだ?
>>332 で書き込んでが、かなりの反響があったようで、それについて議論してる人全体が
対象ってもんで、特定の一個人へのレスではないし。
>>390 アルゴリズムとデータ構造の決定について
どっちが先ってことはないんじゃない?
ほぼ同時に決定するって感じ
でも,STLだと(シーケンスに限っていえば)アルゴリズムとデータ構造の 独立・直交性が高いので,とりあえずで進んでいって後で 詰まったときにある程度の手戻りが効く. これもある程度以上は限界があるけれど.
クラスを使わないほうが効率がいいときにわざわざクラスを使うのは無能。 クラスを使ったほうが効率がいいときにクラスを使わないのと同様に。
で、そもそも「クラスを作るのが面倒」って言い始めた理解の足りない
>>332 はどこへ逝った?
汎用関数はともかく、汎用クラスなんか 使いこなせる気がしねええぇぇーー orz
汎用関数、汎用クラスって何ですか?
×汎用関数 ○関数テンプレート ×汎用クラス ○クラステンプレート ってことか? 何で関数テンプレートとクラステンプレートって 使ってる感覚はいっしょだと思うけどなぁ。 >396 がクラス使うのに慣れてないだけじゃない?
400 :
396 :2005/07/03(日) 16:29:11
×汎用関数 ○関数テンプレート ×汎用クラス ○クラステンプレート ↑の変換でいいかと。 クラスは慣れてないです。 最初は使わなくてもいいですかね?
>>400 クラスの利点を知らないのなら、使う意味は無いよ。
いいよ。 C++なんか生きていく上で必要ない。 忘れなさい。
>>401 >>402 あー、ごめんなさい。
クラステンプレートは使わなくていいかな?
ってことです。言葉足りなくてスマソ。
クラスに慣れてから、ちょっとずつ
ステップアップしたほうがいいのかなーと。
>>404 クラスとクラステンプレートとに同時に慣れる必要はないと思うよ
何かクラステンプレートを作るのはずっと後でいいが、使うのには慣れろ。(STLとか)
トップダウンに「クラスを見つける」ことになれていない、それが 難しいと感じるのであれば、ボトムアップにやればよいんじゃないかな。 Cスタイルで構造体やそれを操作する関数は使ってると思うが、そういうものを クラスにしてみることだ。 ただの構造体よりはコンストラクタがついている方が扱いやすいし メモリの開放が必要ならデストラクタを付けてみる。 構造体を操作する関数をメンバにしてみる。
構造体が理解できていれば、クラスに入るのも難しくないだろう。
普段からどういう風にCを使っているかによるよな。
つまり、人による、と。
そういうことだな
>>405-408 レスありがとうございます (ノω`)・゚・。。
STLはやぱ、使っといたほうがいいのか。。
恥ずかしついでに言っちゃいますと、
クラステンプレート
例外処理 (スローとかなんとか・・)
実行時型情報 (typeinfo・・なにそれ?)
テンプレートライブラリ (いっぱいありすぎ orz)
C++の入出力システム (cout.??? とかios::??? みたいなやつ)
ファイルの入出力 (<fstream>ヘッダの中のやつかな?)
あたりを全部すっ飛ばしちゃおうかと考えてるんですが、
↑で挙げてるやつで、これは最初にやっといたほうがいいってやつは
ありますか?
ちなみに、今の所の近場の目標は、
windowsスケルトン組んで、絵を出して色々やろうかと
思ってます。
Cは一通りやりました。
>>413 例外処理を学べばいろいろついてくるぜ。
>>413 STLは使うと使わないでは著しく開発効率が変わってくる。
ちょっとしたプログラム以上のものでは大概STLで提供される
コンテナやアルゴリズムを必要とするからな。
昔からコンテナライブラリみたいなものはあるが、STLはそうしたものに
比べると、革命的なほど強力で洗練されたライブラリだ。これのためだけに
C++を使う、というヤツも多い。
で、「すっとばす」と言ってるヤツだが、クラステンプレート、例外処理は
使えるようにはなっておけ。全く知らないと、そういうものを利用した
ライブラリが使えなくなる。
RTTIやiostreamはすぐには知らなくてもいいかもしれん。特に後者は
Win32で開発するならば、今後もあまり世話になることは無いかもしれない。
>>414 >>415 なるほど、説得力ありますね。
この2ヶ月ほどC++の言語の勉強ばっかしてきて
まともにプログラムを打ってないので、
なんかもう、とにかく早くクラスを使って慣れたほうが
いいんじゃないかと思ってまして。。
ちょっとキレ気味で orz
とりあえず、例外処理を一通りやってみます。
どうもありがとー m(__)m
>>413 実行時型情報はたしかにどうでもいい。そんな機能もあると知っているだけでいい。
入出力は<<で出力して、>>で入力ということさえ知っていればとりあえずは困らない。
例外だけはWindowsの世界へ足を入れる前にやったほうがいいな。
テンプレートと言えばSTLじゃないが、std::stringは知っておいて損はない。
演算子とlength()とc_str()を知っているだけでも全く違ってくる。
まあWin32ならCStringTや_bstr_tを使う機会のが多いだろうけどな(w
そうか? 俺はWindowsでもtypedef std::basic_string<TCHAR> tstring;で通しているが。
>>419 幸せなヤツだな
そんなことをやっても
find_first_ofなどのメンバ関数で_tcs系の関数が使われるわけではないから
MBCSでは全然NGだし
CStringTや_bstr_tにあるMBCS<->WCSの変換機能も無いだろ
まぁあれだ、CObArrayは使うなと。
>>417 std::stringはこの板でよく見かけますね。
char型の、文字列専用強化版みたいなものでしょうか。
文字列はwindowsプログラムでも使う予定ですし、
ヒーヒー言いながら、やってみたいと思います。ども。
いただいたレスを読み返してみると、
クラステンプレートも、作り方と使い方は知らないとダメっぽいですね。
あと、
C++の勉強を始めたら、やたらとリスト構造(自己参照構造体?)
をよく見かけるのですが、
C++使うなら理解を深めとく必要があるんでしょうか。
C++はstaticをあんま使わないらしいので、
newで確保したメモリを、リスト構造で管理することが多くなるのかな。
でも、リスト構造ちょっとややこしいよ、ママン。
424 :
422 :2005/07/03(日) 18:55:56
まあ何だ、MFC/ATLのコンテナは使い物にならんから、コンテナや アルゴリズムはSTLのを使え。ただしマルチスレッド環境では気をつけろ std::stringに関しては、CStringTのがWin32では良いサポートを提供 しとるから、後者を使え ってとこかな
426 :
デフォルトの名無しさん :2005/07/03(日) 19:46:18
みなさん、お詳しいですね。 能書きは要りませんので、原典だけお教え願えませんか?
428 :
426 :2005/07/03(日) 21:19:45
429 :
419 :2005/07/03(日) 22:09:37
>>420 MBCSが問題になるようなときは専らstd::wstringを使う。
MBCSとWCSとの変換はATL::Cx2xを使っている。
いちいちc_str()を呼ぶのはダサいと思うが仕方ない。
430 :
デフォルトの名無しさん :2005/07/03(日) 22:26:24
C++を覚えるにあたりAccelerated C++を購入し読んでいるのですが、P.20で出てくる『不変量の表明(不変な表明)』という用語があるのですが、これってどういう意味でしょう? 読んでても、よくわからないのですが...
>>429 そこまでしてstd::basic_string<>にこだわる意味は全く無いと思うんだが...
GetBuffer()も無いから、無用なalloca()、またはstd::vector<>との
変換も、結構必要だろ?
>>431 いや、私はstd::stringとバッファを組み合わせて使いたいときには
(どうせそのバッファは一時的でいいはずだから)固定char配列かnewして使う。
まぁ、GUI絡みだとCString使うけどね。
433 :
デフォルトの名無しさん :2005/07/04(月) 09:58:28
しーぷらぷらちょーまじおもしれーwwwwwwwwwwwwwwwwwww
434 :
426 :2005/07/04(月) 11:29:16
>>433 どのへんがどうチョーおもしれーのかも語ってちょ
〃〃∩ _, ,_
⊂⌒( `Д´) < 参照渡しじゃなきゃヤダヤダ
`ヽ_つ ⊂ノ
ジタバタ
_, ,_
(`Д´ ∩ < char*じゃなく、std::stringじゃなきゃヤダヤダヤダ
⊂ (
ヽ∩ つ ジタバタ
〃〃
〃〃∩
⊂⌒( _, ,_) <うにコードって何?SBCSの国に産まれたかったよ・・・。
`ヽ_つ ⊂ノ
グスン・・
>>430 そのへんはスルーして問題なし(と思う)。
ていうか、俺はした。
うにコードは別にCからC++への移行とは何の関係もないな。
あるオブジェクト指向ロマンスの一場面。 A: 「あなた、いつまでも変わらないでいてね」 B: 「安心しろ。ぼくはconstだ」 …の一節が好きなのでC++使います
A: 「あなた,あの時変わらないって言ったじゃない!!」 B: 「うるさいな.const_castしたんだ.」
コンパイル時に下記のようなエラーが出ます。 acx.cpp:124: error: cannot call member function 'void acx<Type>::PB(int, int) [with Type = float]' without object エラー内容がオブジェクトなしではPBという関数を呼び出せないという事はわかるのですが、その原因がわかりません。 呼び出し行は if (ii==0)PB(k,endpnt); なのですが、エラーとなる原因は何なのでしょうか?
>>441 >エラーとなる原因は何なのでしょうか?
オブジェクトがないのでしょう。
メンバ関数以外から呼び出したいなら、オブジェクトを指定する必要がありますね。
或いは、静的なメンバ関数からの呼び出し場合もオブジェクトを指定する必要があります。
#メンバ関数のつもりで非メンバ関数を書いている気もするが。
スコープは解決できてるみたいなんで静的なメンバ関数から普通のメンバを呼び出そうとしてるんでしょ。
444 :
デフォルトの名無しさん :2005/07/15(金) 07:53:32
C++を習得した君 そこで安心してはいけない 次はC++0xだ
は?
C++ のつぎは C+++ にきまっとる。 俺なんか C++++++++++++++++++++++++++++++++++++++++まで習得したぞ。
>>446 ∧∧
∧ < え >
ヽ. < | >
ノ | < | >
()| < | >
u____つ / !!? >
[_____ U  ̄∨∨
ノ
ヽr
ヽ
C++++ = D だから D++++ == E と考えると、
>>446 は C++++ ++++ ++++ ++++ ++++ ++++ ++++ ++++ ++++ ++++ == M まで習得したんだな。
M、つまりマゾ言語
参照とポインタの使い分けについて教えて下さい 参照はint a など1つしか宣言&初期化しない時に使うと便利で ポインタはint a[10]など配列で宣言し、Init(a);などで関数に送り ループで配列を全部初期化する時に便利ってことで理解してもよろしいでしょうか? また参照で送った場合はどのようにして次の要素にアクセスできますか? (参照でポインタの pEnm++のような事を実現できるんでしょうか?)
>>450 仮にポインタを使うと*か->しか使わず、その他のポインタ演算を全く使わないような場合なら参照。
それ以外はポインタ(あるいはイテレータ)。
> また参照で送った場合はどのようにして次の要素にアクセスできますか?
> (参照でポインタの pEnm++のような事を実現できるんでしょうか?)
int&のような場合は無理。&でポインタを取得すればできるw
そういうのはポインタ(あるいはイテレータ)の出番。
452 :
450 :2005/07/18(月) 19:23:38
>>451 dd ポインタ演算を使わない場合は参照でまとめることにします。
イテレータについてググってきますw
すまんが誰か俺に >448 がどういう理屈なのか教えてクレ
454 :
448 :2005/07/19(火) 22:27:26
C++の次がDということで C++++ → D って書いたけど、 C++とDは別物だとか、そういう厳密な話じゃないから気にしないで
C++ => D C-- => C#
C-- => C♭
もうそういうつまんない記号遊びはいいから
iostreamって全く魅力を感じないんだけど、stdioじゃな くてiostreamを使うことで、得られる利点てありますか? C++ぽくみえるとかそれだけかな。
>>458 algorithmと一緒に使いやすいようになってるとか。
>>458 ・型ごとのフォーマット指定をおぼえなくていい
・template 内の型とか、 typedef された型とかの実際の型を意識しないで済む
・実際にアクセスするデバイスを拡張しやすい
・エラーに例外を使える
現状ではこれらを覆すだけのデメリットがある。
実行速度とか、プログラムサイズとか、コンパイル速度とか。
>・型ごとのフォーマット指定をおぼえなくていい でも、iostream でのフォーマット指定は printf 系のフォーマット指定より16倍マンドクサイ('A`)
中には混ぜると美しくないって言う人が…
そこでboost::formatですよ。
>>462 誰かがsync_with_stdioをいつの間にか弄ってて…
sprintfで書式組み立てて流してる漏れはアホですかそうですか
アホだ。 可変個引数なんてせっかくのC++の厳しい型の安全性が台無しじゃないか。
質問です。 CHoge *p = new CHoge(); とした場合コンストラクタが呼ばれ CHoge *p = (CHoge*)mallock(sizeof(CHoge)); とした場合呼ばれないのが何故だか分かりません。 newは特別なのでしょうか? newをオーバーライドし、すでにmallockしてある領域のアドレスを返してやったら、 これまたコンストラクタが呼ばれました。 とても基本的なことかもしれませんが、どなたかご教授お願いいたします。
>>468 ポインタをキャストしてもコンストラクタは呼ばれません。
つーか、そういうCスタイルのキャストはできる限り使わないようにしましょう。
なるほど。 C++のクラスという機能を使うのですから、C++の流儀にしたがってnewするのが正しいですよね。 ですが気になるのは newをオーバーライドして、すでにmallocしてある領域のアドレスを返してやった場合にもコンストラクタが動作したことです。 void* operator new(size_t t){ void* p; p = malloc(t); return p; } として CHoge* p = new CHoge(); としたところ、コンストラクタが呼ばれたのです。 これはnewという記述の魔法とも思える動作で、非常に納得がいかないのですが…。
newはコンストラクタを呼びます。仮令オーバーライドしていても。
なるほど。 コンストラクタが呼び出されるのは「そのクラス用のメモリーが確保される」という動作が誘発するのではなく、 newそのものに備わっているわけですね。 つまり、newが「ポインターと返し、それがクラスであった場合コンストラクタを呼び出す」 という機能を持つ演算子であると考えればよろしいのでしょうか。 なかなか小癪な奴ですね。 (もちろん、実体を宣言したときにもコンストラクタが呼ばれることは知っています)
>>472 考え方が逆。
処理系定義の方法(或いはオーバーロードして)確保したメモリで
コンストラクタを呼び出すようにnewが作られていると考えればよい。
同じように、デストラクタを呼び出してからメモリを解放するのがdelete。
あーそうそう、コンストラクタはクラスに限らず呼ばれるのでその積もりで。
例えばPOD型なら0で初期化されることが保証される。
さらに詳しい解説ありがとうございます。 ネイティブなものでもコンストラクタ呼ばれてるんですね。
本嫁
このスレの存在意義を否定する発言するなw
>>473 new POD だとCと同様に不定値で
new POD() でゼロ初期化じゃなかったっけ?
a
>>477 8.5-7 と、8.5-9 と、8.5-5 にある value-initialize の部分ですね。
480 :
デフォルトの名無しさん :2005/08/22(月) 04:21:51
C++でboostは将来標準になるのですか? 今からガンガン使って大丈夫でしょうか? あとで廃れてしまうなんて事はあるのでしょうか?
C++自体使われなくなってるから大丈夫
何年か前にも同じ台詞を見たなw
>>480 boost全てが標準になるわけではない。
boost::lambdaとか標準になっても困るっしょ。
少なくともC++は当分の間は消えない。
>>480 boost の一部は標準への取り込みを意図しているものもあります。
基本的にソフトウェアは時間で変質しないので、
今使って大丈夫なものはあとで使っても大丈夫です。
「大丈夫」の意味に依るのかもしれませんが。
将来、 boost が廃れる可能性はあります。
C++ が廃れる可能性もあります。
とある本に「VisualC++はC++を拡張したオブジェクト指向型言語」とあったのですが、VisualC++って言語名だったんですか?俺はてっきりIDEの名前だとばかり思っていたんですが。
>>486 Visual C++ は言語名ではありません。
とある本の名前を晒して、さっさと燃やしてしまいましょう。
488 :
486 :2005/08/23(火) 01:20:53
>その開発環境の1つである「Visual C++」は、プロの技術者もよく利用する、 >C++言語を基盤としたオブジェクト指向型言語で 環境と呼んだり言語と呼んだり、なんなんだ。
>>488 言語と開発環境の区別が曖昧だなぁ。ちょっと信用できないね。
ん?Visual C++は言語名じゃないだろ。皮肉ならともかく。
boostが将来標準になった場合、boost/xx.hは変わらないのでしょうか?
>>492 C++標準ライブラリと同列にヘッダが用意されるのだろうが、
当面は互換性のためにboostからもヘッダが提供されるだろうと俺は思う。
C++が廃れるとか喚いている奴がいるが、別にどんなプログラミング言語でもいつかは廃れる。
そのとき新しい言語にうまく乗り移れればそれで問題ないさ。
boostに、boost/xx.h なんてヘッダはない。
struct HOGE { std::string name; long x, y; } という構造体を初期化したいのですが、どのように記述すればよいのでしょうか? HOGE hoge = { "hogehoge", 0, 0 }; や HOGE hoge = { 0 }; ではだめでした。 それともstringは構造体に使用しないほうがいいのでしょうか?
>>495 アナクロな初期化をしたいのならstd::stringは使えない。
std::stringを使いたいなら自前でコンストラクタを書けばいい。
497 :
495 :2005/08/27(土) 17:51:41
>>496 どうもありがとうございます。
ちょっと考えて見ます。
498 :
デフォルトの名無しさん :2005/08/27(土) 23:38:55
>>495 そういう初期化はできる。
ところで } の後に ; がないよ。
>>496 だからそれは間違っている。
const char *からstd::stringへの暗黙の変換があるから問題ない。
暗黙なのか? 変換できるようなヘッダを読んでるから出きるのではないか? 用語として暗黙の変換というコトバはあるが、 初心者には意味が通じないのではないか?
無理に通じないと思い込んでるだけだな、そりゃ。 どうせ、暗黙の変換なんて他人に教えたこともないんだろ?
501 :
495 :2005/08/29(月) 08:00:56
>>498-500 VisualC++6.0ではコンパイル通りませんでした。
コンパイラが原因?
そうは思いたくないです…。
502 :
デフォルトの名無しさん :2005/08/29(月) 08:04:47
>>501 ざんねんながら、コンパイラが原因。
VC6では対応していない。
>>502 ありがとうございます。他の方法を考えて見ます(´・ω・`)
504 :
498 :2005/08/29(月) 10:23:46
>>499 キャスト・一時オブジェクト作成式を使わずに変換できればそれは暗黙の変換と言う。
それに少なくとも496は初心者ではないと思った。
505 :
496 :2005/08/29(月) 13:12:48
あー確かにconst char *を引き数に取るコンストラクタがあった。失敬。 VC6のMSDN見る限り、VC6にもありそうだけど。
506 :
デフォルトの名無しさん :2005/08/29(月) 19:18:08
C の double* p = malloc(10*sizeof(double)); は、C++ では double* p = new double[10]; と書くことは分かりました。 では、C の memcpy(dst, src, 10*sizeof(double)); は、C++ ではどのように書くのでしょうか。
>>506 std::copy(src, src + 10, dest)
508 :
506 :2005/08/29(月) 20:05:14
509 :
デフォルトの名無しさん :2005/08/29(月) 21:06:51
C では opendir(), readdir(), closedir() でディレクトリ内の列挙ができましたが、 C++ ではどのようにしたらいいですか?
ところで、いまだにVC6を使う理由ってmsvcrt.dllだよね? だよね?
だよねだよねウザイ
>>509 ディレクトリ操作は特にC++にはない。
boostという拡張ライブラリにはBoost.Filesystem てのがあるが。
標準では、Cと同じ関数で操作するのが普通。
VC6で動かないコードはクソ
>>509 それはCの標準関数で無い以上、C++ではどうしたらいいかというのは答えられない。
boostのようなC++のライブラリ使えとも、Cのopendir()とかをそのまま使えとも答えられるから。
515 :
デフォルトの名無しさん :2005/08/29(月) 21:50:10
無名関数(lambda)がCやC++にないのは、それが意味をなさないから? 誰からも明示的に呼べない関数作ってどうするんだろう?? LISP(scheme)やpythonってlambdaよく使うけど、何の役にたつんだYO! そのままコードかくだけ・・・じゃないの?cみたいに。。。 なんのための無名ってあるんだ!
明示的に呼べないというより、 そこにあるから名前がなくてもいいって感じ。 インラインであるがゆえ。
>>515 Lisp を使いこなるようになれば分かる。
lambda ってのは、つまり、first-class object だから役に立つんだ。
環境をいっしょくたに抱え込んだ closure としてね。
>>515 lambdaが欲しければboost::lambda。
>>513 > VC6で動かないコードはクソ
俺、今仕事で VC6 縛りなんだが
list<int> l;
for (int i = 0; i < 10; ++i)
l.push_back(i);
set<int> s;
s.insert(l.begin(), l.end());
これが通らなくて悲しい。
>>519 VC6でも、それが通るように書けるんだけど、契約の関係でほったらかしだからな。
521 :
デフォルトの名無しさん :2005/08/29(月) 23:47:40
cygwinというのをインストールして、 Cをやろうと思う。 cygwinから、 make 実行したら main.c ./main.c: line 3: syntax error near unexpected token `(' ./main.c: line 3: `int main(void){' みたいなエラーがでる・・・ コードは以下のとおり #define __RETURN__ 3 int main(void){ return __RETURN__; } なんだろう。。。英字使ってないから文字コード問題はないよね?
>>521 >gcc version 3.3.3 (cygwin special)
普通にコンパイルできるけど。makefileはどうなってんの?
524 :
522 :2005/08/30(火) 07:47:10
>>523 で?
gccでもg++でも拡張子がどちらであろうともコンパイルできるんだけど。
移行中の人はcを使っちゃいけないらしい。
>>521 関数定義をしたつもりが、変数定義扱いになってる。
だから’(’なんていらねーよと言われてる。
ではなぜ変数扱い?
とか言ってみる。
528 :
521 :2005/08/30(火) 23:42:11
>>みなさん
ありがとうございます。
特に
>>527 さんの翻訳は助かりました。
変なトークンじゃない?(って
って感じでしか訳せなくて、意味わかめでした。
原因はまだ探索中、わかったら報告しますじぇ!
すいません、質問です。 C++で構造体を使うと、よろしくないですか?
530 :
529 :2005/09/01(木) 01:18:32
はじめは「ベターC」的な使い方で使うのが良いかなぁと、、。
>>529 使ってよい。
class hoge
{
// ...
};
は
struct hoge
{
private:
// ...
};
と全く同じものだから、何ら問題はない。
>>531 別にそうなってるから使ってよいわけじゃなくて、
元々何の問題も無いだけだよね。
× と全く同じものだから、何ら問題はない。 ○ と全く同じもの。何ら問題はない。
536 :
535 :2005/09/02(金) 03:53:37
↑すまん、無限ループ作ってしまった。
>>534 に訂正。内容がある意味的を得てるw
そして「的を得る」墓穴を掘る>535。
538 :
デフォルトの名無しさん :2005/09/02(金) 04:10:48
お前ら…2人そろって日本語間違えるなよ…
「的を射る」か?
または「当を得る」。つか、
>>535 違うやん。
同じやん。
「と全く同じもの」を「何ら問題はない」の根拠にしているかどうか。
543 :
541 :2005/09/02(金) 18:49:40
レス元を見ずにレスを付けた俺が激しく謝罪しに来ましたよ (;・∀・) <`∀´ >
544 :
デフォルトの名無しさん :2005/09/05(月) 08:29:23
分数を扱うにはどうしたらよいのでしょうか?
class 分数 { int 分子; int 分母; };
547 :
デフォルトの名無しさん :2005/09/06(火) 03:26:18
ofstreamを使ってファイルの入出力をしているのですが、 ファイルポインタすなわち FILE型構造体へのポインタを利用する関数(例えばflock)を使用したい場合 どのようにすればよいのでしょうか?
>>547 とりあえず、標準の範囲では無理。
flock って FILE* だったか?
ofstreamを使ってファイルをロックすることは出来ないのでしょうか?
メンバ関数ポインタの配列を宣言しようとしたのですが、 private メンバにアクセスできないとエラーが発生してしまいます。 これは public メンバにするしかないのでしょうか? class CHoge; typedef int (CHoge::*HogeFunc) ( void ); class CHoge { int A( void ); int B( void ); int C( void ); static HogeFunc func[3]; }; HogeFunc CHoge::func[3] = { CHoge::A,// エラー CHoge::B,// エラー CHoge::C,// エラー };
C++使えねー まあそれはflockとかはUNIXの文化だから、実は UNIX使えねー なわけだけど。
>>551 普通にコンパイルとおるけど by VC7.1
あと、メンバ関数ポインタの初期化子は、&CHoge::A と書くのが基本だ。
554 :
551 :2005/09/06(火) 19:20:58
>>553 自己解決したのですが、お馬鹿なミスでした。
確かに
>>551 は問題無いようです。
自分のプログラムの
>>551 で言うところの
HogeFunc CHoge::func[3] = {
の部分を
HogeFunc func[3] = {
としていたために発生したエラーでした。
ありがとうございました。
名前空間を ::にしてるのはなんで? std.fill()とかじゃいけなかったの?
>>547 「FILE*で」 flock()ができるって、どこの国の話でしょうか?
>>555 stdクラスのfill()メソッドなのか
std名前空間のfill()というグローバル関数なのかが分からないでしょ
っていうかいちいち定義に理由を求めるな
::書きにくい。。 JAVA最高!
>>555 D&Eには型名と同名の変数を作ったときに曖昧性が生じるから :: を使うようにしたと書いてある。
>>558 それを書いているのがD&E。
型名と同名の変数を書く方が悪い もしくは変数と同名の型名(r
そもそもそんなことをできるようにしたCが悪い。
563 :
デフォルトの名無しさん :2005/09/07(水) 19:52:43
C++ で printf と同じことを cout でできますか?
>>563 同じ入力から、書式の等しい出力は可能。
書式文字列の使用は、標準の範囲では不可能。
565 :
521 :2005/09/07(水) 22:27:33
おひさびさです。 いまだに解決できずなやんでいます。 また、gcc や、bcc32 にて、コンパイルはできました。 make ができません。。。。 whichしたところ、/bin/make
>>521 今更だけど__RETURN__をRETURNにしてみたらだめか?
567 :
521 :2005/09/07(水) 23:10:19
>>566 非常に不可解なことが起こりました。
支持どおりRETURNに書き直したところ、うまくいきました。
echo $?
としたところ、3と表示されました。
_RETURN_
にしたらコンパイルエラーなんだろうなと思ったんですが、、、、
なんと_RETURN_もうまくいくようになりました。。。。
なにもしていないんですが。。。
”何かあるとすれば”cygwinのsetup.exeにて、cvsutilsパッケージを
インストールしたぐらいです。
それ以外はギコネコとcygtermしか使ってないっす。。。
めでたしなんですかね?
改行コードがおかしかったか非表示文字が混じっていたか2バイト文字が混じっていたか、 いずれその辺だべ。
_の代わりに_が入っていたに1票
もともと元ファイルの記述がおかしかったには違いないが、
>>568-569 それだとまず別のエラーでは? 自分で試してから喋ってる?
まあ、質問者自身、まったく信頼できないので、実際どんなエラー
だったか確認しようが無いが。
つか、驚くべくは、それしきをようやくdebugできたのかよ……
#define __RETURN__3int main こう定義されてたかも。
>>565 >また、gcc や、bcc32
>にて、コンパイルはできました。
なので、2バイト文字とかじゃなさそうだけれど…
>make
>ができません。。。。
どのコンパイラで問題だったか確認しきれてなさそで話にもならんのでは。
うがっ!!
>>571 実は改行されてなくてエディタ上で折り返してただけとか?
574 :
デフォルトの名無しさん :2005/10/19(水) 21:30:01
age
575 :
デフォルトの名無しさん :2005/10/24(月) 09:20:06
クラスのデフォルト引数は宣言の方に書くのでしょうか?
それでいいんじゃね?
宣言に書き、定義には書かないのが通例。
むしろそうしないと、デフォルト引数が2箇所以上で指定されているというエラーになる。
579 :
デフォルトの名無しさん :2005/10/26(水) 00:59:54
C++の標準ライブラリには時間関係の関数が見当たらない気がするのですが、 これらはCのライブラリから持ってくるしかないんでしょうか?
>>579 いいえ、Cから受け継いだものをそのまま使うと言うことです。
581 :
デフォルトの名無しさん :2005/10/26(水) 05:29:17
じゃあ、あのちょっとキモイ静的領域を共有するような関数ライブラリを そのまま使え、とあなたは仰ると?
583 :
デフォルトの名無しさん :2005/10/26(水) 07:18:36
どっちもいやですね。 お得意のboostとかでなんとかしてくださいよ。
>お得意のboostとか いや、得意じゃないから。つーか、なにが気に入らないのやら。
boostで解決しないことなんてあるのか?
586 :
デフォルトの名無しさん :2005/10/26(水) 10:40:51
587 :
デフォルトの名無しさん :2005/11/07(月) 11:52:34
STL では、動的な1次元配列を生成するために vector が定義されていますが、2次元以上の 動的な配列を生成するための型は定義されていません。 (もちろん、Boost には定義がありますが) そこで、いろいろと調べてみたところ、下記のように 記述をすれば何とか2次元の動的な配列を生成できる ことがわかりました。 vector< vector<int> > matrix(10, 100); ただ、上記のようにして2次元配列を生成した場合、 配列の拡張をしようと思うと、 matrix.resize(99); for( i = 10; i < 99; i++ ){ matrix[i].resize(100); } のように記述をする必要がありそうで、今ひとつな感じがします。 もっと、エレガントに配列の拡張ができると良いなぁ...と思いますが、 そんな夢みたいな方法ってあるのでしょうか? # matrix.resize(99,100) と記述できれば良さそうな気はします。。。
>>587 cppllの過去の投稿をコピペすることの意味を教えてくれ
うるせー馬鹿
単に記述の問題であればLISPを覚えるのが吉 C++でセコセコやってるのがアホらしくなるよ
>>590 lispで何ができんの?emacsのすくりぷティングか?
シェル上でASCIIアートか?
>>587 その場合、デザイン的には、matrix classを組んだ方がいいんじゃない?
メンバー関数として、void resize( size_t m, size_t n ); を定義。
行列をクラスにする事による恩恵は大きい。オペレーターオーバーライドとか、
vectorを使うならコピーコンストラクタは必要だし。
使い古された話だから、山ほど実例があるよ。
あっそ
595 :
デフォルトの名無しさん :2005/11/09(水) 13:45:27
try & catch の理屈がわかりませぬ
>>596 setjmp() / longjmp() のような物だと思いなせえ。それプラスα。
余計ワカラナサスw
例外以外では使えないlongjmp
try 〜 catch を大域脱出に使うと、コスト高杉。そういう用途向けには 作られてない。サンデープログラマなら別に好きなようにすればいいけど。
>>596 try 〜 catchの例外処理はエラー処理を1箇所でまとめて行うためにある。
たとえばmallocと違いnewはメモリが確保できないと例外を投げる。
そこでtry 〜 catchを使えばメモリ確保するたびにいちいちNULLチェックをする必要がなくなる。
(この例ではメモリの解放が出来ないのがまずいけど)
try
{
int *pHoge = new int[100];
double *pFoo = new double[100];
char *pBar = new char[256];
/* 〜 */
return true;
}
catch (const std::exception& e)
{
return false;
}
>>601 try 〜 catch書くと5行ぐらいに増えるけど、
いちいちNULLチェックしたら1行で済んだよ
try 〜 catch で例外状態からの脱出って言っても、 そのエラー要因を後で知りたい時には、どうすりゃいいんだよ。
>>607 boost::scoped_ptrでなんとかしてくれ。
もれはNULLなんて返ってきたことが無いんだが何か?
確かにw
newで例外が発生する? それ以降の代入とかで初めて例外が発生する気がするんだが。 MS VC++の場合。
>>611 最適化で、newが実行される位置がコード上とはずれているのではないか?
614 :
デフォルトの名無しさん :2006/01/22(日) 18:10:17
gccなんですけど。
catch 節に書いた処理でさらに例外が発生したら、どうなるのだ?
>>616 さらに外の catch 節で処理されるか、 terminate() する。
つまり通常の例外発生時と特に変わらない。
C#はJavaのパクリとか言われてるが 初めてJavaを見た時C++のパクリだと思った 以上チラシの裏
今となってはJavaはC++の悪いとこだけ持っていった言語になるな
String型は素晴らしいと思うが
>>620 Javaのことはほとんど知らないんだけど、それはライブラリではなく、組み込み型なの?
前者だとしたら素晴らしいのはライブラリであって言語じゃないっす。
Stringは組み込みじゃなかったっけか・・・あ、適当なこと言うのは止めて置こう 叩かれそうだw
>>622 別に叩かれてもいいじゃんぬるぽ、匿名なんだしぬるぽ。
JavaのStringはデフォ。オペレータオーバロード出来ないJavaが文字列の 足し算できるのはデフォで贔屓されているから。
626 :
デフォルトの名無しさん :2006/01/24(火) 00:04:59
>>625 Stringだけ特別扱いで美しさにかけるぜよ
いまだに例外がサポートされない環境がいっぱいあるし、newはNULL返して欲しいよ。 コンストラクタの中でエラーするようなことスナ!
>>627 newの失敗時にNULLが欲しいのなら
new(nothrow) T;
ただ、個人的には戻り値のNULLチェックは、
忘れてしまいがちな処理の上位に入るので例外を投げる仕様のほうが好み
>>628 nothrow で抑制できるのは
operator new から飛んでくる例外だけだったような。
631 :
デフォルトの名無しさん :2006/01/25(水) 23:38:46
VC++.net2003を使って、C++の勉強とDirectXの勉強をかねて色々やっています。 ベクトル等の構造体同士を加減算させるために演算子のオーバーロードを メンバ関数でやっていたのですが、ふと d3dxmath.h を見てみると、 自分では分からない記述でオーバーロードされていました。 D3DXVECTOR2 operator + ( CONST D3DXVECTOR2& ) const; D3DXVECTOR2 operator * ( FLOAT ) const; これらはどういった動作をするのでしょうか?
DirectXの勉強もいいが、数学の勉強しろ。 動作を理解したところで、旨みが理解できねーから
甘みと言われましても。 今はCで書いていた自前の算術ライブラリをC++に置きかえつつDX9に対応させてる状態で その過程でオーバーロードを使っていこう、というわけですので。 数学の勉強とはまた違う話なんですが。
甘み->旨み 変換がおかしいな・・
わからないと言うのはいいが、一体どこがわからないのだ? ざっと候補を挙げるだけでこんなにある。 D3DXVECTOR2 operator + CONST & const operator * FLOAT ベクトルとベクトルの加算 ベクトルとスカラーの乗算
636 :
デフォルトの名無しさん :2006/01/26(木) 00:35:02
凡用的な質問させて下さい。 現在CからC++を勉強するための良い本はプログラミング言語C++第3版くらいしかなさそうです。 (他のC++の本では絶版の物が多いようなので) プログラミング言語C++第3版とEffective C++を二つ買って14'000円です 他にC++を勉強する良い方法は何か無いでしょうか?
ちょっと関係ないけど買うなら古本屋とかに寄ってみた方がいいぞ。 俺はC++第3版をBOOKOFFで3000円で買った。
>>636 プログラミング言語C++第3版
Effective C++ 第2版
More Effective C++
Exceptional C++
Effective STL
C++ FAQ 第2版
C++ Coding Standards
Modern C++ Design
C++の設計と進化
これらを全部読む
>>637 それは3'000円以上の価値のある買い物をしましたね。
私も古本屋でちょっと探してみたいと思います
>>638 高価そうな本が並んでいますね(@_@;)
でも、レス有難うございます。参考になりました。
移行に限って言うなら、「憂鬱なプログラマのためのオブジェクト指向開発講座」を一通りやって感覚を掴んだら、 EffectiveC++やMoreEffectiveC++、EffectiveSTLのような「定番」を読んでC++に理解を深めつつ JavaやC#でもいいから、オブジェクト指向について解説した本を読んで、オブジェクト指向開発の基礎を学ぶ。 で、ある程度慣れてきたらModernC++DesignやExceptionalC++、D&Eのような、ちょっと深めの本を読むといいと思うけど… 漏れはこの順番でやったってだけで、他の方に合うかはワカンネ。
流石に捏造かw しかしそういうジョークが成り立つぐらい規模が大きくなったってことでもあるしな
安全性のために、 基本的にはメンバ変数はprivateもしくはprotectにして、直接触らない。 値の変更、参照はメンバ関数を使用する。 と習ったのですが、一々メンバ関数を用意するのは面倒です。 値の変更はやむを得ないとして、メンバ変数を擬似的にリードオンリー みたいにするアイデアないでしょうか?
>>649 だからJavaやC#などC++を基にしてできた後の言語では、
みんな、メンバ変数へのアクセスのようだけど実際にはメンバ関数の呼び出しになる「プロパティ」という機能がある。
ちなみにprotectedなメンバ変数も少し気を付けておいた方がよいと思う。
>>649 あるよ。 template 使って property を実装すればいい。
しかし「一々メンバ関数を用意する」という考え方自体に意味が無い。
大雑把でもクラスの役割とインターフェースをひととおり決めて、
その後にどんなメンバ変数が必要かを決めるようにしたほうがいい。
質問させてください. new, delete, コンストラクタ回りを理解するために Better C スタイルで, 以下のようなコードを書きまして…
class X { public: char szData[4]; X(); virtual ~X(); void* operator new( size_t ); void* operator new[]( size_t ); void operator delete( void* ); void operator delete[]( void* ); };
X::X() { putchar('.'); } X::~X() { putchar('.'); } void* X::operator new( size_t size ) { printf( "\n/メモリ確保中. operator new( size=%d )/", size ); return ::malloc(size); } void* X::operator new[]( size_t size ) { printf( "\n/メモリ確保中. new[]( size=%d )/", size ); return ::malloc(size); } void X::operator delete( void* obj ) { printf("/メモリ開放中. delete( obj )/\n" ); ::free(obj); } void X::operator delete[]( void* obj ) { printf("/メモリ開放中. delete[]( obj )/\n" ); ::free(obj); }
class ChildX : public X { public: char szData[4]; ChildX(); ~ChildX(); }; ChildX::ChildX() { putchar('.'); } ChildX::~ChildX() { putchar('.'); }
int main(void) { puts("\n"); { X* pData = new X; X* pDataArray = new X[10]; putchar('\n'); printf("オブジェクトのサイズ: sizeof(X* pData)=%d, sizeof(X)=%d)\n" , sizeof(pData), sizeof(X)); printf( "オブジェクトの場所: pDataArray[0]=[%p],\n" " pDataArray[1]=[%p],\n" " pDataArray[9]=[%p]\n" , &pDataArray[0], &pDataArray[1], &pDataArray[9] ); printf( "&pDataArray[9] - &pDataArray[0] = [%d]\n" , &pDataArray[9] - &pDataArray[0]); delete pData; delete [] pDataArray; }
657 :
653 :2006/01/31(火) 15:38:56
puts(""); { X* pData = new ChildX; X* pDataArray = new ChildX[10]; putchar('\n'); printf("オブジェクトのサイズ: sizeof(X* pData)=%d, sizeof(X)=%d)\n" , sizeof(pData), sizeof(X)); printf( "オブジェクトの場所: pDataArray[0]=[%p],\n" " pDataArray[1]=[%p],\n" " pDataArray[9]=[%p]\n" , &pDataArray[0], &pDataArray[1], &pDataArray[9] ); printf("&pDataArray[9] - &pDataArray[0] = [%d]\n" , &pDataArray[9] - &pDataArray[0]); delete pData; delete [] pDataArray; } puts(""); return 0; }
658 :
653 :2006/01/31(火) 15:40:14
で, コンパイル実行した結果は, 以下のようになったのですが…
659 :
653 :2006/01/31(火) 15:40:52
--- Visual C++ 6.0 でコンパイル・実行した結果: 1: /メモリ確保中. operator new( size=8 )/. 2: /メモリ確保中. new[]( size=84 )/.......... 3: オブジェクトのサイズ: sizeof(X* pData)=4, sizeof(X)=8) 4: オブジェクトの場所: pDataArray[0]=[00431AB4], 5: pDataArray[1]=[00431ABC], 6: pDataArray[9]=[00431AFC] 7: &pDataArray[9] - &pDataArray[0] = [9] 8: ./メモリ開放中. delete( obj )/ 9: ........../メモリ開放中. delete[]( obj )/ 10: 11: 12: /メモリ確保中. operator new( size=12 )/.. 13: /メモリ確保中. new[]( size=124 )/.................... 14: オブジェクトのサイズ: sizeof(X* pData)=4, sizeof(X)=8) 15: オブジェクトの場所: pDataArray[0]=[00431A84], 16: pDataArray[1]=[00431A8C], 17: pDataArray[9]=[00431ACC] 18: &pDataArray[9] - &pDataArray[0] = [9] 19: ../メモリ開放中. delete( obj )/ 20: ..................../メモリ開放中. delete[]( obj )/
660 :
653 :2006/01/31(火) 15:43:51
--- Borland C++ 5.5.1 でコンパイル・実行した結果: 1: /メモリ確保中. operator new( size=8 )/. 2: /メモリ確保中. new[]( size=84 )/.......... 3: オブジェクトのサイズ: sizeof(X* pData)=4, sizeof(X)=8) 4: オブジェクトの場所: pDataArray[0]=[00902DA4], 5: pDataArray[1]=[00902DAC], 6: pDataArray[9]=[00902DEC] 7: &pDataArray[9] - &pDataArray[0] = [9] 8: ./メモリ開放中. delete( obj )/ 9: ........../メモリ開放中. delete[]( obj )/ 10: 11: 12: /メモリ確保中. operator new( size=12 )/.. 13: /メモリ確保中. new[]( size=124 )/.................... 14: オブジェクトのサイズ: sizeof(X* pData)=4, sizeof(X)=8) 15: オブジェクトの場所: pDataArray[0]=[00902DA4], 16: pDataArray[1]=[00902DAC], 17: pDataArray[9]=[00902DEC] 18: &pDataArray[9] - &pDataArray[0] = [9] 19: ../メモリ開放中. delete( obj )/ 20: ........../メモリ開放中. delete[]( obj )/
661 :
653 :2006/01/31(火) 15:44:45
--- GNU GCC 3.3.4 (MinGW special) でコンパイル・実行した結果: 1: /メモリ確保中. operator new( size=8 )/. 2: /メモリ確保中. new[]( size=84 )/.......... 3: オブジェクトのサイズ: sizeof(X* pData)=4, sizeof(X)=8) 4: オブジェクトの場所: pDataArray[0]=[003D4944], 5: pDataArray[1]=[003D494C], 6: pDataArray[9]=[003D498C] 7: &pDataArray[9] - &pDataArray[0] = [9] 8: ./メモリ開放中. delete( obj )/ 9: ........../メモリ開放中. delete[]( obj )/ 10: 11: 12: /メモリ確保中. operator new( size=12 )/.. 13: /メモリ確保中. new[]( size=124 )/.................... 14: オブジェクトのサイズ: sizeof(X* pData)=4, sizeof(X)=8) 15: オブジェクトの場所: pDataArray[0]=[003D49BC], 16: pDataArray[1]=[003D49C4], 17: pDataArray[9]=[003D4A04] 18: &pDataArray[9] - &pDataArray[0] = [9] 19: ../メモリ開放中. delete( obj )/ 20: ..[!!! ここで Windows により強制終了. !!!]
662 :
653 :2006/01/31(火) 15:49:12
出力の 20 行目で, それぞれ挙動が違ってしまい, その理由がいまいちよく解らないのです. virtual ~X() のところを ~X() としてコンパイル実行すると上手くいくのですが, 20 行目の点が足りなくなってしまい, 困ってます. アドバイス下さい;; (652-662 長文失礼しました.)
>>662 X*p=new X[10];
delete[]p;
は問題ないが
X*p=new ChildX[10];
delete[]p
は実はC++では駄目。
なぜなら、これを実現しようとすると型のサイズと要素数の二つを暗黙的に管理する必要になるので、
そんなもったいないことは貧乏くさいC++では許さないのだ。
ChildX*p = new ChildX[10];
delete[]p;
のように正しい型の配列にするか、
X**p=new X*[10];
for(int i=0;i<10;++i)p[i] = new ChildX;
for(int i=0;i<10;++i)delete p[i];
delete[]p;
のようにポインタの配列にするのがC++のルール。
>>663 そうだったのか….
ありがとうございました.
助かります.
new int a[10]; で作成した後、 a[9]だけ削除したいのですが、どのようにしたらよいのでしょうか?
>>665 意味わかんね。
4or8byte程度ほっとけ。
>>665 reallocみたいなのはnew , delete の仲間には無い。
>>665 要素数を動的に増減させたいなら vector 使え。
669 :
デフォルトの名無しさん :2006/02/22(水) 05:46:58
<<演算子をオーバーロードするさいにfriend関数を用いる必要があるのでしょうか?
>>669 それだけの目的なら必要はないと思うけど?
今更ながら恥ずかしい限りですが教えてください。 char* s; という変数があって、上記変数に値を代入した後 int hogehoge( const char* a ) という関数に渡したいのですがエラーになります。 どうすればいいのでしょう?
誤爆しました。初心者スレに逝ってきます_| ̄|○
673 :
デフォルトの名無しさん :2006/03/14(火) 07:37:29
リストで済むなら、ベクタでなくリストを使うべきですか? メモリ使用量とか動作スピードとかはリストの方がエコですか?
んにゃ、listを使うべきとき以外はvectorで充分。 少なくとも、メモリ使用量はlistの方が多くなるし、頻繁な要素の入れ替えや中間への挿入削除以外は速度も遅くない。
675 :
デフォルトの名無しさん :2006/03/14(火) 09:55:10
頻繁な要素の入れ換えを予期するときはリストですか?
>頻繁な要素の入れ換えを予期するとき 設計を見直す。
677 :
デフォルトの名無しさん :2006/03/14(火) 11:56:39
ベクタがあるのにリストの存在意義が分かりません><
dequeがあるのにvectorの存在意義が分かりません
一次元の要素しか扱わないのか。
>>678 dequeよりvectorのほうが実装が単純に出来るだろうし、実装が単純ということは速くなるだろうし。
これは実装の問題ではないが、規格ではvectorしかメモリ上での要素の連続が保障されていないというのも大きい。
面白くないで直してまいれ
TextSS のWindowsXP(Professional)64bit化おながいします もしくは64bitにネイティブ対応したテキスト置換ソフトありますか?
684 :
デフォルトの名無しさん :2006/04/02(日) 05:38:59
boostを使うために、クラスの定義の中に lagged_fibonacci1279 gen; normal_distribution<> dst( 100.0, 20.0 ); variate_generator<lagged_fibonacci1279, normal_distribution<>> rand( gen, dst ); と書いたのですが、2行目と3行目で定数、及び識別子構文エラーが出てコンパイルできません。 クラス外に書いたときは問題ないのですが、クラスごとにseedなどを管理したいので クラス内に書きたいのですが、どのように書けばよいのでしょうか?
normal_distribution<>> normal_distribution<> >
cを勉強してc++へ移行するのはそんな難しくないだろうと 思ってたんですけど、もうc++って言語をcと分けないと 訳がわかんなくなってきました で、お勧めの書籍ってあります? 推薦図書のスレあんま参考になんないっす。
いっそC++から離れてJavaとかC#やってみたら? (オブジェクト指向ならSqueakとか) 一通りやってからC++に戻ったら、 パワーアップした自分に気がつく(はずw)
690 :
デフォルトの名無しさん :2006/04/10(月) 21:00:53
抽象クラスが抽象クラスから継承される事って出来るよね?
692 :
デフォルトの名無しさん :2006/04/11(火) 14:01:49
accelerated c++のP230から質問です。 class Core{ public: double grade() const; protected: double midterm,final; std::vector<double> homework; } double Core::grade() const{ return ::grade(midterm,final,homework); } class Grad: public Core{ public: double grade() const; } double Grad::grade() const{ return min(Core::grade()); } この様に書かれている場合でも、Grad::grade()から呼び出されたCore::grade()内の midterm,final,homeworkは全てCore::ですよね? だとすると、Gradオブジェクトは Core::midterm,final,homeworkを持つという事でしょうか? Grad::midterm,final,homeworkを持つのではなく。 よろしくお願いします。
>>692 どちらかというとmidterm, final, homeworkはCoreのメンバだけど、
GradはCoreの派生クラスだから、GradではCoreのメンバもGrad::でアクセスできるという感じ。
694 :
デフォルトの名無しさん :2006/04/23(日) 08:46:15
age
>>601 エラー処理を1カ所にまとめてしまうと、
new int[100];
new double[100];
new char[256];
のどこでメモリ確保に失敗したのかを知ることはできるのでしょうか?
メモリ確保失敗が1つでも発生すればプログラムは期待通りに動かないわけですから、
成功した分を解放してから抜ける必要があるかと思いますが。
>>695 vector<int> i(100);
vector<double> d(100);
vector<char> c(256);
これでも失敗した箇所を知ることはできないが、成功した分の解放は問題ない。
失敗した箇所を知ることによって何かできることがあるだろうか?
できることと言えばせいぜいデバッグの際に少しは役立つかもしれないということしか思い付かない。
698 :
695 :2006/05/19(金) 00:15:51
>>696 レスサンクスです。
>成功した分の解放は問題ない。
そうなんですか。
もう少し勉強してみます。
どうしてnew[]を使う必要があったとしても、 boost::scoped_arrayやshared_arrayがあるしな。
どうしてnew[]を使う必要がああるのはなぜなんだぜ?
まぁ、new[]が必要となる場合は設計を見直した方がいいと思う。 これは別にそーゆー設計が悪いってんじゃなくて単にそーゆー設計がC++と相性が悪いから。
やりたいこと AのプログラムからBのプログラムを非同期で起動する。(Aはその後終了) CのプログラムからBのプログラムを終了させる。 やってみたこと AのプログラムはCreateProcessでBのプログラムを単純に起動してそのまま終了。 BにはサンプルによくあるコールバックのWndProcに、WM_CLOSEとかを作っておく。 Cのプログラムで、イメージ名(B実行体)をキーにプロセス一覧からプロセスIDを取る。 プロセスIDをOpenProcessに引き渡してプロセスハンドルを得る。(PROCESS_ALL_ACCESS) そのハンドルにPostMessageでWM_CLOSEを投げてみる。 ★何も起きない ・そのハンドルにTerminateを実行すると強制終了はできる。 何か根本的に間違っていたらごめんなさい。
>>702 プロセスハンドルにPostMessageで投げる?
PostMessageはウィンドウに投げる関数だからウィンドウハンドル渡さないと駄目だろ。
704 :
デフォルトの名無しさん :2006/06/02(金) 08:37:30
newをクラス内で使っていない場合、コピーコンストラクタを作成せず初期化しても問題ありませんか?、
>>704 それだけの条件じゃ「問題ない」とは言い切れないなぁ。
心配している問題について正しく理解するのをお勧めする。
706 :
デフォルトの名無しさん :2006/06/03(土) 12:29:28
コールバック関数について質問です。 クラス内にある関数をコールバック関数として登録し、そのコールバック関数内でメンバー変数を変更したいのですが うまいやり方がわからずに悩んでおります。 現状のソースはこんな感じです。 ヘッダ class ProcessManager { static void m_SigChildHandler(); //コールバック関数として使用したい関数 int status; //状態 void m_Init_Application(); }; ソース typedef void (*THREADFUNC)(int); void ProcessManager::m_Init_Application() { signal(SIGCHLD, (THREADFUNC)m_SigChildHandler); /* signal監視 */ } void ProcessManager::m_SigChildHandler() { status = 1; //状態変化したいけれどできない。 } int main() { ProcessManager cProcessManager; cProcessManager.m_Init_Application(); }
>>706 クラス内の静的(static)な関数は、クラスの中にあるということ以外、普通の関数と変わらない。
つまり静的でないメンバー変数にはアクセスできない。
ナニ言ってやがる。staticなんてする必要無い。 でもって、コールバックの使い方自体が間違ってる。 つうか、コールバックの意味知ってるのか? 相手関数コール時点で、「私に返事ください。お返事先はここです。」と、コールバックアドレスを教えれ。
コールバックをする関数自体は、コールバックされる関数のクラスを知っているんだから、 継承されたクラスから継承元クラスにコールバクという使い方が一般的。
710 :
デフォルトの名無しさん :2006/06/03(土) 12:47:05
>>707 そうするとみなさんどのように実装しているのでしょうか。
コールバック関数のみクラスの外に出して、状態はグローバル変数で持つなどしなければいけないのでしょうか?
713 :
デフォルトの名無しさん :2006/06/03(土) 12:48:40
>>710 statusも静的メンバー変数にしてしまえばいい。
715 :
706 :2006/06/03(土) 12:49:58
あ、番号付け忘れた 710と712は私です。
ま、早い話、オブザーバークラスとか、ノーティファイ関数とか調べれ。
>>712 シグナルを相手にするのはコールバックする方のクラスじゃなくって、コールバックされるのを待っている方のクラスだろ?
そっちに全部集約しておけばいいじゃん。
>>717 どのみち実際にハンドラ呼ぶのは signal で、
そこにどうやって this ポインタ渡すんだっつー問題が
解決していない。
>>706 監視したい子プロセスが1つしかない場合は、
>>714 の通り、statusをstaticにしてしまえばいい。
子プロセスが複数あり、各プロセスごとに個別のコールバックを呼び出したければ、
CProcessManagerにプロセスIDとコールバックを納めたクラスのインスタンス(やポインタ)をstd::mapで保存しておいて、
sigactionでシグナルを監視する。
sigactionはコールバック時に、シグナルを発生させた子プロセスのIDが分かるから、
IDから逆引きでプロセスのインスタンスを取得し、コールバック関数を呼び出してやればいいかと。
つうか、C++使ってる時点でコールバック関数なんて概念、捨てれば?
721 :
706 :2006/06/03(土) 13:12:02
皆様、勉強不足ですみません。 今、色々皆さんから教わったキーワードでググっているところです。 結構ヘタレなので、理解に時間がかかっています。
でもさ、staticで宣言された関数って、そのクラスのインスタンスの生成前でも呼べるんだぜ? どういう事か、考えてね/
STLでのソートをしていますが、 struct foo { int number; std::string name; }; のような構造体を作り std::vector<foo> team; のような動的配列を作り、がしがし追加していきます。 あとでnumber順にソートしたくなったとき std::sort( team.begin(), team.end() ); では比較できないため、関数オブジェクトを作りました。
725 :
724 :2006/06/04(日) 13:35:03
class comp { public: bool operator()( const foo &left, const foo &right ) { return left.number < right.number; } } そののち、 std::sort( team.begin(), team.end(), comp() ); // compの一時インスタンスを作る するとソートされます。 分からないのは、構造体やクラスを抱えたコンテナのソートをするには、 その度に関数オブジェクトを作らないといけないのでしょうか。 intとかstd::stringならgreater<>が用意されているのは調べました。 調べた本はSTL標準講座、あとはぐぐりましたが、そこまで書いてあるものは見つけられませんでした。
>>725 クラス自体の順序付けを定義する operator < をつけてしまえば
関数オブジェクトを渡さなくてもソートできる。そうでなければ
関数オブジェクトを渡す必要がある。
これが面倒なんで、 boost::lambda とか使って楽をしようという道もある。
727 :
724 :2006/06/04(日) 14:44:29
>>726 operator<を定義しておけばいいのですね、ありがとうございます。
いまのところ、ソートのキーは1つだけなので、それでいきます。
将来、複数のキーでソートするときはboost::lambdaを調べます。
728 :
702 :2006/06/05(月) 08:21:54
>703 プロセスハンドルとウィンドウハンドルの違いも分からずお恥ずかしい限りです。 ということは、この方法ではメッセージを投げることはできないのですね。 FindWindowを使えば…とは思いますが、クラス名とウィンドウ名で判断するのはなんとも…。 ありがとうございました。
>>728 例えばEnumWindowsで、各々に対してGetWindowThreadProcessIdするとか。
C++って、Cで使っていたものをより安全・便利に利用できる ってだけ? C++形式で書くとわかりやすくはあるけど、Cでできなかった〜がC++にしたからできる、という状況に遭遇しない。
>>730 1からC++を勉強し直す事をお勧めする。
>>730 >Cでできなかった〜が
具体的に何かある?
>安全・便利に利用できる これに何の価値も見いだせないなら、Cを使っていればいい。
>>732 何もない
メールを使わずに郵便封筒でもいい
勤務表をエクセルでなく、手書き+時間計算をすればいい、要はコスト削減
具体的にはクラスってやつでくくるのよ、コードをパックにする(カプセル化)
カプセルにしたら、ネット上で公開されてる別のカプセルを使えるのが利点
Cなら関数のコピペでしょ、それがファイル単位になる
>>734 じゃなくて、「Cでできない事」って何さ。
Cで出来ない事。例えば例外処理とか。 Cでlongjmp/setjmpを使っても、例外処理と全く同等の機能を 実現する事は出来ない。
>>735 うんむ、デザパタとかじゃなく、不可能なことてことか
ま、1本1本線引いたらGUIもできるしな〜
PGが1万人いたら何でも可能ってとこかな
とにかくC++という字面を見るな。 CとC++は無縁。 Cのテクニックは全て忘れろ。 Cはアセンブラの亜種とでも思っておくと丁度しっくりくる。
effectiveC++買ってきた
Cではインラインアセンブラがあるように、 C++では、インラインでCも書けると思うのがよいのかもしれない。
Cを全く知らないんですが、いきなりC++から始めようと思います。 そこでCの知識を全く必要としないC++の書籍を探していますが、 私の目にした多くの本はCを知っていることが前提となっていました。 なにかお勧めのものはないですか?
>741 Accelerated C++
743 :
デフォルトの名無しさん :2006/09/17(日) 19:03:52
多くの言語がCを模倣しているからたいていの本はそう見えるとと思う(変数や条件分岐や繰り返しはどのプログラミング言語でも共通している)。薄っぺらいcの本で少しc勉強してから、c++に手を出してみたら。accelateded c++ は何冊か読んでからの方がいいと思う。
>>741 まずアセンブラをやれ
すこしかじるだけでいい
実際、C++の本にはメモリやアドレスの「定義」が載っていないので
それ無しではかならず詰まる。これは君の責任ではない
ただCはやらなくてよい
C++ == C + オブジェクト指向 だからC言語を知らないとC++は使えない。 なんてアホな事を言う奴の話は聞くなよ。 C++の奥義はboostの中にある。
かといって、いまどきのアセンブラ教科書を買ってしまうと…
つーかいきなりC++から始めようと思っても、やはり情報が無い、 もしくは極めて少ない、加えて超いばらの道だよね。 やっぱCかじってから入った方がいいんでねぇの?
普通Cからじゃね?
技術者同士の会話で「普通」はねぇだろ。何の根拠にもならん。
それもそうだな
C++を0から教えるにしても最初の方はCと大差ない講義にしかならんと思うけど?
オブジェクト指向から入れば?
いきなりTMPから始めちゃえばいいよ
古典的なCの教科書から入った人と オブジェクト指向の概念からかじるような本で始めた人では会話が噛み合わない そんな偏見を持ってたり
>>224 わざわざ数字コテにして自分の存在をアピールしても
他と同様、カスであることに変わりはないんだから無理すんなwww
756 :
デフォルトの名無しさん :2006/10/22(日) 15:17:29
759 :
デフォルトの名無しさん :2006/10/24(火) 10:16:29
最近のヘッダファイルに拡張子が付いていない理由を教えてください
>>759 C++ではnamespaceに属することが推奨されるようになったが
stdio.hやiostream.hなどのライブラリをstdの名前空間に入れてしまうと
今まで作られてきたソースがみんなコンパイルエラーになってしまう。
そのため苦肉の策としてC++のヘッダうちstdに属するもののは.hをはずし
iostream.h→iostream
C言語標準のヘッダはさらに先頭にcをつけて
stdio.h→cstdio
として昔の仕様との互換性をもたせたらしい。
エッチじゃないから♪
>>739 俺も昨日買って来たぞ。
C++は入門したばっかだけど、読み物としても面白いな。
含蓄の部分は徐々にわかっていくのだろうと期待。
継承もとと同じクラス名で継承するにはどのように書けばよいのでしょうか? そもそもそのようなことはできるのでしょうか?
>>763 別の名前空間なんだよな?
継承元に名前空間の指定を付ければいいんじゃない?
これで違ってたら、ソースとエラーメッセージ晒せ。
765 :
デフォルトの名無しさん :2006/12/15(金) 19:45:17
名前空間はCでも使えますか??
使えない。
767 :
デフォルトの名無しさん :2006/12/18(月) 19:15:24
すまん。 文字列定数の配列をクラス定義の中に埋める方法教えてくれ<(_ _)>
それを返す静的なメンバ関数をインラインに書くしかないと思う。
>>767 class CHoge {
public:
static const char *A[];
};
const char *CHoge::A[] = { "HOGE1", "HOGE2", "HOGE3" };
こんな感じ?
770 :
デフォルトの名無しさん :2006/12/19(火) 19:38:21
まいどどうも。
772 :
デフォルトの名無しさん :2006/12/20(水) 03:39:25
C++ってCよりポインタは簡単なんですか?
774 :
769 :2006/12/20(水) 10:13:54
>>771 指摘サンクス。
static const char* const A[];
と
const char* const CHoge::A[] = { "HOGE1", "HOGE2", "HOGE3" };
ってことですね。詰めが甘いな俺orz
だから const は右につけておけと
776 :
デフォルトの名無しさん :2006/12/20(水) 19:00:56
ちなみにそれどう展開されるの?
こうでもすれば、ヘッダだけで用が足りる。
class CHoge {
public:
static const char** GetA() {
static const char *A[] = {"HOGE1", "HOGE2", "HOGE3"};
return A;
}
};
>>772 参照・イテレータによって多少は使う機会が減るかもしれない。
スマートポインタによって動的メモリの解放し忘れは減るかもしれない。
そういう点では楽になるかもしれないが、学ぶべきことが減っているわけではないので、
結局簡単になったとは言えないと思う。
>>772 Cのポインタすら理解して無い人には、C++はハードル高いと思う
反復子ってポインタより簡単なんですか?
ポインタをも包括する概念。 別に簡単になるわけではない。
781 :
デフォルトの名無しさん :2006/12/20(水) 21:25:10
>>779 ポインタみたいに使えるけども
仕組みを理解するのには、ポインタ理解するよりめちゃめちゃ難しい。
そうかな? 聞くより手を動かしたほうぐあ
使うのは簡単だけど作るのが面倒
784 :
デフォルトの名無しさん :2006/12/20(水) 23:12:18
コンテナおもしろがってつかってみたんさ。 劇重くてたいへんなことになっちゃた(T_T) どーしよ。
最適化オプションを目一杯指定する。 reserveを適切に使う。 (特にclass/structを格納する場合)オブジェクトのコピーをなるべく起こさせないようにする。 (メモリの割り当てに時間を取られている場合)アロケータを標準のものから高速なものへ取り替える。
ofstreamで書き込みバッファの容量は指定できないでしょうか?
ofstreamのバッファの容量はどこで指定できますか?
>>787 filebufのpubsetbuf()が、stdioのsetvbuf()に相当する。
char mybuffer[8192];
of.rdbuf()->pubsetbuf(mybuffer, sizeof mybuffer);
790 :
デフォルトの名無しさん :2007/01/06(土) 04:55:12
>>784 そんだけ、コンテナ内部で色々してるって事
重いのはしゃーねー
>>790 そんな見方じゃ C++ の魅力がほとんど無いだろ。
効率を落とさずに抽象化できるのが C++ の重要な特徴の一つだ。
どうせ
>>784 は最適化かけずに比較してるんだろ。
792 :
デフォルトの名無しさん :2007/01/06(土) 18:59:45
STLのstringの簡易版のような自作文字列クラスのインスタンスを 直接char型ポインタ引数とかに渡しても大丈夫な(ちゃんとchar型ポインタとして使える) ようにするにはどうすればよろしいですか
>>792 class 俺string
{
typedef char value_type;
valut_type *value;
...
operator const value_type *() const
{
return value;
}
...
};
794 :
793 :2007/01/06(土) 19:08:01
可変長引数部分に渡しても大丈夫にする為にはデータメンバを char * ひとつだけにして、仮想関数を使わないこと。
795 :
792 :2007/01/06(土) 19:22:41
>>794 ありがとうございます
要は*のオペレータオーバーロードをするってことですか?
>>795 そうだけど、それだけだと printf の第一引数には使えても第二以降の引数には使えない。
第一引数は printf 関数の第一引数が const char * だと型が明示されているから変換オペレータが
呼び出されるからいいんだけど、第二以降の引数は型が明示されていないから
変換オペレータが呼び出されないから
>>794 のルールを守ってないとアウト。
797 :
792 :2007/01/06(土) 20:32:14
>>796 可変長引数に渡す場合に気をつけろということですね
詳しく、サンクスです
valarrayってSTLに含まれるんですか?
800
#defineをconstで置き換えています。 void f(void) { const int x=10; } と void f(void) { static const int x=10; } では何か違いが出ますか? クラス内の定数は、複数のconstのインスタンスが作られないようstaticをつける様にしているのですが、 通常の関数の場合はどうなのでしょうか?
>>801 定数式で初期化してて、アドレスや参照を取ってなければ違いは無いだろうね。
実際はコンパイラによるだろうから、アセンブリ吐かせて確認したほうがいいだろう。
803 :
デフォルトの名無しさん :2007/04/13(金) 09:53:01
文字列を空にするのにどうして strcpy(s, NULL); じゃいけないのでしょうか?
>>803 たった数行の質問で、色々と間違いをしてるのがすごいな
*s=NULL;
キモ
808 :
デフォルトの名無しさん :2007/04/22(日) 18:24:01
ディスクに完全に書き込むためにfsyncを使いたいのですが、ofstreamでのファイル記述子は どのように取得したらよいのでしょうか?
移植性のある方法は存在しない。 逆にファイル記述子を通じて読み書きするストリームバッファを 自分で作れというのが正攻法だが面倒。 最近ではBoost.Iostreamsが支援してくれるけど。
810 :
デフォルトの名無しさん :2007/05/25(金) 01:08:57
CからC++に移行するためにCの勉強はじめた。 #include <stodio.h> int main(void) { printf("Hello, World!!\n"); } (゚∀゚)=3 ムッハー!!
が、がんがれ〜w
C++とCは別物的な書き込みもあるようですね。 みんなどのあたりからC++へ移行したの? とりあえず入門本は理解したから、あとはポインタとかをしっかり勉強してから C++へ移行しようかとか思ってたんだけどアドバイスください。
奥村先生の本がお薦めだよ
ヘッダに関数の中身の書いてあるソースや ヘッダに構造体がtypedef structじゃなくてstructだけで宣言してあるソースが たくさんあるソースを綺麗にする作業にあたった・・・逃げ出したくなった・・・orz 結構つらいなこれ 引数に int getSub(struct RGB_LL_COLOR col) とかあって、こんな使い方正直みたことなかった・・・ どうしてstructをtypedef structに直すとエラーが出るのかさっぱりわからんかった 今日、ちょっとだけ理解できた・・・気がするw
それってC++どころかCでもかなり初歩じゃん
struct RGB_LL_COLORのままで構わないと思う
>>817 それだとヘッダが重複するとインクルードガードがあっても
エラーがでるやんか?
それはtypedef使うと解決できる問題と思えない
>>819 そもそも俺がtypedefもstructもどういう命令文なのか理解できてないのが問題だな
構造体はこうやって宣言するんだぞ。以上
って入門書読んだだけだったからなーw
最初こんな↓風になってた
ヘッダ部(ここから)
構造体定義
struct RGB_LL_COLOR{
int *R;
int *G;
int *B;
}Rgb;
関数定義
int setRgbColorXXX(struct RGB_LL_COLOR *out,int a,int b);
ヘッダ部(ここまで)
このヘッダを#includeしようとすると一箇所でしか#includeできない
#includeしてるヘッダも一箇所でしか#includeできない
って状況だった
ところでこんなスレにいるからには、ついでにC++化しているということでいいのか? ならtypedefを使わずともstruct RGB_LL_COLORではなく、RGB_LL_COLORと使えるぞ。
>>821 こまかいことは気にするなw
ああ、ちなみに間違えた
>>820 の関数定義は内容も書いてあった
int setRgbColorXXX(struct RGB_LL_COLOR *out,int a,int b){
内容が書いてある
}
まあ、
>>820 を普通にこう直したんだ
ヘッダ部(ここから)
構造体定義
typedef struct{
int *R;
int *G;
int *B;
}RGB_LL_COLOR;
関数宣言
int setRgbColorXXX(RGB_LL_COLOR *out,int a,int b);
ヘッダ部(ここまで)
ソース部(ここから)
ヘッダのインクルード
#include "rgb_color.h"
関数定義
int setRgbColorXXX(RGB_LL_COLOR *out,int a,int b){
内容が書いてある
}
ソース部(ここまで)
という感じにしてどこからでもヘッダを呼べるようにした
>>820 の状態ではヘッダとソースでわけることもできんかった
まず「宣言」と「定義」の区別が曖昧だから、しっかり意味を確認しような。
>>820 が駄目なのは struct ... Rgb; という変数がヘッダで定義されてるから。
>>822-823 ではその変数の定義が消えてるんだが、いいのか?
>>824 そうそう、グローバル変数になってたから消した
> このヘッダを#includeしようとすると一箇所でしか#includeできない > #includeしてるヘッダも一箇所でしか#includeできない インクルードガードかけろよ まあヘッダでインライン関数でない関数を定義するのは論外だけどさ
>>826 いや、だからダメだったんだって
書いてあるっしょー
ちなみにインクルードガードをつけてもダメだったから struct RGB_LL_COLOR{ int *R; int *G; int *B; }Rgb; こう↑なってたのを struct RGB_LL_COLOR{ int *R; int *G; int *B; }; こう↑やってみたりもしたけどやっぱり駄目だった希ガス まあ、とにかく色々いじってダメだったんだ
>>828 その変更はインクルードガードが正常に機能するでしょう。
そろそろスレ違いなんで適切な場所に移動しませんか。
つまり、>814も>814が預かったソースもダメ過ぎってことだろ?
有り体に言えば、そう。
=演算子をオーバーロードしたときに return *thisを使うのはなぜですか? +演算子でつかっていた return tmp;ではどうしてだめなのですか?
副作用が起こるのが=だから、普通はtmpなんて宣言しないしtmpなんて返さない。
どういうしくみでその副作用が起こるのかがよくわかりません・・・・
副作用の意味を辞書で調べてきなさい
>>832 Effective C++ くらい買っとこうや。
>>832 1. 値を返すより参照を返すほうが効率的だから
2. (x = y) = z;のような病的な例に対応するため
一般に(複合)代入演算子の結果は組込型だと左辺値になるはずで、それと同じ挙動を目指していると考えればいい
effectiveC++って独習C++とAccelerated C++の演習を 一通りやった程度の経験で理解できるでしょうか? なんか書評見ると中級者向きって書いてあってなんか難しそうなんですが・・・・
>>838 >effectiveC++って独習C++とAccelerated C++の演習を
漏れはどっちもやったことないけどEffectiveC++は理解できたよ。
つーか、半年C++と悪戦苦闘して見つけたノウハウが全部書いてあって笑えた。
♥
すげえ基本的なことなんですが・・・。 Cの時ってDBとかファイルとかからデータもってき足りする場合は大体構造体で管理してました。 a[i].name=なんたらって感じで これってC++ではクラスで定義するかと思うんですが、メンバ変数がいままでの構造体データに相当して、 メンバ関数を色々定義して便利に使う、という解釈でいいんでしょうか? (ンストラクタとかデストラクタとかは自分で定義して) 後、一々書くの面倒だからこれ使えば?ってのはあったりします?>STLの様なもので。
843 :
841 :2007/07/04(水) 19:51:08
>>840 ちょw冷たいww
ってよくみると誤字脱字ひどいですな、スマソ。
Effective C++ 買ったし、読んで好きにしてやるうううううう。
844 :
841 :2007/07/04(水) 19:51:46
840は842の間違い・・・orz
845 :
841 :2007/07/04(水) 21:44:40
Effective C++読んだらいかに馬鹿馬鹿しい質問かというのが分かり申した。 大人しくconstで定義させていただきマッスル。 自分で全定義書くのもありだし、vectorあたりでその辺省略するのもありですな・・・素晴らしい。
846 :
デフォルトの名無しさん :2007/07/05(木) 17:49:09
クラスのコンセプトについてわかりやすく解説しているサイトを教えてください
C++でやるならクラスは使ったほうが良いの? 俺が組むプログラムはstructで事すんじゃうんだけど たまにわざわざクラスを使ってみたりしてる クラスだと何がどう良いのかマジわかんない教えて
>>848 そう思うのなら、使わなくていいんじゃない?
私が作るC++のプログラムも、1/3はクラスを使わないし使ううちの半数はstructで済むし。
1、C++の場合、class だとデフォルトで private、struct だと public。違いはこれだけ。 2、classが使いたくなるまでは、無理して使う必要はない。 3、クラス使わないのにC++を使う理由は? いろいろあります、好きなのをどぞ。
1.だね。 いつも明示的にprivate等はつけてるので、違いは無いって思ってる。 まあ好きなほうで書けば。
参照ってどんなときに使うものなのでしょうか?
ポインタを変更しないことが分かりきっていて、かつ * を打つのが面倒なとき
でっかいものを渡すとき 普通に渡すとでっかいもののコピーが渡されて容量を無駄に食ってしまうので その代わりに参照を渡してやればコピーが生成されない分節約になる
あとはコピーを生成してはいけないときなどに使うんだが これは現段階で色々説明するのは難しいと思う
>>855 Cだとconstなポインタを使っていたところだな。
858 :
デフォルトの名無しさん :2007/09/24(月) 07:44:50
>>855 でっかいものって、もともと配列はコピーされないんじゃないの?
クラスとか構造体とか配列以外にもでっかいものは色々ある。
北海道?
俺の夢とかもな
ちっちぇ〜w
漏れのぬるぽはでっかいですよ。
♣アッー♠おっきい♥
865 :
デフォルトの名無しさん :2007/09/28(金) 05:37:31
なんで ウホッ♦ が無いんだ?
このスレは勉強になるな。やっぱり。
ならやらないか
入れさせてくれるのなら?
869 :
デフォルトの名無しさん :2007/10/12(金) 17:12:11
テンプレートを使い始めたら、コンパイル時にリンカエラーが出るようになりました。 ネットで調べてみたところ、ヘッダファイルに本体もすべて書けばいいとのことですが、 こんな方法しか解決方法はないのでしょうか?
テンプレートの明示的実体化という方法もある。 こちらからコンパイルして欲しいものを指定するというやり方。
ktwr
>>870 テンプレートの明示的実体化というのはどのようにやればよいのでしょうか?
Cでは配列を関数に渡すのにポインタ経由してましたが、 C++で参照を駆使してどうにかなりますか? 配列への参照、って可能?
>>875 参照は実際のプログラミングではまず使わないから安心して
878 :
875 :2007/10/21(日) 21:13:36
ごみん自己解決
というか、C++では「配列」をまず使わない。 みんなstd::vector。当然渡すのもvectorへの参照。
C時代に void strhoge(void); void wcshoge(void); #ifdef _UNICODE #define _tcshoge wcshoge #else #define _tcshoge strhoge #endif _tcshoge(); って書かれてたコードを void str::hoge(void); void wcs::hoge(void); #ifdef _UNICODE namespace tcs = wcs; #else namespace tcs = str; #endif tcs::hoge(); と書き換えてみたんだけどC++的にはあり? namespace ってマニュアル読むとCのマクロ並に他の識別子を隠す危険機能みたいなのに、詳しく説明してる本とか見つからない。 namespace 名前付け規約みたいのってあります?
そういうコードはもちろん可能。 名前空間の名前付け規約というようなものはない。 みな勝手に名前を付けてる。
そうなんですか、怖いですね。 名前の上書き力はマクロの次ぐらいに強いのに。 オープンだからダブっても気にしないってことなのかな。 無名 namespace が絡むと途端に繊細になるし... namespace A{ namespace{ hoge; }} namespace{ namespace A{ hoge; // 別物! }} A::hoge // 解決できない! アクセス方法は?
名前空間は識別子をだぶらせないための仕組みだけど、 名前空間をだぶらせない方法はない。 いや、あるにはあるけどそれは結局名前空間という無限再帰。
>>876 CとしてC++をつかう状況であるならひどい。例えば・・・
あるプロジェクトのリーダがC++をよくしらないとする。
自分がレビューできないもんだから、C++特有のコード
はかかない規約をつくっちまう。
そうするとC++が適切につかわれず、コストかけてC++
を勉強したチームメンバはモチベーションがさがる。
あるある。 #define で数値を定義するときははカッコでくくれ、とか。
>>886 括弧で括るのは当然じゃないか。
問題は、数値をdefineマクロで定義することの方だろ。
は?だからstatic const を知らずに変な規約作るおかしさを書いたわけだが?
その規約自体は(過去の柵などの理由があれば)おかしくはないだろ。 別途、「定数値は(原則として)static const を使え」とでもしておけばよろしい。
890 :
デフォルトの名無しさん :2008/01/21(月) 20:14:21
Cプログラマの為に、ポイントをまとめたドキュメントを販売しています。
プロのプログラマでもあまりにレベルが低い人が多すぎます。
そんな人に限って、自分のレベルの低さを自覚していない、、、
本人は構わないかもしれませんが、その下についた新人プログラマは
たまったものではありません。(私が経験しました。)
今になって分かりました。
彼らもまた、理解できていなかったのです。
プログラミング言語の一番の習得の近道はきちんと理解している人にアドバイスをもらうこと。です。
私のC言語に取り組んだ7年間をすべてぶつけたつもりでテキストを作りました。
私の会社の後輩からは、どんなテキストよりもわかりやすかった!や、
今まで教えてくれていた先輩や、テキストたちが、ちゃんと理解できていないことがわかりました。
と、嬉しいコメントをたくさんもらいました。
そしてなにより、彼らの社内での評価がとても高いということが、私の誇りです。
興味がある方はどうか、下のサイトをみてみてください。
http://mori.eco.to/
C言語の知識、経験はあるのですが、C++を覚え始め難しいと感じています。 C++の文法を解説した本、オブジェクト指向について解説した本をいくつか読み、 そろそろ手で打ちながらより実践的に覚えていこうと、C++を使ったシューティング ゲームプログラミングの本を片手にやろうとしているんですが、内容が難しく感じます・・・。 段階的にC++を身につけていけるような書籍をご存知ないでしょうか? クラス図なんかを見ていると楽しいですし、規模の大きなプログラムが作り易そうな 期待が持てます。 ちょっとずつ身につけていけたらと思っています。
893 :
892 :2008/03/02(日) 21:28:08
ageます。
仲間クラス×4(攻撃、回復) ボスクラス(攻撃、全体攻撃) を作成してドラクエのようなターン制戦闘ができるプログラムでも作ってみれば 全員HPと攻撃力、防御力、素早さあたりのパラメータを持つとして。
そうだな、 仲間2人は攻撃しかできない戦士クラスで もう2人は攻撃と回復ができる僧侶クラスとでも名付けて、 僧侶クラスは戦士クラスを継承したクラスとして作ってみるといい 継承やオーバーロードといったものが理解できてないと作れない
制限時間は一日ぐらいを目安な ちゃんと基礎がわかってるなら一時間ぐらいで作れるはず
>>892 解説書を理解していたらシューティング程度であれば難しくないはずだが…。
流し読みか?
898 :
892 :2008/03/05(水) 00:55:36
みなさん、ありがとうございます。 ご指摘いただいたことを目安に取り組んでみます。
ワロタ
__stdcallが よくわかりません 関数に__stdcallをつけるとつけないと何が違うのでしょうか? つけるメリットは何?
C++への移行とはなんの関係もないな。 stdcallは関数呼出の方法の1つ。引数を渡すのに使ったスタックポインタを戻す役目が 呼び出された関数側にあるのが普通と違う。 呼び出された関数側でスタックを戻すと、x86ではややコードを短くできるので 16ビット時代には重宝された。今では結構どうでもいい。 (16ビットのときにはstdcallなんてなかったけど) 32ビットWindowsが__stdcallを多用している関係上、 こっちが作る関数でも__stdcallの指定を要求されることがある。 また、Windowsでは他の言語でも stdcallのDLL関数は呼び出せるというものが多い(VBとか)というのは利点と言える。 だから、DLLで公開する関数には付けておけ。 あとはWinMainとか必要なものに付けるという感じ。
DLLで公開する関数って WINAPI でないの?
903 :
デフォルトの名無しさん :2008/03/07(金) 07:06:10
__stdcallの別名がWINAPI
904 :
デフォルトの名無しさん :2008/03/08(土) 14:09:51
関数名におまんこぜんかいって名付けると運気アップ
905 :
デフォルトの名無しさん :2008/03/08(土) 14:24:16
初歩的な質問ですみません、c++で下記のような動作をするクラスを作る場合、 Test2宣言についてどうやればいいのかわかりません。 検索エンジンでクラス定義について調べたのですが参考となるものが見つからなくて… ご教授してくださると助かります。 #include <stdio.h> class Test1{ public: Test2 *pT2; // ←意図的にTest2のクラスを呼び出したい void print(){printf("test1\n");} void test(){ pT2 = new Test2();pT2->print();delete pT2; print(); } }; class Test2{ public: Test1 *pT1; void print(){printf("test2\n");} void test(){ pT1 = new Test1();pT1->print();delete pT1; print(); } }; void main(){ Test1 t1;Test2 t2; t1.test();t2.test(); }
Test1の定義より先にclass Test2;と書いておく。 これ、前方宣言という。
上記を元にこのように修正しました。 // 前方宣言 class Test2; class Test1{public: Test2 *pT2;void print();void test();}; class Test2{public: Test1 *pT1;void print();void test();}; void Test1::print(){printf("test1\n");} void Test1::test(){printf("Test1::test()の呼び出し :");pT2 = new Test2();pT2->print();delete pT2;} void Test2::print(){printf("test2\n");} void Test2::test(){printf("Test2::test()の呼び出し :");pT1 = new Test1();pT1->print();delete pT1;} void main(){Test1 t1;Test2 t2;t1.test();t2.test();} 出力結果 Test1::test()の呼び出し :test2 Test2::test()の呼び出し :test1 お世話になりました。
>>908 そのメルマガ、著者の知識が偏っているから要注意ね。
--
C++言語では、
struct _stFoo
{
int member1;
double member2;
};
と定義すればそのまま、
_stFoo stfoo;
と、型として変数定義することができる。
--
流石にこれはないだろw
>>910 引用箇所の問題点がよく分からん。予約名を使ってるのが悪いのか?
Cだと、 struct hoge { ... }; struct hoge hage; としなければならないのを、 C++では、 struct hoge { ... }; hoge hage; でもおkだよ、というのを説明してるんだろうけど、何が問題なのかはよく分からんな。
namespaceの意味が分からん・・
事務課の田中小枝子さんと 秘書課の田中小枝子さんを区別するためにある 秘書課に田中小枝子さんが二人いた場合は 部長の愛人の田中小枝子さんと 課長の愛人の田中小枝子さんで区別しろ
>>914 みな同一人物のヤリマンというわけですね!
>>913 俺ライブラリ
namespace oreore{
template<class Ty>
void foo(Ty x) {
bar();
}
}
自作プログラム
namespace oreore {
void bar() {
}
}
int main() { ... }
このように既存のライブラリに機能を付け加えて、
どの関数が呼ばれるのか分かりにくくする目的がある
917 :
デフォルトの名無しさん :2008/03/18(火) 01:09:24
STDMETHODつけるとなにがいいのかな?
タイプ数削減。virtual HRESULT __stdcallの短縮になっている。
919 :
デフォルトの名無しさん :2008/03/23(日) 01:36:00
ありがとう
920 :
age :2008/03/23(日) 22:11:20
ユニドライバのソースにでてくるPOEMDEV とはなんですか?
型なのはわかるんですが。。。あとユニドライバの開発に詳しい人
いたらお金を出すので専属で俺に指導してくれませんか?
質問はメール。場合により電話
報酬は月5万円固定。
でお願いします。「俺はユニドライバにくわしいぜ!」というやつ
いたら
[email protected] におねがいします。m(_ _)m
__stdcallの中でDのクラス生成したりすると速攻で落ちるのはなぜですか?
ma ti ga i ma si ta
>>921 いい事いうじゃねえか。
で、やれるんだな?
今すぐ頼むぞ。
すいませんが、 構造体の代入についてなんですけど、 struct papa{ int number; int mama_number; } struct papa menber[5000]; for(i=0;i<5000;i++){ menber[i]={i,i}; } これをC++なら実現可能ということなので、 ヒントだけでも教えてください。すいません。
Cでもキャストしたら入らないかな? = (struct papa){i,i} とりあえず手元のGCC4.1.2ではできたけど...
927 :
926 :2008/07/07(月) 21:50:07
連投失礼。C++の場合はCスタイルのキャストは余り好ましくないとされるので注意。 メンバ変数はprivateにして、メンバ関数でアクセスが普通のやり方じゃないかな?
クラス指向の概念は理解できましたが、その設計構築がいまいち理解できません どこかクラス設計の解説に長けているサイトや書籍はありませんか?
VC2005以外のC++でも1つのクラスに属する関数を複数のcppファイルに 分けて記述することは可能ですか? Cのextern宣言みたいなものは必要でしょうか。
#include
できるお classを宣言したヘッダをインクルードしておけばいいお
935 :
デフォルトの名無しさん :2008/09/22(月) 13:08:26
char[]ではなくstringクラスを使うにあたって itoa()やatoi()にあたるコードはC++ではどう書くべきでしょうか
>>935 std::istringstream is(str);
is >> a;
もしくはboost::lexical_cast
というかlexical_castは内部的に
>>936 のようなPSEUDOコードを
使っている
>>935 大仰にしたくなければatoi(str.c_str())でもOK。
itoa()は使わないに越したことはないからstringstreamかね。
>936 なるほど、stringstream系を通すと変換できるのですね。 >937 boost はまだ試していないのですが、色々便利そうです。 そのうち試してみます。 >938 折角C++なのでC++流に書いてみます。 本来ならCでもsprintf()やsnprintf()を使う場面ですが 説明しやすいためitoa()と書いてしまいました。
凄い基本的な(?)ことで申し訳ないんですが coutとprintfは同時に使えないんでしょうか? コンパイルは通りますが、実行時にprintfのところでエラーが出ます。 ヘッダを色々変えてみたり、using namespace std;をつけたり外したりしましたが駄目でした。 よろしければお願いいたします。
確か使える保証はないと書かれてたはず……だがどこに書いてあったか思い出せない。 一応バッファリングの問題とかがあるからね。 Boostが使える環境ならcout、そうでないならprintfの方が便利だと、俺は思う。
>>940 混在させるとバッファリングの関係で出力に影響があるかも知らんが、
実行時エラーにはならないと思うんだ。
何かprintf()の使い方を間違っているんじゃないか?
# printf(str.c_str())していて、strの中身に%が含まれているとかw
>>944 初心者の頃にやったなあw
最初の頃はprintf("%s",str);とか思いつかなかった。
946 :
940 :2008/09/22(月) 20:26:06
ありがとうございます
てことは私が何かポカしてる可能性が高いんですね
明日もう一度確認してみます
>>942 VC2005です
>>943 >>944 今手元に無いんですが
「メモリが“read”になることができない」
「メモリが"written"になることはありませんでした」みたいなエラーです
まずい領域を参照したみたいな
でも printf("a"); でもエラー吐くんですよね
げ、sage忘れたorz
>>940 std::sync_with_stdio()はtrueを返すよね?
>944-945 って言うか printf(変数) は危ないよ 第一引数は必ずフォーマットか文字列中に%を含まないと確実に保証できる文字列にすべき それが問題になったソフトウェアは結構あるらしいしな
950 :
940 :
2008/09/23(火) 15:44:15 解決しました 別の場所で配列に値を入れるところで、変なアドレスに値を入れていたみたなんですが どういうわけかprintfの部分でエラーが出るようになっていたようです そもそも最小構成で試してみたら全く問題ありませんでした お騒がせして申し訳ありません