1 :
デフォルトの名無しさん :
03/01/27 03:24 怪しい仕様は細々ありますが大丈夫です!
elegantなソースを目指してね。 関連URL
>>2-10 v(^・^)v
2 :
デフォルトの名無しさん :03/01/27 03:24
3 :
デフォルトの名無しさん :03/01/27 03:25
4 :
デフォルトの名無しさん :03/01/27 03:25
5 :
デフォルトの名無しさん :03/01/27 03:25
6 :
デフォルトの名無しさん :03/01/27 03:26
7 :
デフォルトの名無しさん :03/01/27 03:26
来てみました。特に用件は無いです。 聞きたい事は、山程在るんですが、 理解してなさ過ぎなので、力付けたいと思います。
>>10 律儀なのはいいけど、ここは馴れ合いのスレじゃないので挨拶せんでもいいです。
12 :
デフォルトの名無しさん :03/01/27 06:42
13 :
デフォルトの名無しさん :03/01/27 07:39
template<class T> void foo(void){} template<class T> inline void foo(void){} 上の書き方では、インライン展開はされないんですか? それとも両方同じ意味?
>>13 上下で意味が違う。上が普通。下がinline指定付き。
>>14 答えになってないだろ。
「普通」 ってどういう事だよ。
まあ結局は、最適化の方法によると思うけど・・・。
場合によっては inline も無視されるし。
>>15 あーすまんな、そこでいう普通ってのは、inline指定無しってことだ。
>>16 そんな事は一目瞭然だろ。
13 は、実際にどうなるかが知りたいんだろうに。
>>17 そんな事は言えないだろ。
>>15 にも「まあ」以下にちょっと書いてあるし。
>>18 15=17 ですが何か?
どうして言えないと思うんだ?
「インライン展開はされないんですか?」 が実際にどうなるかという話で無いと
したら何だというんだ?
inline を指定した事になるのか、という質問には見えない。
なんかスレ立て早々、戦争が勃発してるし。
>>1 乙。
>>19 え、だって、「それとも両方同じ意味?」とかゆってるし・・・。
インライン展開されるかどうかはinline指定の規則に従うってことで済ませとかないと
コンパイラからコンパイルオプションから聞き出さない限り意味のある答えはでないだろ。
>13が環境を示さない限り「実際にどうなるか」って話は意味無い。
ってなわけで、「実際にどうなるか」の話なんて漏れにはできん。
>>19 よ、見本でもみせてやってください。
>>13 どちらでもほとんどの処理系でインライン展開はされると思うが、リンケージが異なる
かな。C++ だと inline 関数のデフォルトリンケージは static なんで、オブジェクトに
特殊化したテンプレート関数を格納したい場合(ライブラリ作る場合)は前者でコンパ
イルしないと、まずいと思う。
23 :
デフォルトの名無しさん :03/01/27 10:31
> C++ だと inline 関数のデフォルトリンケージは static これほんと? ドラフトの中にこんなんあるけど。 [Footnote: The inline keyword has no effect on the linkage of a function. --- end foonote]
24 :
デフォルトの名無しさん :03/01/27 12:44
まだC++をはじめたんですけどなかなか覚えれなくて みなさんどんな感じでC++を覚えたのでしょうか?
すみません下げ忘れてました。
>>24 俺はC++3rdを頑張って読破した。(Cは多少わかってる状態で)
とりあえずC++3rdを買って読む。あとは
>>1 が頑張ってくれたテンプレ集とか、cppll ML(最近質が落ちてるけど)とかわからなくても漁ってみるべし。
わからなくなったら周りのC++に詳しい人とか、このスレで聞くといい(叩かれるかもしれんが…)。
cppll ML
http://www.trickpalace.net/cppll/ で、
>>1 乙カレー
あ、ちなみに俺の言った方法はよほど暇人じゃないとできないかも。(いろいろ他の言語をつまみ食いしながら二年位かかった) 中学〜高校のときだったしなぁ…。 仕事で今すぐ必要というならアドバイスできませぬ。なにせ趣味グラマなもんで。
28 :
デフォルトの名無しさん :03/01/27 14:09
■■■■■I90vmCq+さんへ■■■■■ こんにちはMlQ38syLです。 ボクのくだらん遊びに付き合ってくれてありがとうございます。 仕事でなかなか良いアイデアが浮かばなくってイライラしてました。 おかげ様で良い気分転換が出来ました。 仕事に戻ります。サンキュ♥
perlみたいにいろんなライブラリがラインセンスフリーで出回んないかなぁ。
>>26 いまcppllはtietewによる新人いじめの真っ最中なので不適かと。
#あれじゃ「身内」以外は投稿しにくいよなぁ。
13です。言い方が悪くてすいません。
>>13 上の書き方では、インライン展開はされないんですか?
この意味は、「実際に展開されるかどうかではなく、inlineを付けなくても
inline指定したことになるのか?」っていう意味でした。
テンプレートは、コンパイル時に定義が見えなくてはいけないのでinlineを付けなくても同じかなと。
>>22 ちょっと状況が想像できません。調べてみます。
>>34 inlineを付けなくてもinline指定した事になるのは、クラス宣言部内で
メンバ関数を定義した時だけでは?それ以外の時は明示的にinline
と指定する必要がある。
ちょっとお聞きしたいんだが vector<int> v; vector<int>::iterator i = v.begin(); ++i; //これは未定義ですか?不定?それとも安全?
ちょっとミス v.begin → v.end ということです。
>>36 vector<T>::iteratorの型は大体の処理系でT*だから、++iをする分には問題ないけど、
それを操作するとマズいことになると思われ。
仕様がどうなってるかは仕様書を見てくれ。
> vector<T>::iteratorの型は大体の処理系でT*だから、++iをする分には問題ないけど、 そーゆー認識ってマズーだと思う。
>>13 -
テンプレート関数はヘッダに書けるけど、inline指定しなくてもいいんだよね。
じゃ、普通の関数をヘッダに書きたいけどinline付けたくない!ってとき、
template<int dummy> void hoge_imp(void){ //普通の関数のつもり}
#define hoge hoge_imp<0>
main(){ hoge(); }
って書けばよさげじゃない?
#defineが汚いけど。
>>40 > 普通の関数をヘッダに書きたいけどinline付けたくない!ってとき
どういう場合にそんなことがしたくなりますか?
42 :
デフォルトの名無しさん :03/01/27 21:51
>>36-37 この場合、begin()でもend()でも未定義です。
*iが出来ないイテレータについて++i;はできない規格です。
規格書に「未定義」と定義してあるところは見つけられなかったけど...。
で、結局関数テンプレートを実体化したらinlineになるの?ならないの?
45 :
デフォルトの名無しさん :03/01/27 22:01
二次元配列のdeleteってどうやればいいの?
>>5 のspirit 見て感動しますた。何か面白い事出来そうかも・・・何が出来るかな?
48 :
デフォルトの名無しさん :03/01/27 23:48
ハンドルされていない例外がある ってエラーメッセージが出るんだけど、何がわるいのでしょうか?
>>48 0 除算やメモリアクセス違反などを疑え。
50 :
デフォルトの名無しさん :03/01/28 01:00
構造体を宣言して、その構造体を他の構造体の要素に するということはできるのですか? kouzoutai.kouzoutai2.youso見たいに書くと思うのですが。 一般にやっぱりあまり使われませんよね?
使うよ。
>>50 API絡むとごく普通に使われてると思うが。
ありがとうございます。 今構造体をある構造体の中に組み込んで kouzoutai[i].kouzoutai[j].yousoという風に使いたかったので。 どうやらごく普通に使っているならそのまま使ってみたいと思います
>>53 クラスを他のクラスの中に入れるとコンポジションとなって少し意味が
変わるかもしれん。
どういうことですか?
>>55 メンバ関数を含む構造体を他の構造体に入れると、オブジェクトの再利用の
観点から特別な意味合いを含むようになる。
特別な意味合いってつまりは使い方を特別にしなければいけないということでしょうか。 質問ばかりですいません
>>36 std::vector<T>::iteratorはランダムアクセスイテレータです。
ランダムアクセスイテレータに対してoperator++()を適用するには、
適用前に参照はがしが可能、適用後に参照はがしが可能または
最後を過ぎた状態でなければなりません。(仕様書参照)
この場合、vは空であり、v.begin()にしろv.end()にしろ、
v.end()を返し、これは参照はがしが出来ません。よってこれは
operator++()が適用前に必要な条件を満たしていませんので、
結果は未定義です。
>>57 構造体がメンバ関数を含んでいなければ別に気にする必要はない。
含んでいても、だからある特別な使い方をする必要があるという意味で
はない。特別な使い方を意識すればバグが出にくくなる、それだけ。
わかりました。ありがとうございます。特にメンバ変数を含んでないので。がんばります
>>58 規格書の事を仕様書仕様書って言うなよ・・・
>>62 そんなものを 「参照」 と言われても・・・
STLとAPIの命名規約がちがうのでソースが見にくいです。STLで ”_” を使うのはやめてください。
標準規格の STL のネーミングを俺様APIのネーミングに合わせろってか。
シリアル接続でストップビットを"2"にすると、 ポートに接続できなくなるのですがなぜですか?
68 :
デフォルトの名無しさん :03/01/28 20:16
>>67 すみません。C++とどういう関係があるんでしょうか?
69 :
デフォルトの名無しさん :03/01/28 20:32
いま、クラス設計をやっています。 Win32 API で行われているようなかんじで、登録されたデータを ハンドルで管理したいと思います。 ハンドルの生成/開放を行う、一般的な方法はありませんか? 単純だし、自作できるとは思うのですが標準で用意されてるなら そっちを使ったほうがいいかと思いまして。
>>69 オブジェクトのポインタで充分ではない理由があったら聞かせてくれ。
>>60 > 特にメンバ変数を含んでないので。がんばります
^^^^
どうがんばる気だ ?
73 :
デフォルトの名無しさん :03/01/28 21:29
なるべくプログラムからポインタを排除したく思い、これからはメソッドの引数に参照を使うようにしようと思っています。 でも、例えば void SetCurRecord(const CRecord *curRecord); みたいなやつがあったとして、これを参照で渡すようにしてしまうと、わざとNULLを与えてデータをクリアするという事が出来なくなってしまいます。 他にも void GetProperty(short *prop1, short *prop2 = NULL, short *prop3 = NULL); こういう風にして欲しいデータだけ取り出したいようなインターフェースが作れなくなってしまう気がします。 参照とポインタの使い分けテクを教えてください。
> なるべくプログラムからポインタを排除したく思い なんで?
だからスマートポインタ使えって。 あと、うかつに delete されたりするのがいやなら、デストラクタを protected/private にして、public な release メソッドでも作る。
利用者にはポインタのアドレスをハンドル値として 見せてしまえばいいんでは?
78 :
デフォルトの名無しさん :03/01/28 22:47
>>78 リンク先読んだが、どうも筆者がコンテナやstd::stringを痛く気に入っている
という事は理解できたが、だからと言って「ポインタ不要」とばっさり言い切って
しまっている点がいただけない。
ポインタはC++でも必要な場面はいっぱいある。コンテナが使いやすい事は
認めるが、効率が最高かと言えばそうでもなかろう。
81 :
デフォルトの名無しさん :03/01/28 23:11
>>79 お疲れさまです。
オッチャンも全くそう思うんですが、使い分けの基準がハッキリしないのが気に入らないのです。
さっきの引数の話でもそうですが、「なるべく参照を使うようにして、無理なところはポインタ」っていうのでいいんでしょうか。曖昧だなあ…。それならもう最初から全部ポインタでも良いような…。
>>78 あなたが、そこに例の挙がっているようなミスを犯さなければ、ポインタを避ける
理由は何も無いのだが。
それにポインタが無いと、C++ のうまみである多態がコードで表現できない。
人の論を参考にするのはいいが、鵜呑みにはするなよ。
83 :
デフォルトの名無しさん :03/01/28 23:18
>>82 >あなたが、そこに例の挙がっているようなミスを犯さなければ、ポインタを避ける
まあそうですが、間違いが起こりにくくなるならそれに越したことは無いかなあと思うわけでして・・・。
>それにポインタが無いと、C++ のうまみである多態がコードで表現できない。
や、とりあえず関数の引数についてだけでいいです。
>人の論を参考にするのはいいが、鵜呑みにはするなよ。
肝に銘じます。こうもっともらしく書かれると信じてしまいがちですからなぁぁあ
>>73 あくまで漏れの意見ね。参考程度に。
> void SetCurRecord(const CRecord *curRecord);
これは、Recordset のようなオブジェクトを作って、カレントはインデックスで
管理した方がいいと思う。
> void GetProperty(short *prop1, short *prop2 = NULL, short *prop3 = NULL);
どんな時にこれが必要になるのかわからない。
Property prop1;
prop1.get();
とかのが好き。
85 :
デフォルトの名無しさん :03/01/29 00:27
>>84 どうもです。
>これは、Recordset のようなオブジェクトを作って、カレントはインデックスで
ああ・・ちょっと上手く伝わらなかったでしょうか
例えばプレビューウィンドウにSetImage(const CBitmap *image);とやるところをSetImage(NULL);ってやったら表示してた絵が消えるとか
他にも色々あると思うんですよ、NULLを渡したい時が
>どんな時にこれが必要になるのかわからない。
何が言いたかったのかといいますと、デフォルト引数にNULLが使えると色々便利だと思ったのです。
他にもWin32APIでもデータへのポインタorNULLを引数に取るやつが色々あります。
その場合、引数には参照しか使わないというルールをゴリ押しすると、何か空(デフォルト)のオブジェクトを作って引数に渡すという無駄な事が発生するので嫌だなあ、と。
>>78 途中まで読んだけど何やねんコレ…
char * abc_str = "aBC" ;
abc_str[0] = 'A' ; /* 'a'->'A'に上書き */
87 :
デフォルトの名無しさん :03/01/29 00:32
>>86 >バグその1「ポインタの構文や概念は理解しにくい」
こういう間違いが起こり得ると言う事が言いたいのでは
洗練されたC++プログラムからはポインタが消え失せるというのは判る。 実際そうだし。でも78のはちとズレてるな。
>>87 こんな事書いたら例えポインタを本当に理解してても
筆者がポインタを理解してないだけってオチで落ち着くと思うけど
せめて char abc_str[] = "aBC"; だよなぁ。
91 :
デフォルトの名無しさん :03/01/29 00:39
で、関数のパラメータはポインタか参照かドッチ?というか、どう使い分ければ?
>>88 > 洗練されたC++プログラムからはポインタが消え失せるというのは判る。
OO で設計する限り、ポインタ自体は消えないだろう。ただ寿命管理に関して、
手作業で delete する機会は、ほぼなくなるが。
>>91 NULL がありえるならポインタ。なければ参照。
その場で値を作って渡したいなら const 参照。
93 :
デフォルトの名無しさん :03/01/29 00:56
94 :
デフォルトの名無しさん :03/01/29 00:58
>その場で値を作って渡したいなら そういうコンストラクタがある場合だよな
>>92 > OO で設計する限り、ポインタ自体は消えないだろう。ただ寿命管理に関して、
C++で設計する限りの間違い。
微妙にズレてるってことは78のページの人が来たのか?
>>95 別に間違いじゃないだろ?
97ゲットオォォォォ!!
 ̄ ̄ ̄ ̄ ̄∨ ̄ ̄ ̄ (´´
∧∧ ) (´⌒(´
⊂(゚Д゚⊂⌒`つ≡≡≡(´⌒;;;≡≡≡
 ̄ ̄ (´⌒(´⌒;;
ズザーーーーーッ
>>94 Yes
そもそも「その場で値を作って渡す」という使い方をするのは、string や complex
のような値指向のクラスがほとんど。仮想関数無し、代入・コピーありってヤツね。
99 :
デフォルトの名無しさん :03/01/29 01:24
スマートポインタの所有権の概念が理解できんな。 ヒープに作ったオブジェクトをdeleteしてくれるだけで十分なのに。 どういう使い方するんだこれ
そういえば pImpl がお気に入りになってからは ユーザーコードからはポインタ減ったな。 内部的には増えたわけですが。
>>99 どのスマートポインタについて言ってるんだ?
102 :
デフォルトの名無しさん :03/01/29 01:27
pImplってなんや
>その場で値を作って渡したいなら const 参照。 ドーユー事?もっとアホにも分かるように言ってくれ
>>104 void aho(const std::string& aho);
aho(std::string("aho"));
>>99 ヒープに作ったオブジェクトを「誰が」deleteしてくれるのか
を決めるのに、所有権の概念が必要。例えば
typedef char* char_ptr;
char_ptr hogehoge() { return new char[100]; }
char_ptr q = hogehoge();
のchar_ptrをスマートポインタ化することを考えると、hogehogeの返値の
テンポラリオブジェクトが破棄される瞬間(2行目の文が終わる瞬間)に
deleteされちまったら困る…(この文の後でqを使えないのでは無意味)。
だから例えばstd::auto_ptrの場合、テンポラリからqにポインタがコピーされたら、
その時点でqに「所有権」を移して、q以外のオブジェクトは勝手にdeleteしないようにする。
なので、俺はスマートポインタのコピーなんかしねぇぞ! という人には
auto_ptr は確かに不要だと思う。そんな貴方には boost::scoped_ptr をオススメする。
だけど普通、「いろいろ複雑にポインタを渡しまくるけど、確実にどこかで
deleteはせねばならん」 という厄介な問題を自動的に解決するために
スマートポインタを使うもんだと思うので、所有権付きのは無いと結構
困ると思うがどうか。
やべぇ一箇所大嘘だ。 > char_ptr hogehoge() { return new char[100]; } こんなもんauto_ptrでは解放できんので、 > char_ptr hogehoge() { return new char('a'); } とかで一つよろしく。
109 :
デフォルトの名無しさん :03/01/29 06:50
質問です。 #include<iostream.h> class test1 {public: int t1;}; class test2 {private: test1 *ts1l; public: void ts2(test1&); void setlink(test1&); //関連をつなげる関数 void test();}; void test2 :: ts2(test1 &tst1) { cout<<"ts2 :"<<tst1.t1<<endl;} void test2 :: setlink(test1 &tst1) { *ts1l=tst1;} void test2 :: test() { cout<<"test:"<<ts1l->t1<<endl;} void main(void) { test1 *tt1; test2 *tt2; tt1 = new test1; tt2 = new test2; tt2->setlink(*tt1); tt1->t1=11; tt2->ts2(*tt1); tt2->test(); delete tt1,tt2; } を実行すると、test2::test()の方の挙動がおかしくなります。tt1->t1が変化しても動的に変化してくれません。 何故でしょうか?
110 :
デフォルトの名無しさん :03/01/29 07:12
解決しますた。
>>107 > 「いろいろ複雑にポインタを渡しまくるけど、確実にどこかで
> deleteはせねばならん」 という厄介な問題を自動的に解決するために
> スマートポインタを使うもんだと思うので
その場合は auto_ptr も使い物になりませんがな。shared_ptr か、もしくは
侵入型ポインタを使う必要がある。
112 :
デフォルトの名無しさん :03/01/29 11:52
C++ で getchar() みたいな一文字取得する方法ってどんなですか?
113 :
デフォルトの名無しさん :03/01/29 11:54
それと itoa() みたいな数値から文字列に変換する方法も教えてください。
>>112 ひょ準入力からの一文字取得なら
int i = cin.get();
とか(最後はEOFが返るはず)
>>113 ostringstream ostr;
ostr<<"manko: "<<999<<endl;
string s = ostr.str(); //(*´∀`)
115 :
デフォルトの名無しさん :03/01/29 14:55
>>114 ありがとうございます!
もうひとつ質問があるのですが、conio.h の getch()
みたいなキーを押したらすぐ返るようなものはないでしょうか。
ファイルの加工をしようと次のようなコードを書いてみたのですが、 なぜかファイルを上書きしてくれません。どの辺りがおかしいのでしょうか。 コンパイラはborlandです。 using namespace std; int main() { fstream file("foo.txt",ios::in | ios::out); string tmp; vector<string> buf; while(getline(file,tmp)){ buf.push_back(tmp); } file.seekg(0); for(unsigned int i = 0; i != buf.size(); i++){ 中略 file << buf[i] << endl; } file.close(); return 0; }
118 :
デフォルトの名無しさん :03/01/29 15:31
配列要素数0の変数って、どういう扱いになるんでしたっけ? 移植中のあるソースで使いまくってて、、 struct hoge { int Length; char Data[0]; int exSize; char ExData[0]; } みたいなんです。 ここの Data や ExData に、Length もしくは exSize長のデータを 割り当てたい場合はどうすればいいんでしょうか?
>>117 .seekp()にしても上手く行かないようです。
>>116 file.clear()してみてはどうかすら(てきとう)
>>120 できました。
eofbitが立ってたのに全く気づきませんですた。
ありがとん。
>>115 規格書持ってないので詳しくはわからないけど恐らく標準には無いと思うよ。
意味わかったっす・・・
>>70 >オブジェクトのポインタで充分ではない理由があったら聞かせてくれ。
ポインタを使いたくないから、ハンドルを使いたいんです。
ライブラリ利用者に、ライブラリ内部のメモリに直接アクセスされたり、
ポインタを保持されたりしたくないんですよ。
というか、現在は参照のみでポインタは一切使ってません。
できるだけポインタ使わないのが当然かと思ってたのですが
ここの板を見ると業界的にはそうでも無いようですね。
いや、べつに煽りでもなんでもないですよ。
>>124 何の用があって内部のメモリを指すようなハンドルが必要なんだ?
全部クラス内に隠蔽して処理すればいい。
>>118 普通はポインタにするんではなかろうか?
structの中の配列はどうやったって固定長だ
127 :
デフォルトの名無しさん :03/01/29 21:15
スマートポインタってどうやって(何に)使うんですか。教えて偉い人
>>127 new したオブジェクトはほぼ全ての場所でスマートポインタを使うことが望ましい。
コードが例外を throw した時、プログラムは delete をすっ飛ばして呼び出し元に飛んでく可能性があるので、その場合も正しくオブジェクトを破棄するために使用する。
実際最も一般的なのは、単一のオブジェクトを複数の場所で参照している場合、どのタイミングで削除するべきかをカプセル化したい場合など。
またC/C++では、単体オブジェクトと配列でdeleteとdelete[]を使い分けなければいけないが、一度ポインタに格納してしまうと区別がつかなくなる。
スマートポインタでこの問題を解消できる。
他にもNULLポインタにアクセスしようとした時にアクセス違反ではなく独自の例外を throw したり、新しくオブジェクトを作成することで何事もなかったかのようにプログラムを続けたり。
delete できないようにしたり、あるいは delete されてもまた必要になったら自動的に new しなおしたり。
ログを取ったり。
など、いくらでも考えられると。
>>126 void *aaa;
struct hoge *hogehoge;
aaa = malloc( 100 );
hogehoge = aaa;
memcpy( hogehoge->Data, moe, 80 );
みたいに使ってますわ。
memcpy( ((struct hoge*)hogehoge)+1, moe, 80 );
と同じ意味になるようですな
130 :
デフォルトの名無しさん :03/01/29 21:47
すんません、少し聞きたいことが・・・ classの中にpublicで、 LPBYTE bDat LPBITMAPINFO bInfo というのがあって、 それらをGlobalAlloc()で領域を確保してます。 これで画像を表示したいんですが、表示されません。 classのメンバをGlobalAlloc()で確保してはいけないんでしょうか。 コードはプロシージャ内に記述していたときは動作しました。 クラスメンバ関数ではない関数で、上記二つの変数を渡した時は動きませんでした。 ・・・何がいけないのか検討がつきません。お願いします・・・
>>130 > classのメンバをGlobalAlloc()で確保してはいけないんでしょうか。
そんなことはない。
132 :
デフォルトの名無しさん :03/01/29 22:43
>>128 なるほど。う〜ん、、、、便利なような気がする
>>130 > ・・・何がいけないのか検討がつきません。お願いします・・・
質問する場所さえ判断を間違えている事。
>>118 C ではよく使うテクニックだけど、C++ でこれをやるのはアホ。
あと、118の構造体の定義は破綻してると思うが。
>>135 要素数 0 配列って、どう考えても末尾に 1 つだけだよな…
自己レス。 すまん、アホとまでは言い切れないな。可変長のパケットデータなんかを扱う ときはああいう構造体はたしかに便利だ。 ただヘッダー部とデータが連続している必要がないところでは、ヘッダー部に データへのポインタを持たせて、コンストラクタで new してやるのが普通だろう。
139 :
デフォルトの名無しさん :03/01/30 20:11
文字列を引き数で受け取るメソッドがあります。 引き数の型にはconst char*型を指定するのが良いのかと思いますが、 このプログラムの中ではstd::stringばっかり使われており、 受け取った側でもstd::stringにして使いたいと思っています。 それなら最初からconst std::string&とかを受け取るようにしても良いのでしょうか。 オシエテよ!
戻り値をstd::stringにすることと、引数をstd::string const&にすることは別問題だと思うが。 まぁどちらにせよstd::stringを使うのがC++としては普通だわな。 戻り値のstd::stringはオーバーヘッドが大きいから気を付けな。
あぁ、すまん。 受け取った側ってのはそのメソッドのことか、 じゃぁ何も考えずにstd::string const&でいいんでない? 呼び出し元もstd::stringを使ってるならオーバーヘッドはないし。
142 :
デフォルトの名無しさん :03/01/30 22:04
>>141 どうもです。やっぱりそれでイイんですか。
MFCとかだとconst CString&じゃなくてLPCTSTRを受け取るやつばっかりですよね。
だから何か意味があるのかと思ってたんですが。あれって何でですかね。
>>142 MFC だと、たいてい const CString& 取る関数も定義されてるけど。
たとえば…
CSize GetTextExtent(const CString& str) const;
int DrawText(const CString& str, LPRECT lpRect, UINT nFormat);
>>142 どうだっけな・・・
MFC の CString は内部で参照カウンタを使うことでインスタンス生成時のオーバーヘッドを軽減していたと思うから、CString const& で受け取ってもあんまり代わらないんじゃなかったかと思うけど。
まぁ忘れた。もしかしたら↓と同じ理由かも。
std::string の場合、
char const* -> std::string の変換はかなり重い。
逆は大抵最適化で消滅するほど軽い。
だから引数を std::string const& で受け取ると。
Method( "text" );
のように呼び出すたびにかなりのタイムロスを引き起こす。
char const* で受け取っていれば。
Method( some_string.c_str() );
としてもほとんどロスはない。
145 :
デフォルトの名無しさん :03/01/30 22:29
>>143 そうだったんですか
じゃあMFC使ってコード書くときにconst std::string&を受け取るメソッドばっかり作っても笑われないすかね
CStringと両方作るべきですか どうなんでしょう
146 :
デフォルトの名無しさん :03/01/30 22:36
>>144 レスどうもです。
>char const* で受け取っていれば。
>Method( some_string.c_str() );
>としてもほとんどロスはない。
ええ、僕もそう思ったんです。けど、Method()の中でまたstd::stringにして使うんです。
それなら全部const std::string&で統一して、const char*を全廃しようかと思う訳です。
#でもMFC使ってアプリ組むならconst CString&で統一ってのもアリかと思うんですが、これはマズイですか。
>>146 MFC使うならCStringで統一した方が効率的。
MFC用だと割り切ってるのに悩む必要があるのかと小一時間
149 :
デフォルトの名無しさん :03/01/30 22:52
そんな事言ったってなるべく標準のものが使いたいじゃないですか気分的に。 例えばファイル名を受け取って画像を読むような関数ならstd::string使いたいですよ。 何か別のMFC使わないアプリ(もしかしたらMac用とか)作るときに再利用するかもしれないですし。 そういう時のためにMFCのCStringとかCListとかCMapとかそういったモノで汚染されたコードは 作りたくないです!!
>>149 それを言うならCStringとstd::stringが混在してるコードの方がよっぽど作りたくないが・・・。
151 :
デフォルトの名無しさん :03/01/30 22:59
>>149 自分でCString型つくっときゃ済む話しだろ。
ペアで使うようにすりゃいいじゃん。
152 :
デフォルトの名無しさん :03/01/30 23:10
>>150 ホンダラどないせぇっちゅうんじゃゴラアアアア!
ライブラリとして切り離せそうなクラスはstd::stringで統一/MFCに近い部分はCStringにするとかエエと思うんですが。
>>151 それはCStringに相当するものを自分で作れと言うことですか
ちょっとよくわからないんdすが
153 :
デフォルトの名無しさん :03/01/30 23:12
「かもしれない」はムダの元。
>>152 逆切れは勘弁してくれ。
MFC使ってアプリ組むならっつーからCString使えっつってるだけじゃんよ。
そのライブラリが一番近い環境に合わせればいいじゃん。
画像を読み込む時にWin32APIを使うならLPCTSTRを使えば良いし、
CBitmapを使うんならCStringを使えば良いし、
STLを使うんならstd::stringを使えば良いし、
全部自前でやるんならchar const*を使えば良いだけの話だろ。
>>149 > そんな事言ったってなるべく標準のものが使いたいじゃないですか気分的に。
そもそも MFC 使ってる時点で「標準」に拘る意味はない。本気でマルチプラットホーム
対応にするなら Mozilla のように MFC 捨て捨てで、もっと下のレイヤーから作り込ま
ないと。
157 :
デフォルトの名無しさん :03/01/30 23:20
>>156 下の階層から作ると依存性が高くなると思うが。
158 :
デフォルトの名無しさん :03/01/30 23:31
>>153 それは一番よくないと思います!STLの本の冒頭に「貴方は既に他人が作ったコードを自分で作り直して云々、車輪の再発明云々」
ってかいてありましたよ
>>154 イヤッハハ、まあそうおっしゃらずに・・・
でも画像読み込み関数なんて絶対MFCと分離したいと思いませんか
>>155 >MFC使ってアプリ組むならっつーからCString使えっつってるだけじゃんよ。
たしかにそんな気もします。MFC使ってるんだからMFCの流儀にあわせてコーディングする。
これはコレで正しいと思います。MFCがCString用意してるのに無理してstd::stringを
使うというのもヘンかもしれないですね
>>156 それはどうなんでしょうか。。。確かに幸せな世界が来るかも知れません。。
でも凄いマイワールド展開しまくりな上に、凄い手間がかかりそうです。そこまではできないので、
出来る範囲で汎用的なコードを書きたいのです
158は低脳を装った煽りか。
漏れは、LPCTSTRを見ると、ユニコードでなんか絶対ビルドしないと分かってるのに、 char *を渡すのを躊躇ってしまう。同様にしてstd::stringも。 で結局、TCHARかCString・・・
>>160 #ifdef _UNICODE で std::string, std::wstring 切り替えれば? 俺は WTL::CString
使うけど。
俺はマルチバイトの処理が面倒なので内部はみんなstd::wstringだ、 そしてVC++付属のSTLのバグに悩まされたり、STLPortのコンパイルオプションの違いに翻弄されたりするんだ。 それでも何も考えずに++itrで次の文字に移れるのはめちゃくちゃ幸せだ・・・
class CFileData{ public: CFileData(char *filePath); virtual ~CFileData(); protected: BYTE *m_pBuff; : : こういうクラスを作っています。コンストラクタでデータファイルを開き、 m_pBuffに格納する仕組みです。 そこで質問なのですが、コンストラクタでデータの読み込みに失敗した場合、 失敗したかどうかはどうやって判定すればいいのでしょうか? 後で、bool IsSuccess()みたいな関数を呼んでやら無いといけないでしょうか? それとも、コンストラクタでデータを読むという仕様自体が間違っているでしょうか? アドバイスください。
>俺はマルチバイトの処理が面倒なので内部はみんなstd::wstringだ、 お前は贅沢だ、贅沢は許さん
>>163 例外を飛ばしたり operator bool を定義する
>>163 素直に
class CFileData{
public:
CFileData();
virtual ~CFileData();
bool Read(char *filePath);
とでもしておけば?
168 :
デフォルトの名無しさん :03/01/31 00:30
C++でCSV形式のファイル読み込むのに なにかスマートでいい方法ないですかね stringにいれてsubstr()でとっていくとか istreamのget()かgetline()でdelimiterを’,’にして よんでいくとか方法はいろいろあるんですけど なかなかうまい方法みつからなくて
169 :
デフォルトの名無しさん :03/01/31 00:32
Windowsに設定されている、DNSサーバアドレスを取得するにはどうすればよいのでしょうか? やはりWinsockを使用するのでしょうか?
172 :
デフォルトの名無しさん :03/01/31 00:57
namespace X { enum { E = 1 }; } struct X { enum { E = 2 }; }; int f(){ return X::E; } 「あいまいです」とか言われそうなもんなんですが、 エラーも警告もなんにもでないんです。 同じ名前の名前空間とクラスが :: で指定されたとき、 どのように振舞うような仕様なのでしょうか? ちなみに、gcc3.2 では、 f()==2 になります。
>>172 BCC 5.5.1 では
エラー E2238 TestCon.cpp 6: 'X' の宣言が複数見つかった
>>173 ありがとうございます。
MSVCでも試してみたら、エラーになりました。
gccがバグってんのかな?
C だと struct って独自の名前空間を持ってたけど、C++ だとどうなんだろ。 キーワード struct が省略可能ってことは、やっぱり普通のグローバルになる のかな。 だとすれば gcc は間違ってると思うけど・・・規格博士降臨キボンヌ。
3.3 -4 a namespace name or a class template name must be unique int its declarative region. 3.3.7 A class name or enumeration name can be hidden by the name of an object, function, or enumerator declared in the scape. 7.3.2 -4 A namespace-name 〜 not 〜 same declaretive region. つまり、クラス名と列挙名はオブジェクトや関数に隠されるけど、ネームスペース名と テンプレートクラス名は、宣言空間でユニークじゃなくちゃいけないってか。 gccの負け?
じゃあ、こんなことも可能なのか・・・ class A{}A,B; //OK. class C{}; C C; //OK. C D; //Error.
178 :
デフォルトの名無しさん :03/01/31 08:00
newで確保した領域は mainが終了すると勝手に解放されますか?
>>178 勝手には解放されません。deleteすれ。
new[]で確保したものはdelete[]で。
それがいやなら、スマートポインタでも使ってくれ。
環境依存の話はよそでやって
>>178 まともなOSだったら解放される。しかし、delete しないということは
デストラクタも呼ばないわけ? それだとまずいことが多々おきそう。
>>180 これくらいなら環境依存というほどでもないっしょ。
mainが終わって、グローバルに置いたオブジェクトのデストラクタが 呼ばれた後は、何が起こるか未定義だな。
183 :
デフォルトの名無しさん :03/01/31 21:12
本当にしょうも無い質問でごめん。 C++でJavaみたいにWebアプリケーションの開発って出来ます? 仮にできるとしたら、Javaに勝っていますか? 本当にどうしようもない質問でごめん。。。
185 :
デフォルトの名無しさん :03/01/31 21:43
>>183 「Javaみたいに」とはどんな特徴のことだ?
C++でできるか否かはそれに因る
>>183 CGIをWebアプリと呼べるのならできる。
もしくは、JavaをC++で作ってやるとか
JavaのコードをC++で生成するとか(以下略)。
>勝っていますか?
しょうもないので却下。
188 :
デフォルトの名無しさん :03/01/31 22:50
ファイル間の依存関係を軽減するために class CData; class CDocument { CData *m_data; ・・・ こういう風にしてCDocumentのコンストラクタでm_data = new CData;やってます。 でもこれだとdelete忘れたり色々鬱陶しいので、できることなら #include "CData.h" class CDocument { CData m_data; ・・・ こんな風にしたいと思っています。何かいい手はないでしょうか。
190 :
デフォルトの名無しさん :03/01/31 23:04
>>189 ポインタになってるのがそもそも嫌なんです。deleteできちゃうっていう状況が嫌です。
でも依存関係は減らしたいのです。
例えば標準のstringが気に入らなくて、自分で作ったCMyStringがあるとします。
もうこれはアプリの中にあっちこっちで使われてる上に、今後UNICODEをエンコードしたり、
色々な機能を追加させる予定だとします。
こういう場合どうしたらいいですか。
>>190 そんなあなたにconst auto_ptr
192 :
デフォルトの名無しさん :03/01/31 23:09
string如きにコンストラクタでいちいちnewしたりするのもめんどくさいです
>>190 なにを聞きたいかがまったく分からん。
CMyString(char *str) {
this->str = charToUnicode(str);
}
って書いてchar型で渡されたらUnicodeに変換して、内部でUnicodeで管理すればいーじゃん。
外部からはどっちで渡されてもOKにしといて。
つーか、自分でfacet作るなりどっかから持ってくるなりすれば標準ライブラリ使って Charsetの変換とかもできるようになってるんだけどな、C++は。
195 :
デフォルトの名無しさん :03/01/31 23:20
依存関係を減らすのにpImplイディオムが有名だ、 しかしコンストラクタでnewしたくないめんどくさがり屋にはお勧めできない。 さらに依存関係をほとんど無くすのにJavaが有名だ、 しかしこちらは全てのオブジェクトをnewする必要があるのでますますお勧めできない。 依存関係とめんどくささはトレードオフの関係にあるようだ。
198 :
デフォルトの名無しさん :03/01/31 23:24
>>196 ていうか、そういうのって一般的なんですか。あんまりそういうのやってるって聞いたこと無いんですが。
メンバのオブジェクトというオブジェクトを全部scoped_ptrとかで持ったりしたら、
人に見せたときに「うわーなんだこのプログラム!バカがいるYO!」とか言われないですか。
199 :
デフォルトの名無しさん :03/01/31 23:30
>>197 >依存関係を減らすのにpImplイディオムが有名だ、
それは名前から察するにEffective-C++でも紹介されていた、実装クラスとインターフェースクラスを
分離するっていうテクですか。
>しかしコンストラクタでnewしたくないめんどくさがり屋にはお勧めできない。
それもそうですけど、これでもインターフェースクラスに変更があったら再コンパイルですよね。。。
それならauto_ptr使うほうがまだ良い気がします。ファイルの増殖を防げますし。
>さらに依存関係をほとんど無くすのにJavaが有名だ、
ああ、なんかありますよね、、、ゲーム作りたいのでJAVAだと速度が心配です。
>依存関係とめんどくささはトレードオフの関係にあるようだ。
了解しますた。
>>198 scoped_ptrのソースを持ってきて、そのコンストラクタを書き換えて自動的にnewするようにすれば君のやりたい事が実現できる。
毎回newを書かなくても、その独自のscoped_ptrを使えば自動的にインスタンスが作られる。
それを馬鹿だと言うやつには経緯を説明して、それでも理解できなければそいつがバカだと笑ってやるがいいよ。
>>198 ふつーはメンバのオブジェクトを個々に scoped_ptr で持たずに pimpl イディオム
使うけどな。Effective C++ じゃなくて Exceptional C++ ね。
> それもそうですけど、これでもインターフェースクラスに変更があったら再コンパイルですよね。。。
それは仕方ない。
ただ、影響を最小限に留める方法としては、
1. 純粋仮想関数だけからなるインターフェースクラスを分離
2. 実装側は、そのインターフェースを継承して vtbl を埋める
3. クライアントはインターフェースだけを見る
って手がある。
インターフェースを拡張する場合、既存のインターフェースには手を加えず、別のイン
ターフェースを定義して、それを実装側に継承させる。(インターフェースの多重継承
というヤツやね。COM でも良く使われてる)
202 :
デフォルトの名無しさん :03/01/31 23:39
>>200 うわっ、本当だ、画期的だ。それってスゴくないですか!!??
心配なんですが、scoped_ptrみたいなクラスのテンプレート引き数って、includeしてないやつでもOKですよね!?
うーむ。これは新しい。。。演算子オーバーロードしてポインタに見えなくするとか、色々出来そうですね
203 :
デフォルトの名無しさん :03/01/31 23:52
>>201 >インターフェースを拡張する場合、既存のインターフェースには手を加えず、別のイン
>ターフェースを定義して、それを実装側に継承させる。
ははぁ、、、なるほど、、、色んなワザがあるんですねえ。こんな感じでいいんですか。
class CImpClass : public CInterfaceVer1, public CInterfaceVer2 ...
{
};
うーむ
204 :
デフォルトの名無しさん :03/02/01 00:07
>>200 やってみましたけど、テンプレートクラスの中で目当てのオブジェクトをnewできないじゃないですか!
作りたいクラスの名前しか分からないからnew出来ない、そりゃそうか、、、
>>204 template< typename T > class ptr_container
{
public:
ptr_container(void) : m_ptr( new T() ){}
~ptr_container(void){ delete m_ptr; }
private:
T* m_ptr;
};
ってできないっけ?
206 :
デフォルトの名無しさん :03/02/01 00:20
>>205 こういうのは無理みたいです
#include "ptr_container.h"
class CData;
class CDocument {
ptr_container<CData> m_data;
};
コンパイルエラーになります。CData.hをインクルードしたらいけますけど、
それだと最初の目的が達成できないです。
>>206 俺はできたよ。
普通にポインタ使うときと同じように、しかし初期化する必要なく。
CDocumentの実装ファイルには当然CData.hをインクルードするよ。
>>205 無理。new する時点で、そのクラスの定義が見えないと NG なんで。
別のクラスにインスタンス構築を押しつけるって手はある。
template <calss T, class TFactory>
class ptr_container
{
public:
ptr_container() : m_ptr(TFactory::Create());
~ptr_container() : { delete m_ptr; }
private:
T* m_ptr;
};
struct FooFactory
{
static Foo* Create();
};
>>207 > CDocumentの実装ファイルには当然CData.hをインクルードするよ。
……スレの流れを読め。
>>209 俺はスレの流れを正しく把握してるって
188を読むからに206はCDocumentの実装ファイルにCData.hをインクルードする事はかまわないと言っている。
211 :
デフォルトの名無しさん :03/02/01 00:40
予期しない 'class' 'one_image' です。 と書かれて一つのメンバ変数が指されるんですけど どういうこと?
213 :
デフォルトの名無しさん :03/02/01 00:45
>>207 ごめんなさい、いけました。includeする順番間違ってました。
これマジ凄いですよ、みんな使いましょうよ。
今時これくらいならオーバヘッドだってあんまり気にならないでしょう。
ところでちょっと謎な現象なんですが、
CDocument.cppの中でCData.hを正しい順番でインクルードしないとエラーになるというのは分かります。
で、ためしにCHoge.cppってのを作って、その中ならCDocument.h単体でインクルードしてもエラーにならないのは
どういう事なんでしょうか。なんか勘違いしてますか僕
>>210 はい、CDocument.cppの中でCData.hをインクルードするのはOKです。
でないとCDataを触れないですからね。
いままでJAVAの勉強していてc++は文法理解した程度です。 c++でXMLを扱おうとしてxerces-cを使っているのですが、 サンプルをコンパイル時に fatal error C1083: インクルード ファイルがオープンできません。'xercesc/util/PlatformUtils.hpp': No such file or directory とエラーが発生しました。 設定的な問題だと思うのですがどう対処すればいいのでしょうか?
みなさんありがとうございました、色々やってみましたがいけそうです。 え〜と混乱してしまいましたけど、 CDocument.cppでCDocument.hをインクルードする時にCData.hもインクルードする必要があるのは、 CDocument.cpp内にCDocumentのコンストラクタの実装があるから。 CHoge.cppでCDocument.hを単体でインクルードしても、CDataを触ったりしない限りCData.hをインクルードしなくてもコンパイルとおる。 という理解で良いでしょうか。 ていうかこれって凄いアイディアじゃないですか。STLに入れて貰えそうじゃないですか
>>215 おけ。
でもデフォルトコンストラクタが無いと動かないので208のように使うのが一般的かと。
しかしコンストラクタを省略するのはものぐさなのでC++向きじゃない気も。
LokiのSmartPtrにはそういうポリシーを受け入れる用意があるけど、各自勝手に実装しろってスタンスだし。
フーン、いいね、これ。デフォルトコンストラクタが無いとダメっていう制限あるけど、後でInit()呼んでやったら良い訳だし。 ptr_containerが「.」をm_ptr->に、「&」をm_ptrに置き換えてくれたりしたら最高なんだけど、そういうのは無理なのかね。
C++ の仕様上 operator. はオーバーロードできません。
220 :
デフォルトの名無しさん :03/02/01 09:14
'two_image::two_image' : オーバーロードされたメンバ関数が '<Unknown>' にありません。 とかいうエラーメッセージが出るのですけど、 どういうことなんでしょう?
221 :
デフォルトの名無しさん :03/02/01 09:17
> デフォルトコンストラクタが無いと動かない scoped_ptr 的に使うならptr_container自体に関するコンストラクタとかは 全部不要だろうから、 template< typename T > class ptr_container { public: ptr_container() : m_ptr( new T() ){} template<typename T1> ptr_container(const T1& t1) : m_ptr( new T(t1) ){} template<typename T1, typename T2> ptr_container(const T1& t1, const T2& t2) : m_ptr( new T(t1,t2) ){} template<typename T1, typename T2, typename T3> ptr_container(const T1& t1, const T2& t2, const T3& t3) : m_ptr( new T(t1,t2,t3) ){} ... と10個くらい並べとくとかいう手がある。constじゃない参照をとる コンストラクタに対応しようとするといささか美しくない方法が必要だが。
223 :
デフォルトの名無しさん :03/02/01 10:51
派生先クラスのメンバ変数に派生元のクラスのオブジェクトを含むときは 継承しないただのコンポジションと違うところありますか? 派生クラスのメンバオブジェクトのコンストラクタの仕方とか。
>>234 class class0{
public:
int val0;
}
// class0のコンストラクタ
class0::class0(int x){
val0 = x;
}
class class1:public class0{
// メンバオブジェクト
public:
class0 obj0_0,obj0_1;
int val1;
f1();
}
としたときclass1のコンストラクタは
class1::class1(int x1, int x0_0, int x0_1)
:obj0_0(x0_0), obj0_1(x_1){
val1 = x1;
}
とう具合で良いでしょうか?
>>222 へえー。それでもコンパイル通るんだね。
>コンストラクタに対応しようとするといささか美しくない方法が必要だが。
ドーやんの、オスィエテよ!
このやり方ってオーバーヘッドが若干ある&初期化が独特って事以外デメリット無いよね?
227 :
デフォルトの名無しさん :03/02/01 11:59
継承クラスのメンバ関数定義と継承元のクラスのメンバ関数の定義を別の ファイルにするときのリンクの仕方は何か特別のことする必要あるでしょうか?
継承先クラスの関数で継承元の関数を使っていて、 たぶんそのリンクができてないからエラーが出てるのだと思いますが、 どうすれば良いでしょう?
>>225 class1のコンストラクタで、継承元のclass0の初期化子が呼ばれてないから
それだとエラーになるんちゃうか。
230 :
デフォルトの名無しさん :03/02/01 13:08
VB厨なのだが、、、業務ではC++は使ったことが無い。 しかし趣味でC++を勉強していて、とりあえず 「新C++言語入門<ビギナー編>林晴比古 著」 の内容は一通り理解しているつもり。 こんな俺は、C++を使ってのソフトウェア開発で通用しますか?
通用しません。アセンブラをやってからまた来てください。
初心者の中の初心者が読むその本に、業界の中で何の価値があるのだろう。 せめて、ビギナー編じゃないほうの、上下巻のほうを読んだと言おうや。
ということは、会社で暇を見つけてはその本で勉強していた俺は 陰で馬鹿にされている可能性が非常に高いとも言えますね。。。
>>233 そこからステップアップしてくつもりなら何も問題ないのでは。
>>230 C++Primer読んでたけどこれなかなかよかったよ。
下らない本を何冊も買うより、これ一冊で
基礎をちゃんとやるのがいいかも。
>>235 内容はいいけど、でかすぎて重すぎて読みづらい(涙
げ、、、VBもC++もVC++も林さんで揃えてしまった。。。 スレ違いスマソ。
239 :
次回メルチェは23時 :03/02/01 14:23
エッチ な粗品ファイルをあげるから、おしえてください。 回答と粗品の請求は↓へお願い。 l*ol*im*an*10@ho*tm*ai*l.*c*om forループで重い処理をしていても、WndProc()が 機能するような方法をおしえてください。 次のソースで描画の処理はできましたが、例えば、 WM_MOVE はできていません。 LRESULT CALLBACK WndProc(の、 switch (msg) { case WM_RBUTTONDOWN: func(hWnd);で↓が起動
240 :
次回メルチェは23時 :03/02/01 14:23
void func(HWND hWnd) { MSG msg; char str[50]; for (int i = 0; i <= 100; i++) { for (int j = 0; j <= 100; j++) { wsprintf(str, "%3d,%3d", i, j); SetWindowText(hWnd, str); while (PeekMessage(&msg, hWnd, WM_MOVE, WM_MOVE, PM_REMOVE)) { SendMessage(hWnd, WM_MOVE, msg.wParam, msg.lParam);//ここ失敗 } if (PeekMessage(&msg, hWnd, WM_PAINT, WM_PAINT, PM_REMOVE)) { SendMessage(hWnd, WM_PAINT, msg.wParam, msg.lParam);//これ成功 } } } }
空のWIN32アプリを作ってダイアログを表示させたは良いんですが 他のDOS(みたいなの)の画面上でチャットするソースとくっ付けたら ダイアログが表示されなくなりました。ありそうな原因を教えてください。 お願いします
くっつけるなよ(w
>>242 そんな・・チャットする方の動作はしてるんですが、
何でダイアログが表示されなくなったのか分からない(泣
ネットも そんな馬鹿なQ&Aないし。。
244 :
デフォルトの名無しさん :03/02/01 16:21
newで確保した領域はmain関数が終わって プログラムが終了してもdeleteしないと残っているんでしょうか?
245 :
デフォルトの名無しさん :03/02/01 16:23
>>244 staticで宣言してたら残る。
自動変数なら消滅。
基本です〜。
>>244 UNIXではプロセスごとに確保したスタック、ヒープは
プロセスが終了した時点ですべて開放されます。
Windowsは知りません。
すまん。 mainが終わればstaticでも消滅ですた。。。
大抵の場合領域は開放されるがコンストラクタは呼ばれないので悲惨な事になりかねん。
スマン デストラクタ
atexit()に念のため登録しておくとかw
>>247 正確には main が終わった後、プログラムの実装終了前、だな。
254 :
デフォルトの名無しさん :03/02/01 17:50
質問です。 2^0=1 2^1=2 2^2=4 2^3=8 2^4=16 ... となるように記述するにはどうすれば宜しいでしょうか? 『^』だと変な結果になるもので… 例: int k; for(i=0;i<5;i++){ k=2^i; cout<<k<<","; } 結果: 2,3,0,1,6,
255 :
デフォルトの名無しさん :03/02/01 17:53
>>254 超既出質問
cmathインクルードしてpow
256 :
デフォルトの名無しさん :03/02/01 17:54
ちなみに^はビットごとの排他的論理和
257 :
デフォルトの名無しさん :03/02/01 18:04
>>252 >プログラムの実装終了前
すまん・・・もう少し詳しくきぼん
>>257 実装→実行の typo と思われ
1 プログラム実行開始
2 非 local static 変数のコンストラクト
3 main 実行開始
4 …
5 main 実行終了
6 非 local static 変数のデストラクト
7 プログラム実行終了
259 :
デフォルトの名無しさん :03/02/01 18:16
>>248 たいていの場合はmain終わった後にデストラクタが呼ばれるのかと思ってますた。
呼ばれますがな・・・ 呼ばれる順番によっては悲惨なことに・・・
>>261 いや new で確保したオブジェクトに関しては、delete しないとデストラクタ呼ばれんよ。
あ、グローバルなオブジェクトの話じゃなかったのか スマソ
istreamの話なんですが、STLスレじゃなくてココのほうがいいのかな? 日本語文字コード変換などといったようなことをしてくれるostreamフィルタクラスを 作るにはbasic_streambufを継承させたクラスが必要なんでしょうか。 basic_streambufクラスは大きいので矛盾なく子クラスをつくるのは大変なんですが。 javaではかなり簡単に入出力フィルタクラスを作れるんですが。
(-r) フーン
>>267 おお、このフィルタクラスは便利そう。参考になりますな。
269 :
デフォルトの名無しさん :03/02/01 23:59
とある本のサンプルなんだけど。 string from, to; ... ifstream is( from.c_str() ); istream_iterator<string> ii( is ); istream_iterator<string> eos; vector<string> b(ii, eos); ← ここでエラー メッセージは 「この変換を実行可能な ユーザー定義変換演算子がないか、 または演算子を呼び出せません」 なにが悪いのかさっぱり。 だれかー。
>>269 コンパイラ何?
BCC5.6ではオッケーよ。
恥ずかしながら vc6 sp5
>>269 なにが悪いかといえばVC++のSTL関係の実装が標準に準拠しきれていない点。
ちなみにSTLportつかえば通った気がするが。
>>271 VC6はちょっとなあ。
VC.NETでやったら通ったよ。
VC6をバカにするな!
>>272 thanx.
別のSTL使えばOKになるんだろうけども、
そのSTLの何が悪かったのかわからずじまい
になってしまう。
どうしよう...
98年リリースなんだから標準に準拠してなくても仕方ないさ
その標準も98年にリリースされたんじゃなかったっけ
標準がリリースされて数ヶ月で対応できたら、もはや神の領域だろう。
お遊びなら.net Framework SDKのコンパイラを使えばいいよ。 仕事ならVS.net買ってもらえ。
お遊びならMingwでいいじゃないか。
vs.netかぁ。ママ買ってくれるかなぁ。
vc6のvector<string>は適切な コンストラクタを選択できないとこまでは解った。 んで、copy()使って見たらなんとかうまくいった。 //vector<string> b(ii, eos); vector<string> b(100); copy( ii, eos, b.begin() ); サイズ100で初期化はまずいので、 このbへコピーされるサイズをあらかじめ 知るにはどうしたらいいんだろう。。。
std::distance()
おお。取れた。 int i = static_cast<int>(distance( ii, eos )); vector<string> b( i ); copy( ii, eos, b.begin() ); でも、なんか期待通り動かない。。。 なんでだろう。。。
コンソールアプリケーションとSDKによるWindowsアプリケーションとは 何でしょうか?
>>285 スレ違い。
Windows とか Win32API とかすれ立てるまでもないとかその辺り。
VC++上でのことを聞いてるんです。
290 :
デフォルトの名無しさん :03/02/02 08:40
クラスのコンストラクタの定義で one_image::one_image(unsigned char *R, unsigned char *G, unsigned char *B, int size_x, int size_y, int b_x, int b_y) { HSize = size_x; VSize = size_y; } としたら、 error C2144: 構文エラー : ')' が型 'unsigned char' の前に必要です。 error C2059: 構文エラー : ')' 構文エラー : ';' が '{' の前に必要です。 とかエラーが出て、おまけに error C2065: 'size_x' : 定義されていない識別子です。 と、定義されてないことになっちゃいます。 どういうことか、さっぱり分かりません。 どうしたらいいでしょう?
Microsoft Developer Stdioを使ってるのですが、 oneimage::one_image(); のオーバーロードと関係があるんでしょうか?
>>290 クラス定義の最後のカンマを忘れてそうな気がする。
class one_image {
// ...
};←これね。
違ってたらスマソ
>>292 ありがとうございます。解決しました。
そんな事にもきずかないなんて僕は本当に馬鹿でした。
くだらない質問であなたの大切な時間を無駄にして本当に済みませんでした。
僕のようなゴミの質問を真剣に考えてくださって心から感謝します。
笑った笑った。
295 :
デフォルトの名無しさん :03/02/02 10:43
日本人の50人に1人は自殺で死ぬという罠。 珍しくもなんともない。
次のスレをたてるときは、 VC++でWindowsプログラミングをしている人はまずVC++スレに行きましょう。 おそらくあなたの質問はC++の問題ではなくVC++/Windows特有の問題です。 とか書いておきたいね。
299 :
デフォルトの名無しさん :03/02/02 12:53
-> ↑ こn記号の意味は? 厨房でごめんちゃい。
a->bは(*a).bと同じ
>>299 わからない。
大抵は、
>>300 で合ってると思うが、C++ は演算子を定義できるから、他の意味に定義されているかもしれない。
302 :
デフォルトの名無しさん :03/02/02 16:09
:-> :-P
<C++> ::= <色々>|<最高>|幼女
304 :
デフォルトの名無しさん :03/02/02 16:23
スマートポインタには必須だと思うが・・・
307 :
デフォルトの名無しさん :03/02/02 17:58
C++初心者です。 ポインタを勉強して理解をしたつもりでしたが、次に「クラス」 を勉強していてポインタと言うものを実は理解していないのでは?という 不安にかられています。 と言いますのも、ポインタでは変数の「アドレス」を変えたり出来たのですが、 これはイメージ的に掴む事が出来ました。変数の値を置いてある番地のことが「アドレス」 であり、ポインタとはそのアドレスを保有する事のできる「変数」と。 ところがクラスのポインタというものが出てきて面食らっています。 あるクラスの置かれている番地=そのクラスのアドレスというのがピントきません。 変数に比べてクラスは色んな情報を持っているため・・・。 変数、クラスもひっくるめて、全ての「オブジェクト」にアドレスがあるのでしょうか? よろしかったら、「アドレス」というものを初心者にもわかるように説明をお願いしたいのですが。 よろしくお願いします。
charのポインタが判るなら、charの配列のポインタも判るよな、 配列のポインタが判るなら構造体のポインタもわかるだろう。 なら構造体のポインタが判ればクラスのポインタもわかるってもんだ。
>>307 C++ になったら、あまりアドレスには拘らずに、オブジェクトを指すものだと
思っておいた方が。
(特に多重継承や仮想継承が絡むと、内部でオフセット調整とか入るし、
仮想関数へのポインタとかになるとアドレスそのものではないし)
> 変数、クラスもひっくるめて、全ての「オブジェクト」にアドレスがあるのでしょうか?
「クラス」ではなく「インスタンス」あるいは「オブジェクト」な。クラスといったら構造体や
int と同様、型のこと。
アドレスがあるかって話だけど、原則として Yes。例外は register 指定した変数と
this ポインタ、あと仮想関数へのポインタかな。詳しく知りたければ、書籍
Inside the C++ Object Model を読むと良い。
310 :
デフォルトの名無しさん :03/02/02 18:41
charの列へのポインタの指す文字列をcharの配列へ 列全体をコピーする関数にはどんなのがあるでしょうか? char dist[32]; char *src; strcpy(dist,src);//文字列のコピー。 ってのはありでしょうか 御教授お願いします
311 :
デフォルトの名無しさん :03/02/02 19:02
質問です。 整数型の変数 m, n の値を受けて、動的に二次元配列を作りたいのですが、 int **h; for(i=0;i<m;i++){ h[i] = new int[n] } とかすると、強制終了してしまいます。 どのようにすれば実現できるでしょうか?
int *h[m];
316 :
デフォルトの名無しさん :03/02/02 19:26
>314 試しましたが、mは定数ではないのでコンパイルエラーとなります。 h = new int*[m]; for(i=0;i<m;i++){ h[i] = new int[n]; } これもダメでした…
vector< vector<int> > h;
std::vector< std::vector<int> > h(n, std::vector<int>(m) );
constにすれってことじゃ
いや、mが定数じゃなくてエラーだって言うから
int **h; h=(int **)malloc(m*sizeof(int)); for(int i=0;i<m;i++){ h[i]=(int *)malloc(n*sizeof(int)); }
323 :
デフォルトの名無しさん :03/02/02 21:21
>322 Thanxd >h=(int **)malloc(m*sizeof(int)); がなんとなく気持ち悪いけど、いけました! new使う方法は無理なんでしょうか?
325 :
デフォルトの名無しさん :03/02/02 21:27
>324 まぁその通りなんですが、 変な挙動を示した事があるのであんまり初心者向きではないかと。
変な挙動?
キーボードから漢字と半角英文字の混ざった文字列(例えば"abc亜意宇")を読み込んで そのn文字目を指したいときどのようにすればいいのでしょうか…? (wchar.hをインクルード) wchar_t s[256]; gets(s); として"abc亜意宇"をキーボードから入力して '亜'の一文字を出力するために putwchar(s[3]); としてみたんですがうまくいかなくて・・・
328 :
デフォルトの名無しさん :03/02/02 21:37
>326 using namespace std; ってコードを入れると、 それまで動いていた特定のコードが動かなくなるという現象です。 VisualC++6.0で起きていました。
for(int i=0;i<m;i++){ free(h[i]); } free(h);
>>323 >>h=(int **)malloc(m*sizeof(int));
>がなんとなく気持ち悪いけど、
どのへんが?
>>328 using namespace しなきゃいいのでは?
>330 sizeof(int)のところ。 >331 そのままでvector使えるのですか?
sizeof(int*) ...
>>332 std::vectorってネームスペースを指定すれば使えるジャン。
>333 あ、これコンパイルできたのですか… >334 不勉強なもので… 参考文献スレのお世話になってきます…
>.335 そりゃお前の環境がたまたまsizeof(int) == sizeof(int*)だっただけだ。 もっとも違っててもコンパイルエラーにはならんで実行時に死ぬだけだが。
以下のコードを実行すると、2回リターンを押さないと終了してくれません。 どうしてでしょうか? int main(int argc, char* argv[]) { std::string s; std::getline(std::cin, s); return 0; }
ネタ?
>>337 あー、VC++6だろ?
STLportにしたら直る税。
テメェら!とっとと教えて下ちい!
>>340 wcinでも使っとけ。ここはC++スレ
>>341 スマソ。C言語ならあっしに聞けスレがあったのね・・・
ちなみに340は漏れじゃないから。。
scanf("%s end", str) を istream をつかって書くとどうなるんでしょうか。 cin >> str >> "end" みたいな感じに簡単には書けないんですか?
>343 ofstream str(filename); str<<"end"; とかで(・総て・)イイ!!んじゃねーの?
>>343 オイラはダミー一個作っといて
cin >> str >> dummy;
みたいにしてるけど・・・なんかもっといい案無いのかなぁとも思う。
同感
sscanf() とかラップして scanf_stream 作るべし
マニピュレーター自作して cin >> str >> check("end") // "end"じゃなきゃfailbitたてる ってのはどう? 引数付きのマニピュレーターってどうやって作るのかしらないけど。
string を内包する class でも書けば ok かと
>>349 それってstringコピーする分、無駄が出ると思うんだが。
じゃあ char* でいい あとは istream& operator>>(istream&, T) とかで
質問です。 friend 関数に テンプレート関数は使えないのですか? クラス自体はテンプレートではないです。
>>352 使えるよ。クラスでテンプレート宣言しておけば。
template <typename T>
friend ostream& operator << <>(ostream& str, T t);
みたいな感じで。gcc3.2.1では通るがBCC5.5.1ではだめだった。
354 :
デフォルトの名無しさん :03/02/03 20:53
struct List { List *m_next; List *m_prev; CString m_text; public: List() {}; List(const CString&text) : m_text(text) {}; void link(List *next) { m_next = next; next->m_prev = this; }; }; 双方向リストの構造体なんですが、 List() {}; List(const CString&text) : m_text(text) {}; の部分が何をやってるか分かりません。 詳しく解説してもらえないでしょうか? List() {};は、コンストラクタで、各メンバを0かNULLで初期化してると思うのですが。 List(const CString&text) : m_text(text) {};の「&」とか「:」が何を意味してるのかも よく分かりません・・・。
>List() {};は、コンストラクタで、各メンバを0かNULLで初期化してると思うのですが。 いや、何も初期化してないんだと思うんだが
お前の目はfusianasanか!
357 :
デフォルトの名無しさん :03/02/03 20:59
質問でつ。 とあるstatic変数をもったクラスを、いくつかのオブジェクトが継承してるとしますね。 こういう場合・・・ 1:このstatic変数は1個しかなくて、継承したオブジェクト達はこの1個しかないstatic変数を 参照する。 2:このstatic変数のコピー的なものが、継承したオブジェクト達にそれぞれ存在して、 どこかのオブジェクトのstatic変数が変更されると、ほかのオブジェクトの同じstatic変数 も変更される。 のどちらですか?
>>354 C++ってここらへんでつまずく人が多いような気が・・・
List(const CString &text) : m_text(text) {} ;
'&'は参照,":"はListのメンバであることの明示。
この行では,Listのメンバm_textをtextに代入している。
>>359 > この行では,Listのメンバm_textをtextに代入している。
逆だ。textをm_textに代入。
代入じゃなくて初期化では。
>>362 コンストラクタと同じシンタックスにしてるところから
考えてやっぱり初期化と呼ぶのが正しいんじゃない?
んじゃ、初期化でいいよ。
>>362 は 359=360 ではありません。
>>354 俺も昔はここでつまずいた。
言語仕様だから慣れるしかないね。
>>365 >
>>362 は 359=360 ではありません。
それはたぶん皆わかってるが、代入と初期化って
全く別物だから、間違えない方がいいぞよ。
CStringのm_textをtextで初期化する っていうのは
CString m_text(text);
こんなふうに メンバ変数を
コンストラクタで初期化する場合には
>>354 みたいな文法を使う。
代入っていうのは
CString m_text; //デフォルトコンストラクタで初期化
m_text = text; //operater=で代入。
っていう流れ。 いっぺん空のオブジェクト作ってからそこに
放り込むので、初期化が途方も無く重たい場合なんかはロスがでると。
漏れはこんな認識だけど、問題あったら教えてー。
>>355 え?そうなんですか?
じゃあ一体これはどんな意味があるんでしょうか?
C++の構造体って、コンストラクタが使えたりしてよく分かりません。
Cしか経験が無いので。
>>359 なるほど、&は参照の&でしたか。
元にしたソースに空白無しでくっついて表記されてたので、気付きませんでした。
「:」はメンバにアクセスするときに使うんですか。
メンバにアクセスするには「.」か「->」だと思ってました。
C++の「:」は継承に使うものだとばかり思ってました。
>>368 > 「:」はメンバにアクセスするときに使うんですか。
それは
コンストラクタで
メンバ変数の初期化 or 明示的に親クラスのコンストラクタを呼び出す
ときだけ。
基本が抜けすぎてるから、とりあえず「プログラミング言語 C++」を買ってきて
読んだ方が良いと思うぞ。
そして、 CString str = "test"; で躓く罠。
構文砂糖だっけ?
373 :
デフォルトの名無しさん :03/02/04 00:13
お尋ねします。 新しく作った構造体をメンバ変数として定義しますよね。 struct kouzoutai aa; というふうに。 それをメンバ関数での引き数として使うことはできるのでしょうか? というのは、メンバ関数内にそのままaaとして書けばいいのですが、 メンバ変数にbbもあってそれもメンバ関数に使いたかったらaaと書いては できないですよね。だから引数として渡すしかないと思いまして・・・
>>373 何を言ってるかサッパリ分からんので、サンプルコードを書いてみてくれ。
構造体が引数として渡せるかどうかってだけか。渡せる。
376 :
デフォルトの名無しさん :03/02/04 00:26
すいません。 まず、メンバ変数として struct kouzoutai aa, bb; と宣言します。 そしてあるメンバ関数の引数として void function(int Val, kouzoutai cc) というようにすることはよくあるのでしょうか aaやbbをfunctionで使いたいのですが、aaやbbはメンバ変数だから 別に引数として使わなくても使うことはできますよね?でもあるときは aa,あるときはbbを使いたいからfunctionに引数として使いたいわけで。 すいません、また意味不明っぽくて
>>376 普通はややこしいから、メンバとパラメータは違う名前にする。
どうしてもやりたければ、aaでパラメータ、this->aaでメンバにアクセスできる。
378 :
デフォルトの名無しさん :03/02/04 00:34
変数、配列、構造体といろいろあるから学びにくい。 構造体だけにしてしまえばいい。
381 :
デフォルトの名無しさん :03/02/04 00:40
標準ライブラリとか関数とか使うときに どのヘッダをいんくるーどすればいいのかって というのはどうやって知るんですか・・・ googleっていうのはなしで・・・・ 教えてたも〜
385 :
デフォルトの名無しさん :03/02/04 00:44
386 :
デフォルトの名無しさん :03/02/04 00:46
>>386 manって・・・・
gccとかじゃなくて、
bcc使ってるまろは
どうしたらいいんでおじゃるか・・・
そもそもどうしてgoogleは無しなのか
>>381 まともなヘルプなら大抵書いてあると思うが。
ヘルプがなければ適当にインクルードしとけばいい。
どれかに当たりがあるだろう。
それが嫌ならインクルードファイルが置いてあるところにいって
検索すればいい。
慣れれば雰囲気で分かるんだけど。
>>390 きっと整数型とかも構造体として扱うんだよ。
値は関数を使って取得して、
その内部構造は言語的に隠蔽されてるんだよ。きっと。
構造体の中身にも変数を使ってはいけないのか。 それは大変だな。
393 :
デフォルトの名無しさん :03/02/04 14:47
//関数の呼び出しで標準変換を禁止する方法はないものなのでしょうか? #include<iostream> struct CStrin { CStrin(char a){//explicitは使いたくない} }; void test( CStrin s ) { std::cout << "test(CS)"; } void test(float a) { std::cout << "test(float)"; } template <typename T> struct A { void operator() (T a){} }; int main() { test('a');//test(float) A<const char>()('a');//関数オブジェクトを使うしか... }
test(CStrin('a'));
void test(char c){}を用意
396 :
デフォルトの名無しさん :03/02/04 16:27
VC++6.0を使っているんですっが、 switch文の中で、宣言して代入ってできないんでしょうか? // エラー UINT j = DT_TABSTOP | 0x00002F00; DrawText(hdc, str, -1, &rect, j); d:\temp\winapitest001\winapitest001.cpp(92) : error C2360: 'j' の初期化が 'case' ラベルによって行われませんでした。 d:\temp\winapitest001\winapitest001.cpp(85) : 'j' の宣言を確認してください。 //これだとOK UINT j; j = DT_TABSTOP | 0x00002F00; DrawText(hdc, str, -1, &rect, j); どうして前者だとエラーになるのでしょう? 文法的には問題なさそうなんですが。
エラーコードぐらい調べろよ コンパイラ エラー C2360 'identifier' の初期化が 'case' ラベルによってスキップされました。 指定された識別子の初期化は switch ステートメント内では行われない場合があります。 初期化を伴う宣言は、閉じたブロック内で行われない限り、スキップすることはできません。 初期化された変数のスコープは、switch ステートメント内の閉じたブロックの中で宣言されていない限り、switch ステートメントの最後まで続きます。 次にこのエラーの例を示します。 void func( void ) { int x; switch ( x ) { case 0 : int i = 1; // エラー, case 1 によってスキップされます { int j = 1; } // OK, 閉じたブロック内で初期化されています case 1 : int k = 1; // OK, 初期化はスキップされません } }
DrawText(hdc, str, -1, &rect, DT_TABSTOP | 0x00002F00);
>>397 どうもです。なるほど、仕様なんですね。
>>3988 もちろん、そうできるのは分かるんですが、デバッグで確認するために
敢えて一旦代入してみました。
400 :
デフォルトの名無しさん :03/02/04 18:56
using namespace の逆って無いの? define に対する undef みたいなの。
ない。 ヘッダーファイルでは std::string s ; のようにして cpp で using namespace 使うのが一般的なのかな
>>400 ないが、一時的に using したいなら anonymous namespace 使うのは手かも。
anonymous namespace ?
名無しさんのことだよ
>>393 template<typename T> struct nise {
T t;
nise(T t) : t(t) {}
operator T() const { return t; }
};
//------------------------------------------
void test(nise<float> a)
{
std::cout << "test(float)";
}
とすると標準変換よりは優先度が下がるので、
test(CStrin) と test(float) が曖昧です、くらいにはなる。
unnamedだろ。
>>402 VC++6 で通っちゃうんですけど・・・。
#include <iostream>
namespace
{
using std::cout;
using std::endl;
}
int main()
{
cout << "hello, world" << endl;
return 0;
}
408 :
名無し~3.EXE :03/02/05 13:10
>>402 無名ネームスペースじゃだめな気が
あれはstaticの改良だよね?
そのファイルからしか見えなくなるという
411 :
名無し~3.EXE :03/02/05 14:19
>>409 過去ログのどのあたりでやってたかわかります?
結論は?下らんジョークって落ちか。
元ネタは何なんだろう。。。
usingをグローバルで使う奴はタコ
414 :
デフォルトの名無しさん :03/02/05 23:06
すいません、ちょっと質問。 inputとoutputが同じファイルを指すストリームであるとして 書き込みプログラムで int a = 0; output.write((char*)&a, sizeof(int)); 読み込みプログラムで while (!input.eof()) { input.read((char*)&b, sizeof(int)); cout << b << endl; } とすると 0 0 と二回結果が返ってきます。 一回しか書き込んでないのになぜ?
while ( input.read((char*)&b, sizeof(int)) ) { cout << b << endl; }
416 :
デフォルトの名無しさん :03/02/05 23:29
>415 なるほど。 実際にはいろんな型の複数のデータを扱っているので 構造体にでもまとめてその手法を使ってみます。 ありがと。
>>416 「手法」じゃねーよ。>414が間違ってるだけ。
ちゃんと理解してから先に進みやがれってんだ。
(char*)とsizeof(int)がよくないんじゃないの?
>418 ごめん、精進します。
>>417 最後のデータより後ろを読んだ時にeofbitがセットされる。
正しくデータが読み込めている限り、eofbitはセットされない。
>>419 それなら
>>415 でも治らないだろ。
>>414 input.eof()がtrueになるのは、一度読み込んでみてからでないと
判断できない。
だから
while (true)
{
input.read((char*)&b, sizeof(int));
if (input.eof()) break;
cout << b << endl;
}
ではないかと思うのだが。
俺がバカだったのは認める。
>>421 >>422 の言うこともわかる。
しかし、
>>414 で、2度目の0の出力が不思議だ。
あ、2度目の読み込みでは、データは読めず、前の0がbに残ってるからかな。
自己レス。やっぱりそうだった。
>>414 の設定で、
int b, c = 100;
ifs.read((char*)&b, sizeof(int));
cout << b << endl;
ifs.read((char*)&c, sizeof(int));
cout << c << endl;
としたら、
0
100
と出力された。
今晩は勉強になりますた。
サンキューです。
>>421 >>422 あんど
>>414
>>426 かぶりましたな。
まあ、もう少し、やさしい人になってちょーね。
429 :
デフォルトの名無しさん :03/02/06 00:05
話戻すようでわるいんだけど。 ifstream is( from.c_str() ); istream_iterator<string> ii( is ); istream_iterator<string> eos; int i = static_cast<int>(distance( ii, eos )); vector<string> b( i ); copy( ii, eos, b.begin() ); なんかうまくcopyされてないみたい。。。 この ii の値はdistanceの後変わってしまう? あとeosってここではどんな意味が?
>>430 istream_iteratorにdistance?
eosはend_of_streamだな。
distanceした時点で読み込みが完了するものとおもわれ。
入力が完了するまで要素数はわからないので、あらかじめ確保するのはムリ。
back_inserter使え。
>>430 eosってのはstd::istream_iterator()という引数なしの
コンストラクタだから、EOFを示している。
distance()でeosまでの距離を取ったら、ストリームを一度最後
まで読むから、値がおかしくなるんじゃない?
std::copy(ii, eos. std::back_inserter(b)); ではどうか。
みごとなかぶりっぷり。
ケコーン(w
>>430 ifstream is( from.c_str() );
istream_iterator<string> ii( is );
istream_iterator<string> eos;
int i = static_cast<int>(distance( ii, eos ));
vector<string> b( i );
ii.clear();
ii.seekg(0, std::ios::beg);
copy( ii, eos, b.begin() );
こうやったらどう?
おもいっきり戻ってるね。 ちなみに、何がしたいかわかんないけど、フツー ifstream is( from.c_str() ); istream_iterator<string> ii( is ); istream_iterator<string> eos; vector<string> b(ii, eos); でない?
438 :
デフォルトの名無しさん :03/02/06 01:51
例えば参照カウント式のスマートポインタを作るとして、 ポリモーフィズムを扱いたい場合には explicit counted_ptr(T* p = 0) : ptr_(p), count_(new long(1)) { } template <typename U> explicit counted_ptr(U* p = 0) : ptr_(p), count_(new long(1)) { } という二つのコピーコンストラクタを作るのかなぁと思ったのですが、 良く良く見ると後者は前者を包含してるように思えます。 という事は前者はいらないのでしょうか? ちょっとこの辺り(型の自動変換の問題とか?)にイマイチ自信が無いのですが、 後者だけでは何か問題があったら教えて頂けますでしょうか。
書き忘れた事を一つ。 前者で explicit を取ればいいような気もするんですが、それには 何か潜在的な危険は無いんでしょうか?なんか参照カウントならいいよう な気がしなくもないんですが、boost::shared_ptr は後者のみみたいで、 その辺が良く分かっていなくて混乱しているのですが・・・
>>438 explicitは、単にT*が暗黙にcounted_ptr<T>に変換されるのを防ぐ
ためだからちと違うんでない?
前者でも counted_ptr<Base> ptr(new Derived()); は書ける。
後者は前者を包含するけども、↑を書く時点では前方参照でもOK
らしい、ちゅうところが違うみたい。
#同じコンパイル単位に定義は必要だが。
#include "counted_ptr.h"
class Base; class Derived;
void func(Derived *p) { counted_ptr<Base> ptr(p); } // 前方参照のみ
class Base {}; class Derived : public Base {};
g++3.2では、前者はNG、後者ならOKでした。
テンプレートにマッチすることで、型のチェックが遅延するのかな?
ん、なんか
>>438 の疑問をとりちがえたらしいや。
後者は前者を包含するし潜在的な危険もないので、後者だけでいいんじゃない?
と答えるところだったのか。
explicitの有無については
>>440 になるんでないかの。
また、細かい話だがそれはコピーコンストラクタとは言わんと思う。
コピーコンストラクタっつたら、これ↓じゃない?
template <typename U> counted_ptr(const counted_ptr<U> &);
442 :
デフォルトの名無しさん :03/02/06 07:55
コピーコンストラクタはtemplateから暗黙的に生成されないよ。 だから両方必要なはず。 ExceptionalC++に書いてあったと思う。
>>442 言ってることがよくわからんけど、テンプレートでもコピーコンストラクタできるんじゃない?
やってみたらできたよ。
できる −> 暗黙に生成される
んー(苦笑
>>440 =441
ありがとうございます。とりあえず後者のみで良さそうって感じですかね。
boost::shared_ptr もそうなってるっぽいですし、まぁそうかなぁとは思ったので
すが、なんか前者が無いとイマイチ根拠の無い不安があるんですよね(苦笑
# たしかにコピーコンストラクタとは違いますね。スミマセン。
>>442 ,443
うー、ExceptionalC++持ってないから分からないのですが、とりあえず
後者だけでもg++3.2.1なら通るんですよね。僕の環境でも。ただ、g++も標準に準拠している
のかどーなのかまだ完全じゃないっぽいんで、判断が難しいんですよね・・・
# VC++で通らないと「きっとVCの準拠度の低さのせいだな」と結論付けちゃうんですけど(w
あと、boost::shared_ptr を見てて思った事。
operator=(T* p) じゃなくって reset(T* p) っていうのは、やはり
a = b = c = ...
とかっていう時にポインタと shared_ptr が混ざってると混乱するから
なんでしょうかねぇ?個人的には operator= でいいような気もするんですが・・・
>>448 嘘を言ったように見える。
↓のコード、実行前に予想した結果と、実際に実行した結果が同じになるか?
#include <iostream>
struct X
{
  X(){}
  template<typename T>
  X(const T&){ std::cout << "template constructor" << std::endl; }
};
main()
{
  const X x;
  X copied(x);
};
>>449 予想:Xにはコピーコンストラクタが暗黙で生成されるので、実行してもX(const T&)は呼ばれない。
結果:その通りだった。
しかし、その前に、
>>449 のコードは、なんだか尋常でないものを感じる。
もう少しフツーのコーディングを覚えた方がいいんじゃないの?
コピーコンストラクタって言葉遣いもまちがってそうだし。
ああそうか。
>>449 は、X(const T&)から、X(const X&)が生成されるかもと思って、
そうでなかったので、それを「テンプレートからコピーコンストラクタが
暗黙に生成されることはない」と言ったんだね。
そりゃあ、用語がめちゃめちゃやん。
もう寝る。
>
>>449 のコードは、なんだか尋常でないものを感じる。
うむ、mainの終わりにセミコロンがついてるのは尋常じゃぁない。
>>451 なにがめちゃめちゃになってるのかわからん。
起きたらまとめてくれ。
コピーコンストラクタは、受け側と送り側が全く同じ型でないと 生成されないみたいだね。 で、テンプレートを使った一見コピーコンストラクタに見える定義 だけど、受け側と送り側が同じでない場合があるからという理由 で、コピーコンストラクタになる事を拒絶するようだ。 例え同じ型でも。
しかしこういう全く同じ型だと明らかに分かる場合でもコピーコンストラクタを 呼んでくれないのはなぜ?(T_T) #include <iostream> template <typename T> struct X { X() {} X(const T&) { std::cout << "template constructor" << std::endl; } }; int main() { const X<int> x; X<int> copied(x); X<int> copied2; copied2 = copied; }
>>454 どこが明らかなんだ?
X(const X&) 書く以外に、同じ型であることが明らかである場合があるのか?
代入は代入演算子を(以下略
>>455 >>456 やっぱりだめか・・・・
基本的にテンプレートはコピーコンストラクタは全くだめなんですね。
459 :
デフォルトの名無しさん :03/02/06 19:05
>>454 X<int> copied(x); において
const T& は const int& になるのであって、
const X<int>& にはなりません。
X< X<int> > copied(x); が正解です。
>>459 本当だサンクス!
型が合えばテンプレートでもコピーコンストラクタを生成してくれました!
>>460 確認しておくが、テンプレートからコピーコンストラクタは生成されんぞ。
>>461 クラステンプレートではなくてメンバテンプレートでという意味ですか?
うん
>>463 でもこれだとメンバテンプレートだけどコピーコンストラクタを生成
してくれたよ。
template <typename T>
struct X {
X() {}
template <typename U>
X(const U&) {
std::cout << "template constructor" << std::endl;
}
};
int main()
{
const X<int> x;
X<X<int> > copied(x);
}
>>464 「コピーコンストラクタを生成してくれた」とは、
そのソースの実行結果がどうなることを言うんだ?
コピーコンストラクタの意味わかってる?
>>464 T==Uの時、X(const U&)を呼んでくれたという事なんですけど・・・・
これはコピーコンストラクタと呼ばずに別の呼び方をするべきでしょうか?
>>466 T==Uでも、X<T>::X<U>(const U&)はコピーコンストラクタじゃぁねぇ。
X<T>のコピーコンストラクタは、X<T>::X(const X<T>&)
>>467 よくわかりました。
ありがとうございました。
469 :
デフォルトの名無しさん :03/02/06 19:52
#include "iostream" struct S_Base{public:float x,y;virtual ~S_Base(){;}}; class C_Child_S_Base:public S_Base{public:virtual ~C_Child_S_Base(){;}}; class C_GrandChild_S_Base:public C_Child_S_Base{public:~C_GrandChild_S_Base(){;}}; class C_Base{public:float x,y;virtual ~C_Base(){;}}; class C_Child_C_Base:public C_Base{public:virtual ~C_Child_C_Base(){;}}; class C_GrandChild_C_Base:public C_Child_C_Base{public:~C_GrandChild_C_Base(){;}}; int main(int argc, char* argv[]){ S_Base *p_SB=(S_Base *)new C_GrandChild_S_Base; delete p_SB; C_Base *p_CB=(C_Base *)new C_GrandChild_C_Base; delete p_CB; return 0; } structを継承する時に基底structでデフォルトデストラクタを使ってる例 をよく見かけますが、仮想デストラクタでないためかVC++.Netだと ASERT落ちします(当然ながらclassも同じです)何故でしょう? 今までふつーに使って平気だと思ってたのですが・・・ 上のソースのベースのデストラクタをコメントアウトして実行してみてください
ASSERTEはメモリリークの警告ではないんですか? structのデフォルトデストラクタはvirtualでないというのは C++の仕様ですか?それともMSだけですか?あとclassもそうなんですか? _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)); で落ちます
>>471 おちつけ。まずは仕様書…とは言わんが、せめて「プログラミング言語 C++」と
MSDN Library 読んでからな。
>>472 手元の本はEffectiveC++しかありません
MSDN見てみます
だからあれほど規格書を仕様書と呼ぶなと
>>474 げ、ほんとだ。脳内で置換しておいてくれ。
>>469 class A {
public:
~A() { cout << "~A" << endl; }
void foo() { cout << "A" << endl; }
};
class B : public A {
public:
virtual ~B() { cout << "~B" << endl; }
virtual void foo() { cout << "B" << endl; }
};
class C : public B{
public:
virtual ~C() { cout << "~C" << endl; }
virtual void foo() { cout << "C" << endl; }
};
main() {
A* a = new C; // 危険
a->foo();
delete a;
B* b = new C;
b->foo();
delete b;
}
さて、何がどう呼ばれるでしょう?
#define _CRTDBG_MAP_ALLOC #include <stdlib.h> #include <crtdbg.h> MSDNで関係ありそうなのは、VC++6.0のメモリリーク検知の記述だけでした 上の順番で入れるといいらしいのですが、うちの環境では結局同じ所で 落ちました structもclassも派生させるんならデフォルトデストラクタを使うな ということですか?誰か教えてください でも、DirectX関係でもstructから派生させてデフォルトデストラクタを使ってる ような気がしますが・・・???
>>476 あ、ごめんなさい更新していませんでした。
今読みます
>>476 当然class Aは仮想デストラクタでないのですから~Aで止まりますが、
私が分からないのは「デフォルト」デストラクタは仮想かそうでないのかが分からないのです
特にstructから派生させる時は、「デフォルト」デストラクタを使う場合が多いのでは?
>>479 まず、classとstructでの差は無い。
基底クラスが無い場合、デフォルトではvirtualにはならない。
基底クラスがある場合、デフォルトでは、基底クラスのデストラクタと同じになる。
>>480 ありがとうございます。それが知りたかったのです。
巷にある、structから派生させているのにも拘らず「デフォルト」
デストラクタを使っているサンプルは誤りということですね。
>>481 仮想関数を1つも宣言しない場合は、誤りであるとは言えない。
>>482 >仮想関数を1つも宣言しない
デストラクタはclass派生させる場合は仮想にしなければならない
という認識ですが
>>483 自己レス
派生元のデストラクタを仮想にということです
>>485 情報ありがとう
へっぽこ英語力でななめ読みですが、
ええと、仮想デストラクタにしない場合というのは
親族クラスのその階層以下でそれ以上「動的確保しない」場合のみですか?
それなら分かるのですが、階層以下で「動的確保してる」場合は
メモリリークですよね。意訳間違ってますか?
コストはあまり考えずに仮想ばっかやっていましたが・・・
サンプルを元に派生クラスを作る場合はサンプルのデストラクタの属性に
気をつけろということですね
>コストはあまり考えずに 破門。C++以外の言語に乗り換えれ
ちなみに以下のコードはVC6ではコンパイルエラーがおきる #define _CRTDBG_MAP_ALLOC #include <crtdbg.h> #include <stdlib.h>
>>487 >破門。C++以外の言語に乗り換えれ
そんなぁ
デストラクタは主に動的確保の開放で使いますよね
それを途中で切ればコストは稼げますが、リソースの方が重要じゃないですか
安全に切る為にはその階層以下がNULLデストラクタってことですよね
NULLデストラクタだとあまりコストが稼げない気もしますが・・・???
>>488 あ、順番は必ず守れとMSDNに書いてました
>>490 「クラス階層以下で動的確保」「デストラクタを途中で切る」「NULLデストラクタ」
デムパがびゅんびゅん飛び出してる。
自分にしかわからん造語をあたりまえみたいに書き散らすなボケ。
そりゃぁ破門したくもなるぜ。
>>492 はい、すみませんデムパ説明します
「デストラクタを途中で切る」
継承クラスで非仮想デストラクタを宣言する
「クラス階層以下で動的確保」
上(デストラクタを途中で切る)のクラスから継承されたクラスで
newなどの確保をする
「NULLデストラクタ」
NULL命令(これは造語ではありません)しかないデストラクタ
頼むから469の相手をするのはやめてくれ。
>>494 すまん。これで最後にさせてくれ。
>>493 破 門 確 定 。
理由を聞かれても答えんからな。
$ NULL ぬるぽ!
___ ガスッ
|___ミ ギビシッ
.|| ヾ ミ 、 グシャッ
∩_∧/ヾヽ
| ,| ゚∀゚). .| |;, ゲシッ
/ ⌒二⊃=| |∵.
.O ノ %`ー‐'⊂⌒ヽ ゴショッ
>>493 ) ) ) )~ ̄ ̄()__ )
>>496 ヽ,lヽ) (;;;;;;;;;;;;;;;;;)(_(
>>497
夢だ、夢だ、、
ちんぷんかんぷん揚げ
朝のぬるぽから夜のぬるぽまで幅広くサポート
あるクラス(Aとしよう)のデストラクタがvirtualであれば、 そのクラスを継承したクラス(Bとしよう)のデストラクタは必ずvirtualになる。 Bのデストラクタに対しvirtualキーワードを付けるかどうかに依存しない。 これはメンバ関数についても当てはまる。
class A { virtual void func() const {} }; class B : public A { nullpo void func() const {} }; Bのfunc()をvirtualで無くす方法。ぬるぽ。
502に追記。classとstructの違いは、デフォルトのアクセス権のみなので、 502の事柄はstructにも当てはまる。
ぬるぽっていつごろからどういう意味で使われだしたの?
507 :
デフォルトの名無しさん :03/02/07 00:46
頭痛い...。
「デストラクタを途中で切る」
>>502 の言う通り。
「クラス階層以下で動的確保」
やっぱり意味が分からない。
多分
>>502 を踏まえれば意味の無くなる言葉なのだろう。
「NULLデストラクタ」
デストラクタは暗黙に
メンバ変数と基底クラスのデストラクタを呼ぶという後処理を含むので、
完全に無くなるというのはメンバ変数にデストラクタを呼ぶクラスがなく、
かつ基底クラスも同条件である場合のみ。
「NULL命令」
いわゆる NOP のことか?
上記の様に完全に消え去る場合は関数が呼ばれすらしないし、
それ以外でも NOP などは入らない。
関数と関数の間の詰め物として NOP を使うことがあるが、それは100%別の話だ。
それとも ((void*)0)(); という類のものか?
これは上の完全に消え去るということと同義なわけだが、
その条件は上の通り非常に厳しいものだ。
「NULL命令」 もしかして空文のことか?
まあ、リソースの解放を気にしているだけマシなのかもしれん。
>>485 のリンク先読んでみたけど、
"A Good Thing"と"Yuck"が訳せん…
特に後者。ひょっとして笑うところ?(んなわけないか)
質問です。 ↓のような op= の定義は、C++的にアリですか? std::wstring& operator=( std::wstring& lhs, std::string& rhs ) { if( !s.empty() ) { std::vector< wchar_t > buff( rhs.size()+1 ); if( std::mbstowcs( &buff[0], rhs.c_str(), rhs.size() ) == -1 ) throw charactertype_convert_exception(); lhs = &buff[0]; } return( lhs = L"" ); }
>>517 …つーか グローバルな op= ってコンパイル通らないや。
ごめん、op<<=に変更 VC++7.0 で動作確認。
std::wstring& operator<<=( std::wstring& lhs, const std::string& rhs )
{
if( !rhs.empty() )
{
std::vector< wchar_t > buff( rhs.size()+1 );
if( std::mbstowcs( &buff[0], rhs.c_str(), rhs.size() ) == -1 )
throw std::runtime_error("bad chartype convert");
lhs = &buff[0];
returnlhs;
}
return( lhs = L"" );
}
アリですか、ナシですか?
>>518 ちゃんと動くんならアリだと思うけど、<<=はあんまり見慣れないから、
ソースが読みづらくなりそうだと思いました。
つーか・・・何がしたいの?
521 :
デフォルトの名無しさん :03/02/07 14:28
if ("おっぱい" == "おっぱい") cerr<<"Is this undefined?"<<endl;
つか書き方がキモい std::wstring& operator<<=( std::wstring& lhs, const std::string& rhs ) { if( rhs.empty() ) return( lhs = L"" ); std::vector< wchar_t > buff( rhs.size()+1 ); if( std::mbstowcs( &buff[0], rhs.c_str(), rhs.size() ) == -1 ) throw std::runtime_error("bad chartype convert"); lhs = &buff[0]; returnlhs; }
てかなんでこの処理を演算子にするんだ
>>520 ,523
std::string& operator <<= ( std::string& lhs, std::string& rhs );
std::string& operator <<= ( std::string& lhs, std::wstring& rhs );
std::wstring& operator <<= ( std::wstring& lhs, std::string& rhs );
std::wstring& operator <<= ( std::wstring& lhs, std::wstring& rhs );
...
std::wstring& operator <<= ( std::wstring& lhs, int rhs );
int& operator <<= ( int lhs, tstring& rhs );
などとそれぞれ作っておけば、型や方向を気にすることなく、
target <<= source; とか、
str <<= 123;
と何でも変換機みたく書けるなぁ…と考えたからです。
lexical_cast みたいにターゲットの型を明記する必要もないし。
ただ、
>>519 のいうように、ソースみて混乱するかも…
つーか、書いてて無用の混乱を生み出しそうな気がしてきたな…
まぁ、忘れてください。
wstringstream, stringstream にそれぞれ operator<< を定義するっちゅーのはまぁいいと思うんだが。
526 :
デフォルトの名無しさん :03/02/07 23:55
lexical_castが UNICODE対応とトークン対応すりゃいいんだが。 (doubleもspecializeする必要あるが...) (でも、すべてのコンパイラでUNICODE使えるかわからん) cout << lexical_cast<string>("あい aうえ",L"う"); //あい a な感じで
L""ってgccだと悲惨なことにならんか?
528 :
デフォルトの名無しさん :03/02/08 02:15
とりあえず前スレより上へ浮上age。
>>524 「何でも変換」って時点で最悪。
キャストとかも explicit にすべきなのに、
代入演算子で暗黙の型変換なんかされた日にはもう。
ロケールってあんま良く分かってないんだけど、とりあえず setlocale( LC_ALL,"”); のかわりにしたいなら locale::global(locale("")); ってやっときゃいいの?
てsつとふぁせtto
532 :
デフォルトの名無しさん :03/02/08 21:12
質問です。 #include<iostream.h> int main() { cout<<rand()<<endl; } とやると、何度やっても答えが130になります。が、 int main() { cout<<rand()<<endl;cout<<rand()<<endl;cout<<rand()<<endl; } とやると、130、10982、1090となります。 数字を実行毎に変化させる事は出来ないのでしょうか?
>532 srand
srand(time(NULL));
535 :
デフォルトの名無しさん :03/02/08 21:59
>533-534 アリガd ところで、gmtimeってなんの略でしょう?
give me your time.
なるほど「お時間もらえますか?」ですね。アリガd
Σ(゚Д゚)
グリニッジ標準時(Greenwich Mean Time; GMT)だYO!
ま、マリリンモンローのポポポスターが・・・
>539 すると、残りのimeってなんの略ですか?
Ikumaeno Meidonomiyageni Ehimemikan
Greenwich Mean Time Ikumaeno Meidonomiyageni Ehimemikan
和洋折衷すぎ
warota
参照を使って次のようなコードを書いたとします。 int* p = NULL; int& i = *p; i = 100; ここで3行目のように i を使うと segmentation fault を起こします。 (int*)NULL にアクセスすることになるのだから当然ですね。 また (&i == NULL) という式の値は真(非零)となります。 少なくとも僕の環境 Debian GNU/Linux 3.0r1 (gcc 2.95.1) ではそうなります。 で、お聞きしたいのは、ANSI C++ や Stroustrup の C++ の 言語仕様的には次のいずれなのでしょうか? 1) 2行目の宣言が不可能でその結果が未定義 2) 3行目の式の評価が不可能でその結果が未定義
2行目の宣言…ではなく、 > *p; null pointer の dereference が未定義。
ということは、2行目の時点で実行時エラーとなるような 実装もあり得ると言うことでしょうか?
551 :
デフォルトの名無しさん :03/02/09 21:07
よく、サンプルプログラムについてる、 Return 0; って何ですか?例えばこんなん。 #include <stdio.h> main() { printf("name: "); return 0; //←これ。 }
>>551 多くの処理系(というか OS)では
main 関数の戻り値が 0 であった場合に
プログラムが正常終了したと見なします。
なので、特に main 関数の中で問題が発生しなかったときには
return 0 などとしているわけです。
でも 0 が正常終了を表さないような処理系もあるので、
次のように書く方が移植性が高いでしょう。
#include <stdlib.h>
int main (void)
{
// your main code here
return EXIT_SUCCESS;
}
>0 が正常終了を表さないような処理系 ネタでつか
554 :
デフォルトの名無しさん :03/02/09 21:20
>>552 なるほど。ありがとうございます。
何故かほとんどの記事がコレには触れないんです^-^;
bcc32ではreturn 0; 無くてもコンパイル・実行共に通ったので、
悩んでました。
省略するのが一番移植性高そうだな。
>>550 うむ。例えばCINTはそこで落ちるね。
>>556 ふーむ、やはりそうですか。
うちの環境で #include <iostream.h> やって、
cout << *(int*)NULL << endl;
なんて実行すると (nil) って表示されたんで、
「ん? lisp みたいに nil を返すなんてこともトリッキーながらできたりして。」
って思ったわけです。
ある関数ないでエラーが発生したりして、 意味のある値を返すことができない場合は 次の二つの方法があると思います。 1) あり得ない値を返す。 たとえば年齢として負の値を返すとか。 2) 戻り値とは異なる経路でエラーを伝達する。 3) 例外を発生させる。 で、lisp で言うところの nil みたいなものを扱う方法が C++ にあれば 1) をやる場合に便利だなぁと思ったわけで・・・ まぁ浮動小数点における NAN みたいなものでしょうか。 いや、 int をそのまま使わずに Java の Integer 型みたいに クラスにくるんでしまえばなんとでもなるのはわかっているんですけど、 それも大げさだなぁ、と思った次第でして。
>>553 dos の batkey とかは、リターンコードで情報を返したりするよ。
>>559 が「0 が正常終了を表さないような処理系」だっていうのか?
へぇ・・・。
C++ならstdlib.hじゃなくてcstdlibだろ
なるほど、batkeyという「処理系」があるんですね。アリガd
>>565 dos と言うものを知らんアフォが絡んできただけのことか...。
標準C++はmain関数に限り、return文を書かないと、return 0; を 実行して終了したのと同じ意味になるので、0が正常終了を表さない 処理系では標準C++は使えないね。
>>568 main 関数の返す値とプログラムの返す値が同じである必要は無い。
0とEXIT_SUCCESSとは、exitの引数およびmainの戻り値として渡されたとき、 同じ動作をする仕様となっております。
>>567 いま boost の class optional のコードを読んでみました。
結局のところ、
class optional
{
いろいろ
省略
private:
bool m_initialized;
storage_type m_storage;
}
となっていて、そのオブジェクトが有効か無効かを記憶しているだけですね。
>>559 0 が正常終了を表さないような処理系もある
と言う事と
リターンコードで情報を返したりする
事は全く別の問題だろ
574 :
デフォルトの名無しさん :03/02/10 06:36
アクセス関数でメンバにアクセスするとインライン化してもかなり重くなる こういうのを全部publicにしちゃうのはC++的にどうですか? ちなみにゲームのプログラムです。
575 :
デフォルトの名無しさん :03/02/10 07:49
折れアクセサあんまり書かん。 安全上必要なときだけ書く。 面倒なだけじゃなく、コードが増えて可読性落ちる、保守性落ちる。 折れのまわりには、必ずアクセサ書く香具師いる。 いろいろ理由言ってるけど、最後は趣味の問題。
>>575 アクセサにしとかんと、インターフェースと実装を分離できないやん。
>>574 > ちなみにゲームのプログラムです。
俺は本職のゲームプログラマだけど、性能が要求される部分なんて、全体から
見たらほんの一部だよ。
たとえばアクションゲームでプレイヤーの制御する部分なんか、しょせん 1/60s
に一階しか呼ばれないから、そこで間接ジャンプが 100 回ぐらい入っても誤差
誤差。
>>577 C++なら、アクセサ無しでもテンプレつかって分離という手もあるぞ、まあお勧めはせんけど。
>>578 テンプレートはコンパイル時にシグネチャに基づいて結合させるから、プレイヤーの
状態遷移の制御なんかにゃ使えんでしょ。(あっちは実行してみないと状態が確定
しないわけで)
アクセサをインライン化しても重くなる場合ってどこでオーバーヘッドが かかってるの?
581 :
デフォルトの名無しさん :03/02/10 14:14
>>581 デバッギングオプションを on にしていて、
実は inline になっていない、とか?
583 :
デフォルトの名無しさん :03/02/10 14:54
//戻り値void, 引数void void f(){ cout<<"f()"<<endl; } f(f()); //error. why?
引数voidってのはな、void型を受け取るって意味じゃぁないぞ。
>>575 が逝ってることは、不要ならGetやSetを書かんということじゃないの?
メンバ変数は当然privateとして。
そんなら、普通のことだが。
もし、メンバ変数をpublicにしるということなら。。。
ガクガクブルブル
>>585 使いたくないけど、どうしても必要なら friend ですかね。
でも漏れは今まで演算しオーバーロード以外で使ったこと無いですけど。
メンバ変数を public にするならむしろ明示的に class じゃなくて
struct って書いた方がいいかも。
>>585 virtualじゃないなら書いてもコンパイルが遅くなるだけでアプリのスピードは変わらん。
すいません勘違いしてました。582sanの言うように設定ミスってました。
>>577 san
そろそろ全体の負荷を把握しときたいなとプロファイラを導入したのが事の発端でした
>>586 てきとーなこといってんじゃねぇよ。
得意げな顔してなにが「 fiend ですかね。」だ。
お前は本当に、以下略。
>>585 > もし、メンバ変数をpublicにしるということなら。。。
> ガクガクブルブル
なんでメンバ変数をpublicにしたらいけんのか小一時間
>>590 データメンバをpublicにするなら、classの中に置いてある意味が無くなるだろ。
>>592 データメンバをpublicにするなら、classに置くのもグローバルにするのも
同じと言いたいのですか?
>>590 君は、
1.ただのばか
2.いろんな可能性でうんちくを述べたいばか
のどちらかだろうから、とりあえず、息の根を止めてよかよ。
ばかが一人でもはいるとC++の開発は破綻するって、名言だなあ。
あはは。煽りうざいなぁ。息の根止めて氏ねよ。
>>584 内側のf()は何も返さないのだからOKになるのが普通じゃないですか?
言われてみるとそんな気もしてきたけど・・・
ハッ?漏れは
>>583 にだまされているのか?
575じゃないが、時と場合によっては、 メンバ変数をパブリックにしてもいい場合もあると思うが。 メンバを勝手に変更しても、問題ない場合とか。 class RectDrawer { ... public: Point begin; Point end; }; 他にも、Point とか、Rect とか、Matrix みたいなのは、その典型。
引数をとらない関数の「引数リスト」に引数を記述すること自体が 構文として間違っているのでは。
>>600 C の構造体に、操作に便利なメソッドを幾つか追加したってタイプのデータ構造な。
個人的には struct にするけど。
最近C#使い始めて、移植性の都合上で意図的にメンバを public にする事が多くなってる。 C++ にもプロパティーが欲しい今日この頃。
プロ仕様のパティー ↓ (゚д゚)ウマ-
ファイルのプロパテー
Java3DのVectorとかMatrixとかも速度のために成分がpublicになってるでござる。 って普通かも。
>>606 それはね、使ってみると分るよメッチャ便利だから。
特にテンプレートと組み合わさったら無敵になると想像。
>>607 VECTOR や MATRIX みたいな、値指向の型だとそれもありだろう。OOP でいうところ
のオブジェクトではなく、むしろプログラミングのネジ・クギにあたる具象クラスってヤツ
な。
プログラミング言語 C++ でも散々解説されてるけど。
プロ現C++高いよアニキ〜
下手な本2,3冊買ってしまうより,なんぼかまし. どんと買っとけ
C++Primerもそのアンサーブックも買ったよ。 プロ現C++よりさらに分厚くて、見て笑ってしまう。
所謂has-aの場合、クラスの外からメンバクラスへのアクセスがだるいのですが。
漏れ的には、いまだに A級B型C++ が 初心者にはもっともわかりやすいと信じて疑わないんだけど、 でも廃刊。しょぼーん。
class A { //いろいろとかく }; typedef B A; これって、エラーになりますよね。 単純な型以外で typedef のようなことはできないものでしょうか? class B : A {} と継承しても良さそうなものですが、 オーバーロード演算子は継承されませんよね。
やっぱり #define でプリプロセッサの助けを借りるしかないのでしょうか?
618 :
デフォルトの名無しさん :03/02/11 07:52
typedef A B; じゃないのか?
ごめん、
>>616 は typo
で、よくソースみてみたら
typedef A : B;
ってやってたよ!
何で真ん中にコロンなんて入れちゃったんだろう。
( ゚д゚)ポカーン
621 :
デフォルトの名無しさん :03/02/11 14:36
コンパイルは通るのですが、実行すると落ちまする。 殿,どうかご助力を。 #include <stdio.h> aisatsu() { printf("hello"); return 0; } main() { int ans; int loop; ans = 0; printf("処理を選択してください\n"); printf("1.aisatsu 2.aisatsu"); scanf("%d",ans); if (ans == 1) aisatsu(); else aisatsu(); }
&ans;
なんで俺セミコロン書いてるんだ・・・?
624 :
デフォルトの名無しさん :03/02/11 14:45
>>622 Σ( ̄ロ ̄;
実行できました。かたじけのうござる。
どうして &をつけるとうまくいくのでござろうか。
Cスレでやってよ
あれ?Cスレ?
かぶた
こんにちわ、C++厨です。
厨はすっこんでろ
一瞬、豚はすっこんでろ、かとオモタヨ。
たしかに豚もすっこんでて良い
632 :
◆8x8z91r9YM :03/02/11 16:20
633 :
デフォルトの名無しさん :03/02/11 16:32
>>632 そういうのを使う用事のある人に対して反感を持っています。
無作為にor不特定多数にメールを投げるのはやめなさい。
もっとまっとうな商売をしなさい。
つか、こいつこの板に常駐してね? 前もどっかのスレで作ってくれって言ってたよ。
In-Depthシリーズの「C++ ネットワークプログラミング」を買おうか子一時間迷った。
C++ というかオブジェクト指向の言語を使っていて、 いつも悩むのが 「ああ、コンストラクタが失敗してたらどうしよう・・・ 」 もちろんこういうことは例外で処理するのがスマートなのだとは思いますが、 例外処理を使いたくない場合は皆さんどうしておられるのでしょうか? 1) クラスの中に、コンストラクト成功・失敗のフラグを用意する。 で、アクセス関数として int IsAvail(void) みたいなのを用意する。 2) コンストラクタの引数に成功・失敗を返すための変数への参照を取る。 MyClass::MyClass ( int & flag) でも引数なしのデフォルトコンストラクタだとどうしようもない。 これ以外に何か方法あります? #グローバル変数使ったりするのは即却下。
コンストラクタで初期化処理を行わない
た、確かにそれは一つの解決法ですね。 どうしてもコンストラクタが必要になるケース以外では。 1) 引数なしのデフォルトコンストラクタが自動的に呼び出される場合。 2) 型変換のためにコンストラクタが自動的に呼び出される場合。 「自動的」って言い方はよくないかなぁ。 「暗黙に」といった方がいいのかもしれないですが。
> 安く作成 (・∀・)カエレ!
640 :
デフォルトの名無しさん :03/02/11 17:54
>>635 Aceとかいうのを使ってナニする奴かい?
漏れも一瞬迷ったけど、変な物使うぐらいならと思ってWinSock2.0の本を買って帰ったよ。
641 :
デフォルトの名無しさん :03/02/11 18:21
636じゃないですが、 例外処理を有効にしてコンパイルするときに、 例外処理のオーバーヘッドを最小限に抑えるためのアプローチって、 なにか一般的なものはありませんか?
例外の無い言語使えばいいじゃん
例外処理を有効にしてコンパイルしている時点で、 例外処理によるオーバーヘッドは仕方ないものだと思います。 #実行時型情報もオーバーヘッドありますね。
やはりオブジェクト指向は高水準言語の方が適してるのか
速度が求められるところは C++ で書いて、 それ以外は Scheme とかで書きたいなぁ、なんて思う今日この頃。 いや、10分ほど前から libguile のマニュアル読み出したところなんだけど。
メモリの動的確保を採用してもそのオーバーヘッドを
最小限に抑えるようなアプローチは結構一般的なものがあると思ってるけど、
例外処理については
>>643 のように「仕方ないもの」で
済ませてしまっているようで、もうちょっとなんとかならんものか、と。
手当たり次第に throw() を付けていくってのは効果的なんでしょか?
647 :
デフォルトの名無しさん :03/02/11 19:27
CとかC++使えちゃえば他のジャヴァとか覚えるのは簡単ですか?
覚えるんじゃなくて学ぶんだよ。
(゚Д゚)ハァ?
(゚O゚) オオ?
みんなどこいっちゃったの? オロオロ
>>651 姿は見えなくても、いつも漏まえのそばにぬるぽ。
VC6の場合、static_cast<>使う場合はコンパイラに実行時型情報を要求されるんですが static_cast<>の場合って普通の型キャストとおなじなので実行時型情報はいらないですよね?
> static_cast<>の場合って普通の型キャストとおなじなので実行時型情報はいらないですよね? これはたしかにそうだが、 > コンパイラに実行時型情報を要求される これの意味がわからん。
1行目は dynamic_cast の typo の悪寒。
>>646 >手当たり次第に throw() を付けていくってのは効果的なんでしょか?
throw() があると、例外の有無をチェックするコードが挿入されるので、
逆に効率が悪くなる。
>>656 げ、そーなの?俺
>>646 じゃないけど、throw()付けとけば
例外投げない宣言として変なコードが挿入されないだろうとばっかり思ってた・・・
>>656 それはthrow()を付けた関数の中に、throw()のついてない関数の呼び出しがある場合。
とはいえ、インターフェース決めるときの手がかりにはならんな。
gcc3.2で少し試してみたけど、例外が発生しなかった場合のコードに注目すれば、
throw()を付けても付けなくてもほとんど変わらないようだ。
追加コードも妥当なものだった。
もっと想像を絶するコードになるかと思ったが、結構理想的な実装になってるじゃないか。
throw()をつけるつけないで効率が変わるのは、コンパイラの実装が未熟なのだろう。
そうなると、一般的なアプローチがないのもしょうがないな。
>throw()を付けた関数の中に、throw()のついてない関数の呼び出しがある ↑個人的にはこの場合はコンパイルエラーにして欲しいな。
unexpectedォーーー
えっちだ!
誤爆スマソ
663 :
デフォルトの名無しさん :03/02/12 23:35
fstreamとofstreamってなにか違いが有りますか? 例: fstream fl; fl.open(ios::app){...} fl.close() と ofstream ofl; ofl.open(ios::app){...} ofl.close() って、やってることは何か違うのでしょうか?
>>663 openのデフォルトモードが異なる。
std::fstreamはstd::ios::in及びstd::ios::out
std::ofstreamはstd::ios::outのみ
あーでもstd::fstreamはstd::istreamとstd::ostreamを継承しているけど std::ofstreamはstd::ostreamしか継承してないから、std::ofstreamに >>なんか適用しようとするとエラーが出るかも知れない。試してないけど。
>664-665 為になる情報を有難うございます。 非常に参考になりました。
わからないので教えてください AをベースにB、Cを継承してクラスを作り A *hoge; で、hogeにBまたはCのポインタを持たせた場合 hogeが保持しているクラス型を特定することはできますか? クラスBなら1、クラスCなら2などと応答するメンバ関数を作らないとだめですか?
typeid().name()を使ってもだめだったー
>>667 何をしたいのかがわからん。
特定するだけならtypeid()でいいんじゃないの?
>>667 わかりました。基底クラスのAが一つでも仮想関数を持っていれば、
typeid(*hoge).name()で実際の型がわかります。
もしAが仮想関数を持っていなければ、typeid()の結果は常にAに
なります。
おおお、できましたありがとうございました! こんな演算子があったなんて・・・
672 :
デフォルトの名無しさん :03/02/13 02:17
標準入力を標準出力に流すだけのプログラムを↓のように書きました。 #include <iostream> main(){ std::cin.tie(0); std::cout << std::cin.rdbuf(); } cygwinのgcc3.2で実行すると、1文字でも入力すると無限ループに陥ってしまいます。 なにかまちがってるんでしょうか?
超高速事故解決しました。 std::ios_base::sync_with_stdio(false);
ifstreamの内容をstringstreamに読み込んで、複数回読み取りを 行おうとしましたがうまくいきません。どこがおかしいのでしょうか。 int main() { std::ifstream ifs("stringstream1.cpp"); std::stringstream str; char ch; str << ifs.rdbuf(); str >> std::noskipws; while (str >> ch) std::cout << ch; str.seekg(0, std::ios::beg); while (str >> ch) std::cout << ch; // だめぽ・・・ }
674です。自己解決しました。 strにeofbitが立っていたのが原因でした。clear()をかませると うまく動作しました。 int main() { std::ifstream ifs("stringstream1.cpp"); std::stringstream str; char ch; str << ifs.rdbuf(); str >> std::noskipws; while (str >> ch) std::cout << ch; str.clear(); str.seekg(0, std::ios::beg); while (str >> ch) std::cout << ch; }
自己解決ブーム
>>672 >>673 MinGW3.2.2だとsync_with_stdio(false);がなくてもハングしないよ。
環境に依存する問題なのかな。
678 :
デフォルトの名無しさん :03/02/13 15:35
なんでfstream系にファイルサイズ返すメソッド無いの?
>>678 それは俺も悩んだ。ファイルサイズというもの自体が環境依存だから
らしい。
従来のようにバイナリでfopenしてfseek()とftell()を使って求めてる。
C++Primerには string f(){ string str; .... return str; } のようなコードが良く出てますが、これって無駄に文字列のコピーが行われますよね?
>>680 autoのstd::stringのリファレンスを返すと大変な事になるから。
682 :
デフォルトの名無しさん :03/02/13 17:09
ファイルがあってファイルサイズがないとはこれは随分矛盾した話だ
>>682 例えばUN*Xのようなシステムにおけるデバイスファイル(スペシャルファイル)
のようなものにはファイルサイズはないだろ。
デバイス、FIFO、ソケット、ディレクトリ、etc...を含めたファイルの種別
だの、そのファイルシステムにおける管理のされかたなんてものは
立派に環境依存だ。
そうか、C++は低水準言語だったな それじゃしかたない
>>680 g++3では、最適化を禁止してもコピーが抑制されるよ。
規格上オッケーなのかなあ?
\ │ / / ̄\ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ─( ゚ ∀ ゚ )< C++って超最高! \_/ \_________ / │ \ ∩ ∧ ∧ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄\∩ ∧ ∧ \( ゚∀゚)< 最高最高さいこ〜 超最高〜〜〜〜! >( ゚∀゚ )/ | / \__________ ________/ | 〈 | | / /\_」 / /\」  ̄ / /
int main() { return 0; }; //↑ これってなんかまずいですか?
690 :
デフォルトの名無しさん :03/02/13 22:41
691 :
デフォルトの名無しさん :03/02/13 22:49
>>689 ちがう。
戻り値をどっかで受けるときにコピーが発生するはず?だが
g++3はコピーせずに戻り値のところに直接生成する。
693 :
デフォルトの名無しさん :03/02/13 22:54
あんた!この携帯代どうすんの!? おかん払っといて おかん??!! プオーーーン あんた・・・本当はやったら出来る子やのに・・・(涙
>>686 RVO( Return Value Optimization ) で検索しる。
697 :
デフォルトの名無しさん :03/02/14 00:46
>>688 } のあとの ; はいらない。
それ以外は別に何も。
698 :
デフォルトの名無しさん :03/02/14 03:30
初心者質問ですが、一般に、例外を投入して、 catch ブロックにぶっ飛んだ後、問題を処理して 元のtryブロックのコード(の次)に戻りたいときは どうしたら良いのですか? 投入する構造体に、細かいデータを与えておけば 可能でしょうけど、例えばMFCのCFileException には そんなデータは入ってないみたいだし、そういう動作は 想定していないのでしょうか?
701 :
デフォルトの名無しさん :03/02/14 03:55
>>699 ありがとうございます。
ややこしくなるから、実装しなかったということですか。
>>700 例外を投入する可能性のある関数ごとに、執拗に1つずつ
try - catchで囲っていくのって、なんかソースが冗長で美しく
なくなる気がするんですよね。そんなことないですかね?
標準関数に例外を投入する関数があるから、使わないわけ
にもいかないし・・・。
if(! foo()) { /* 失敗した時の処理 */ } と try{ bar(); } catch(,,,) { /* 失敗した時の処理 */ } の差をどう感じるか、かな。 失敗した時の処理が必要ないなら冗長に感じるのも分かるけどね。 マクロでも作ると楽かも? でも、そもそも例外ってのはすぐ復帰できるようなものには使わず、 そういう時は bool 値か何かを返すのが普通だと思うんだけど、 その関数はそういう仕様にはなってないのかな?
>>702 goto キタ━━━( ´∀`)・ω・) ゚Д゚)・∀・) ̄ー ̄)´_ゝ`)-_-)=゚ω゚)ノ━━━!!!!
たかが goto でそんなに嬉しい?
たかが goto 。 されど goto 。
>>702 goto ってやっぱり最後の手段じゃないかなぁと。
ただcatchから戻るのは goto しかないですね。
おそらく戻る必要のないようにエラー処理をするのが
正しい書き方なのでしょうが。
>>703 自分が想定していたのはMFCのCFileです。
ファイルが存在しないときに、CFileExceptionを
投入するんですが。
直接、CFile でファイルを開こうとすると、file not found で
例外投入の可能性があるし、CFindFile でファイルを
検索してからだと、CFileにcatchブロック書くのが不必要な気がするし。
まあ、堅牢なソースには良いのでしょうが、個人用にちょこちょこ
と作ったアプリだと、その辺が面倒に感じてしまう・・。
>>707 gotoに必要以上に敏感になる必要はない。
適切に使われてる限り何の問題もないどころか、
ラベルを適切な名前にすることでソースの可読性を上げることができる。
そういうところで意地んなってdo/whileとか使ってると余計わけわかなコードになる。
>>709 まぁ概ね同意だけど、
catch から goto で戻るというのはあかんかと(w
try ブロック内のオブジェクトのデストラクタが全部呼ばれてるというのに
戻っちゃまずいっしょ。
>>708 直接 CFile のコンストラクタで開こうとせず、
CFile::Open を使って開こうとすれば
第3引数を指定することで例外を投げないようにできます。
711 :
デフォルトの名無しさん :03/02/14 09:40
基礎クラス(仮想メソッドがあって、new出来ないヤシ)って、 名称にbaseとか入れたりします?
仮想メソッドがあってnew出来ないヤシって 何のことかと思ったがpure virtualのことか
713 :
デフォルトの名無しさん :03/02/14 09:50
質問させてください。C6Entです。 タスクトレイ(時計が表示されている所です)にあるアイコンの ToolTipTextを取得する為にはどうすればよろしいでしょうか? やりたい事は・・・ あるアプリ(他人のアプリ)がありタスクトレイのアイコンのToolTipTextに記 載されている文字が「pp」と「ss」とあったとします。そして「pp」であれば 何もしない。「ss」であればそのアプリを強制的に終了させる。 という動作を行いたいと思っています。 よき方法をお教え下さい。お願いします。
MFCスレへ逝け
>>711 まあ名前付け規則は趣味の問題って感じだが。
漏れは付けない。
通常、そのベースクラスが外から使うインターフェイスになることが多いので、
一般的な名前にする。
716 :
デフォルトの名無しさん :03/02/14 10:38
>>715 じゃ、他の方法、例えば、ファイル名とかでベースクラスって分かるようにするの?
C言語な人が多い環境でベースクラスを普通にCVSしといても無視されるかゴミ扱いされる悪寒。
>>715 そうやね。漏れも同じ。
Stream ← StreamFile, StreamXXX
特殊化(派生)するならこんな具合につける。
718 :
デフォルトの名無しさん :03/02/14 11:04
>Stream ← StreamFile, StreamXXX これも逆もあったりするね。 某だと、 TStream ← TFileStream TSocketStream とか。 順番どっちが良いよ。 それから、Streamにプリフィックスも無し?
>>718 クラス名をアルファベット順に並べたときのすっきり感と
基本:派生:派生…のほうが意味が(漏れには)わかりやすいので
そうしているけど、それぞれ個人の好みでしょうなぁ。
>それから、Streamにプリフィックスも無し?
あれは例なので、クラス名が衝突しそうなら紛らわしいので
ひねって別名を考えています。
うーん。prefix が必要なケースもありますかな?
経験不足なせいか、漏れはあまり使った記憶はないのですが。
baseが外部に隠された実装詳細でしか無いのであればbaseつきだろうが そうでなかろうがどうでもいい気がするが、baseが外部に公開されており しかもそれが一般的にインタフェースとして利用されることを期待している 場合は、baseなんて付いていないほうがいいと思うけどね。 "base"ってのは要は実装で、そのクラスの概念とは全く関係の無いものだろ。 そういうのを思わず外に漏らしてしまうような名前の付け方ってのは、 俺はあんまり好きじゃない。 # とは云えそれが用いているデザインパターンを明らかにするために # FacadeやFactoryといった名前を付けることは多いし一般的なんだよな。。 # プログラマにとっては分かりやすいとも云えるし。しかしオブジェクト指向の # 本質からいって、クラスの名前はそのクラスの概念を表すのが本筋だと # 思う。
>>719 別名を考えるのは面倒
名前の衝突を恐れずに namespace で分けたほうがいいYO!
長くなるけど
TaroFoo TaroBar ッテクラスメイミルトメマイガ・・
722 :
デフォルトの名無しさん :03/02/14 11:43
>基本:派生:派生…のほうが意味が(漏れには)わかりやすいので これは納得。こちらが流行って欲しいけど、英語圏では違和感があるのかな。 ># とは云えそれが用いているデザインパターンを明らかにするために そう。 これをしたいんだけど、みんな、どーしてるのかなー、と思って。 名前に付けるのかファイルに付けるのか。(Javaだとこの点不自由だね)
723 :
デフォルトの名無しさん :03/02/14 13:59
#ifndef __cplusplus #error Must use C++ for STDCOMP.H #endif STDCOMP.Hに上のようなステートメントがあって、エラーになります。 STDCOMP.Hというのは、最初に自分で手直しして使うもんなんでしょうか?
725 :
デフォルトの名無しさん :03/02/14 14:12
まさにマルチとマルチのハーモニー。
727 :
デフォルトの名無しさん :03/02/14 16:01
コンストラクタの初期化リストは左から右に必ず実行されますか? C() :a_(0), b_(f(&a)) {} //f()呼び出しの前にaは必ず生成されている?
>>727 Exceptional C++のソースを見ると
保証はされていない印象。
>>727 初期化順序は、常に「宣言定義の登場順」。
class A {
int b_;
int c_;
A(): c_(0), b_(0) {}
};
ならば、b_が先に初期化される。
ちなみにまぎらわしいのでコンパイラによっては順序が違うと警告が出るよ。
>>727 コンストラクタの初期化順は「基底クラスの宣言順→メンバの宣言順」だ。
でも a_ を初期化しても a は初期化されていない罠。
そんなヤツはわらぶき屋根にすみません。
733 :
デフォルトの名無しさん :03/02/14 20:03
参考書の例題で、変数nに0→1→0→1を永久に繰り返させる例として int n; OnTimer(UINT nIDEvent) { n = (n + 1) % 2; としているのですが、int型変数nが計算過程で領域より大きい数字を扱うのは 問題ないのでしょうか?
int n = 0; n ^= 1; 俺ならこう書くが。
俺は n = !n; 派
BASIC時代は N=1-N をよく使った。 応用もあって、3と5を交互に入れ替えるなら N=8-N とかもできる。
n=(a+b)-n か。いいね。 n=(a^b)^n でもいけるかな。
739 :
デフォルトの名無しさん :03/02/14 21:05
souka!!
740 :
デフォルトの名無しさん :03/02/14 21:05
プププ
>>636-638 637に一票。
使って欲しくないコンストラクタはprivateにするとかFactoryパターンを使うとか。
暗黙の呼び出しは…、使わない。明示的な変換関数を用意する。
ちなみにデストラクタでも例外は投げないようにするため、
後始末はデストラクタ実行前にやっておく。
それが行われたかどうかをデバッグ時に確認(assert)するだけ。
>>741 コンストラクタから例外投げないように細工するってこと?
例外処理が問題なく動作する環境でもそうするの?
それは勘弁してほしいなぁ。
743 :
デフォルトの名無しさん :03/02/15 07:57
C/C++って2進数表記が使えないのはなんでだろう? 32bitくらいまでだと、2進数表記でも 冗長うにならずに、かえって分かりやすいと 思うんだが。
>>743 漏れもわからん
ANSI-ISO標準化のときに取り入れてもよかったと思うけど
要望が少なかった(8,16進で表現できる)から?
2進数表記のためにわざわざパーサ組むのも面倒くさいな
それよりも、ビットローテートがないのが悲しい。
746 :
デフォルトの名無しさん :03/02/15 13:11
下のようなコードでimage1,image2がクラスoneのオブジェクトで image1->v = 100;image2->v = 200; であるとしたとき、base1,base2とも200になるのはなぜ? base1には100をbase2には200入れたいのだけど、 どうしたらよいでしょう? setで定義されたjに上書きしてるようなのですが・・・。 int* one::set(){ int j; j = v; return &j; } int *base1, *base2; base1 = image1->set(); base2 = image2->set();
int j; のところは static int j;
class one { int* v; public: int* set(); }; int* one::set(){ return &v; } じゃ駄目?
すまそ、int* v; → int v;
>>748 コードを簡略化してたのですが、
int jのところは構造体で
構造体にクラスの変数の値を入れて構造体を返すようにしたいです。
それなら struct Hoge {}; class { Hoge hoge; int v; ...}; Hoge* one::set() { //いろいろ return &hoge; } でいいのではないかな
ていうかこの人、基礎知識の部分でヤバイ気がしますが
一週間前に初めてクラス使ったので、スマンね。
クラスの中に構造体を定義して今まで作ったコードを書き直すのが面倒くさいから やりたくない。てっとりばやくコードを書き直して base1には100をbase2には200入れたいというだけ。 static使ってるからだと分かってるけど、 使わないと構造体のポインタを返しても、構造体のインスタンスがなくなるから しょうがなく使おうとしてるけど、別の方法が無いか聞いてるだけ。
むしろきちんと書き直さないと余計はまりそうな つーか、てっとりばやくってんなら、staticではなくローカル変数にして アドレスではなく実体を返すのが問題少なくていいんじゃないすかね。
>>755 本に構造体はポインタで返すとか書いてたから
わざわざポインタでやってたんだけど、
変数でも返せる?
一番手っ取り早いと思うのだけどな。どう面倒くさくなるのだろう。 ポインタでなくても、構造体のサイズがそんなにデカくないなら 値返しでもいいと思うけど。
>>754 OOPを学習・理解して書き直したほうが
貴方にとって長期的な利益につながると思われ
>>757 メンバを構造体に入れてメンバ変数を放っておくと
100万要素の配列3つが倍になって無理。
だから元のメンバ変数を削除しないといけないけど、
クラスの全部の変数に構造体のstruct.をつけるのは面倒でいやということ。
>>758 ○○Pって何?
知っといた方がいいものなら、知っておきたいけど。
>>746 君、もしかして new を知らないだけでは?
>>759 どういう構造を表現しようとしてるのかよくわからんや。
ともかく
OOPってのはObject Oriented Programming, オブジェクト指向プログラミングってこと
VisualC++.netのインストールに1時間40分もかかるとは思っていなかった。 それ以前にVisualC++.netにあんなに金がかかるとは思っていなかった。
>>760 newは他の部分では使いまくってるけど、
newを使ってクラスの中で配列を定義しようとしたら、
エラーになるから使えないと思ってた。
クラス定義の中でnew使える?
>>761 クラスの定義は次の通り。
class one_image
{
protected:
// メンバ変数
int HSize, VSize; // 画像の横サイズ、縦サイズ
u_char red[4000*2000];
u_char green[4000*2000];
u_char blue[4000*2000];
int base_x, base_y; // 基準点の座標
int corner_x[4], corner_y[4]; // 角の4点の座標
double edge_inclination[4], edge_interception[4]; // 縁の4辺の傾き、切片
int num_pixel; // 横サイズ×縦サイズ
public:
メンバ関数が5〜6個ある
};
764 :
デフォルトの名無しさん :03/02/15 14:52
class A {}; // ←ほんとはもっと複雑。 A foo() { return A(); } ってのがあるとき、 void var() { A a = foo(); } ってやったら、クラスAのインスタンスを返すことができました。 クラスAのコピーコンストラクタが起動しなかったし、 また a の寿命がつきる時に foo()の返したオブジェクトも死にました。 なんかめちゃめちゃ不思議で便利な振る舞いだな、って思ったのですが、 これってVC++特有の振る舞いなのでしょうか?
void one::set(Hoge*) の形にするとか。
766 :
デフォルトの名無しさん :03/02/15 14:56
>>763 JAVAとかやってました?
class A {
char* buf2 = new char[10]; // エラー。
char* buf2; // ポインタだけ宣言しといて
A() { // コンストラクタで確保。
buf2 = new char[10];
}
};
>>765 最初はそのような形にしてたけど、それだと
構造体Hogeの初期化をしないとエラーが出るし、
かといって初期化するのは面倒だから、先のような形にしたというわけ。
>>766 言語はCしか知らないからJAVAは分からないけど、
コンストラクタで定義するという手があったわけね。
どうも。
>>767 わかってるとは思うけど、Javaの場合は開放が不要だけど
C++ではデストラクタで開放も必要ね
>>764 それはまっとうなC++コンパイラならどれもやってること。
A foo() {
return A();
}
という関数 foo() を呼び出すとき、コンパイラはスタックとかに
戻値用の領域を確保してそのアドレスを foo() に渡している。
foo() は return のときにそのアドレスにオブジェクトを構築する。
んで、 A a = foo(); のような呼び出しの場合は、作ろうとしているオブジェクト a の アドレスが直接 foo() に渡されるから、一時オブジェクトが作られる こともない。非常に効率的。
A foo() { A a; ... return a; } だとコピーになるかというと。
今日ナンバーズ諸々を1800円分買っちまった 17日はまだか?
More Effective C++ 項目20:戻り値最適化の促進 あたりは参考になると思われますです。ハイ。
クラスに関数 f() を追加する テンプレートを作りたいので以下のようなコードを書きました。 template < class T > class foo : public T { public: foo() : T() { } void f() { } }; しかし、これだとTの引数なしコンストラクタしか呼び出せません。 基底クラスのpublicなコンストラクタ全てをpublicで継承させるにはどうしたらよいのでしょうか。
f() を持ったクラスを作って、それを継承させたらあかんのん?
>>763 const auto_ptrを勉強してくれ・・・
そのクラスは、余りにも酷すぎる。
>>763 やっぱりC++から勉強すべきだったね。残念だ。
780 :
デフォルトの名無しさん :03/02/15 19:56
>>777 auto_ptrを勉強すると、763のコードはどうなるの?
ぼくは、 763 のクラスは、
class pixel {
u_char red, green, blue;
}
とか
class point {
int x,y;
}
とかってクラスをつくって、
one_image内部でそれを使用するようにして定義しなおすだけで、
別に見にくくもなくなるような気がする。
>>780 で、std::vector<pixel>で保持、だよね。
num_pixelは不要(vectorのsize()で分かる)
C挫折したのでC++を勉強します
てーか、漏れと同じじゃん。
えっとぉ、JavaとC++は同じなんですよね? Javaの質問にも答えてくれますか?
787 :
デフォルトの名無しさん :03/02/15 22:04
try { //.... } catch ( ... ) { } catch (std::exception& e) { } catch (std::bad_cast) { } スウトラウスストラップが、上記のコードでは 2番目と3番目のcatchブロックは決して 実行されないって書いているんだけど本当? (C++3版 p427) exceptionの派生クラス bad_cast が投入された ときには、3つともすべてのcatchブロックが実行 されるんじゃないの? 後者2つのcatchブロックで、それぞれ基底クラス と派生クラス、双方の例外処理を行いたい場合は どうしたら良いんですか?
788 :
デフォルトの名無しさん :03/02/15 22:06
じじぃの言うことに嘘はない
789 :
デフォルトの名無しさん :03/02/15 22:10
ま、嘘はないんだろうけど、^^; 派生クラス部分のメンバ変数の修復処理と、基底クラス部分のメンバ 変数の修復処理を別々のcatchブロックでやりたい場合は、一般的に どうしてるのかなと思いまして。
再throw
791 :
デフォルトの名無しさん :03/02/15 22:24
再throwするには、try がネスト構造になってないと ダメですよね。そう言う風に設計しるってことですか。
792 :
デフォルトの名無しさん :03/02/15 22:55
質問です。 #include <iostream> using namespace std; class j { public: int a; int & operator*() { cout << "[*()]"; return a; } int * operator->() { cout << "[->()]"; return &(operator*()); } }; void main() { j i; i.a = 100; cout << "@ i = " << *i << endl; j *p = new j(); p->a = 101; cout << "@ p = " << **p << endl; } のとき operator->() を呼出すにはどうしたらよいでしょうか。
(*p)->
795 :
デフォルトの名無しさん :03/02/15 23:09
>>793 ありがとうございます。
cout << "@ (*p)-> = " << (*p)-> << endl;
を付け加えたところコンパイルで
g++ j.cc -o j
j.cc: In function `int main(...)':
j.cc:40: parse error before `<'
となってしまいます。
なにかまずいところがありますでしょうか。
796 :
デフォルトの名無しさん :03/02/15 23:18
.
797 :
792です。 ◆ZtXjKqCmiQ :03/02/15 23:20
792です。 #include <iostream> using namespace std; class j { public: int a; int & operator*() { cout << "[*(j)]"; return a; } int * operator->() { cout << "[->(j)]"; return &(operator*()); } }; class d { public: j a; j & operator*() { cout << "[*(d)]"; return a; } j * operator->() { cout << "[->(d)]"; return &(operator*()); } }; void main() { d *n = new d(); n->a.a = 102; cout << "@ (*n)-> = " << (*n)->a << endl; } としたところ @ (*n)-> = [->(d)][*(d)]102 となり class d の -> は呼ばれましたが class j の -> を呼ぶ方法はないのでしょうか。
i.operator->(); p->operator->();
>>797 -> の結果が構造体(クラス)へのポインタじゃない場合、表記しようがない気が
801 :
792です。 ◆ZtXjKqCmiQ :03/02/15 23:27
>>798 すばらしい。ありがとうございました。
今夜は寝られそうです。
>>799 そうかもしれません。
802 :
デフォルトの名無しさん :03/02/16 00:35
class File_ptr { FILE* p; public: operator FILE*() { return p;} }; (C++3版 p428) このオペレータの意味がわかりません。 なんか戻り値ないのに、return p してるし。 これを呼び出すには、どうしたらいいのですうか? あるいは、これが呼び出されるのは、どういう場合ですか?
File_ptr fptr; FILE* p = fptr; // <- ここ
>>802 (FILE*) にキャスト汁!のときでは?
805 :
デフォルトの名無しさん :03/02/16 01:14
>>803-804 ありがとうございます。
なるほど、キャストですか。
p328 に解説がありました。
>>789 >>787 のコードでは、
> 派生クラス部分のメンバ変数の修復処理と、基底クラス部分のメンバ
> 変数の修復処理を別々のcatchブロックでやりたい
ということが見えないんだけど。もうちょっとわかりやすい例を書いてよ。
807 :
デフォルトの名無しさん :03/02/16 20:06
万策尽きました。何方かアドバイスお願いします。 以下のようなコードで無限ループになてしまって、しかもファイルの中味はちゃんとあるのにbufの内容がなにも表示されない場合どのような原因が考えられるでしょうか。(in は ifstream* in となってます) char buf[256]; if (!in->is_open()) exit(1); // ここでは終了しないのでファイルは開けてる while (!in->eof()) { in->getline(buf, sizeof(buf)); cout << "[loop] " << buf << endl; } 開発環境は以下の通りです。 $ gcc -v /usr/lib/gcc-lib/i386-redhat-linux/3.2/specs から spec を読み込み中 コンフィグオプション: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --host=i386-redhat-linux --with-system-zlib --enable-__cxa_atexit スレッドモデル: posix gcc バージョン 3.2 20020903 (Red Hat Linux 8.0 3.2-7)
>>807 そのコードで、eofbitがセットされる前にfailbitがセットされると、無限ループする。
810 :
デフォルトの名無しさん :03/02/16 21:47
スマートポインタの実装時に、配列かそうでないかで、 例えば boost なら shared_ptr と shared_array に分けていますが、 配列でないポインタを new hoge[1] して、配列として管理することの 問題点はなんですか?
delete と delete[] を間違えちゃぁいけねぇ。
>>807 もう一つ。eofbitが立つのは、getline()を実行してみてからでないとわからない。
だから
while (true) {
in->getline(buf, sizeof(buf));
if (!in) break;
cout << "[loop] " << buf << endl;
}
と書かないとね。
813 :
デフォルトの名無しさん :03/02/16 23:55
windowsに標準で付いているサウンドレコーダーのように マイクから音声を取り込んでる最中にその音量を表示したいのですが、 どのようにしたらいいか分かりません。 waveIn系のAPIを使って調べるしかないのでしょうか? どなたか分かる方よろしくお願いします。
>812 >in->getline(buf, sizeof(buf)); >if (!in) break; 無限ループか、coreの予感
>>813 ここで聞いても無駄だから、素直にWin32APIスレとかに逝け。
>>814 スマソ。
if (!*in) break;
だった。これでもダメか?
failbitとeofbitって共存可能だろ?
>>815 スレ違いでごめんなさい
そっち逝ってきます
>>817 別々なフラグだから、メンバ関数eof()とfail()で調べられる。
しかしeofbitが立つ時は同時にfailbitも立つから、普通は
operator void*()で調べてる。
正否の判定が operator bool() でなく operator void*() なのは どうしてだらう。
まあそれは色々と事情が在るんだよ・・・
ぶーるだとたちざんとかできちまうってこった
bool→intの格上げを規格に入れたのはなぜだ? void*→int*は禁止したくせに。
>>811 ごめんなさい。たぶん説明がたりなかったかも。
前提として new と delete がクラス内で閉じてるってのがありました。
ユーザーが勝手に delete するのまで考慮するのならともかく、
new と delete がクラス内で完結するのなら、
全部配列でもいいんじゃないかと思ったわけです。
ただ、そういう実装を見たことがないので、ちょっと聞いてみただけです。
Loki のスマートポインタも、boost の様に配列かそうでないかで
使い分けるのも、面倒くさいのです。
825 :
デフォルトの名無しさん :03/02/17 01:07
分かった! こいつはとんでもない勘違いしてたぜ!! ひゃっほう!!
なんとなく分かったような分からないような。。operator void*() が 呼び出されるようなコンテキストで、ifstream が + や - の被演算数 になる状況って実際のところあるのでしょうか。
浮動小数型の扱いについてですが、 float型で変数定義して、ループ使って0.001×1000したら 1にはならないわけですが、この理由を説明せよ って問題です。 どう説明すればイイでしょうか?
>>827 小数点以下の数の扱いについて、IEEEの資料を嫁。
>>827 0.001は2進数では循環小数になるから。これでいいか?
>>824 だからって全部配列にするのはエレガントさに欠けるだろ。
>>830 それ、本当?
1E-3 になるような気がするんだが。
1e-3の何処が二進表現なのかと
835 :
デフォルトの名無しさん :03/02/17 13:37
const の アドレスを返す関数があった場合, そのアドレスはどうやって保持すればいいのでしょうか?
どういうこと?
837 :
デフォルトの名無しさん :03/02/17 15:48
すみません質問です C言語の最高の可能性って何処まであるんですか?
無限に努力すれば無限の可能性が秘められています。
839 :
デフォルトの名無しさん :03/02/17 16:01
質問です。よろしくお願いします。 二つ目のtemplate関数は通るのにどうして三つ目のtemplate関数は テンプレート関数はすでに定義されています というコンパイルエラーが出るのでしょうか?コンパイラは VC++6 Sp.5 + STLport です template <typename VectorType> void print(std::vector<std::vector<VectorType> >& obj) { for ( unsigned long i=0; i<obj.size(); ++i ) { for ( unsigned long j=0; j<obj[i].size(); ++i ) { cout << obj[i][j] << ","; } } } template <typename ListType> void print(std::list<std::list<ListType> >& obj) { for ( std::list<ListType>::iterator lit1=obj.begin(); lit1!=obj.end(); ++lit1 ) { for ( std::list<ListType>::iterator lit2=lit1->begin(); lit2!=lit1->end(); ++lit2 ) { cout << *lit2 << ","; } } } template <typename ListType> void print(std::vector<std::list<ListType> >& obj) { for ( unsigned long i=0; i<obj.size(); ++i ) { for ( std::list<ListType>::iterator lit=obj[i].begin(); lit!=obj[i].end(); ++lit ) { cout << *lit << ","; } } }
>>839 template <typename ListType>
void print(std::list<std::list<ListType> >& obj) {
for ( std::list<std::list<ListType> >::iterator lit1=obj.begin(); lit1!=obj.end(); ++lit1 ) {
for ( std::list<ListType>::iterator lit2=lit1->begin(); lit2!=lit1->end(); ++lit2 ) {
std::cout << *lit2 << ",";
}
}
}
>840 すいません typo です。 それでもエラーは消えません。 よろしくお願いします。
>>841 これでどうだ?
template <typename VectorType>
void print(std::vector<std::vector<VectorType> >& obj) {
for ( unsigned long i=0; i<obj.size(); ++i ) {
for ( unsigned long j=0; j<obj[i].size(); ++i ) {
std::cout << obj[i][j] << ",";
}
}
}
template <typename ListType>
void print(typename std::list<std::list<ListType> >& obj) {
for (typename std::list<std::list<ListType> >::iterator lit1=obj.begin(); lit1!=obj.end(); ++lit1 ) {
for (typename std::list<ListType>::iterator lit2=lit1->begin(); lit2!=lit1->end(); ++lit2 ) {
std::cout << *lit2 << ",";
}
}
}
template <typename ListType>
void print(std::vector<std::list<ListType> >& obj) {
for ( unsigned long i=0; i<obj.size(); ++i ) {
for (typename std::list<ListType>::iterator lit=obj[i].begin(); lit!=obj[i].end(); ++lit ) {
std::cout << *lit << ",";
}
}
}
若干修正。 template <typename ListType> void print(std::list<std::list<ListType> >& obj) { for (typename std::list<std::list<ListType> >::iterator lit1=obj.begin(); lit1!=obj.end(); ++lit1 ) { for (typename std::list<ListType>::iterator lit2=lit1->begin(); lit2!=lit1->end(); ++lit2 ) { std::cout << *lit2 << ","; } } }
禿の書いたSpecialEditionの日本語版はありますか?
>>839 一箇所 ++i ぢゃなく ++j だろとかしょーもないツッコミはおいといて
多分 VC++ 6 のバグ。ソース見た目どこも悪くない。
bcc5.5 と gcc-3.2.2 の両方で (修正後) 正しく実行できたよ。
C++なんて使うなあほ。
>>847 おい禿! 日本語分かるのなら日本語版もお前が書け!
ストラウストラップ先生の頭に油性マジックで 「ぬるぽ」って書いてみたい(;´Д`)ハァハァ
>842 がんばってもらってすいません。やっぱりコンパイルエラーです。 >845 了解しました。どうもありがとうございます。 >846 SP7探したんですけど見つかりませんでした。どこにあるんですか?
>>855 お前がその板に言った方がいいんじゃなくて?('-'*)
もう帰ってこないでくださいね。 迷惑ですんで。
>>857 なんでこいつはこんなに怒っているんだろう
iostreamをseekさせるマニュピレーターってある?
861 :
デフォルトの名無しさん :03/02/18 14:33
動的配列って、 intArray = new int[10]; delete [] intArray; みたいに書けますよね。 reallocみたいなこと出来ますか?
862 :
デフォルトの名無しさん :03/02/18 14:34
>>861 できないのでstd::vectorのほうが便利
863 :
デフォルトの名無しさん :03/02/18 14:37
thanx!
>>862 でも、内部に持つ予定の、計算ライブラリが、double配列しか受けてくれないし。
計算ライブラリに値を渡す前に、数も可変で。
で、配列であって、かつSTLみたくなって欲しいんですけど、
std::vectorって、もしかして配列として扱える?
864 :
デフォルトの名無しさん :03/02/18 15:01
逆に、C++でnew使わずに、alloc realloc使ってたら変?
変。
866 :
デフォルトの名無しさん :03/02/18 15:07
>>863 vectorは一般的な実装なら(vector<bool>以外)
先頭要素のアドレスを渡せば配列のように連続した並びとして使える。
ただし規格で保証されてない、実装依存の使い方になっちゃうけど。
867 :
デフォルトの名無しさん :03/02/18 15:09
規格で保証されてないんなら怖いな。 組み込み用目立コンパイラだし、STL完動か分からないし。
868 :
デフォルトの名無しさん :03/02/18 15:17
doubleのような基本型に限定して、malloc/reallocでやるのが無難かね それをラップしたクラス作るといいんかな。
869 :
デフォルトの名無しさん :03/02/18 15:20
ラップしたクラス希望。
自分で作れ。
std::vectorの内部表現が素の配列と互換性を持つことは標準の補遺で 保証されている。
なんだーそうなんだ。
>>871 じゃあ、std::vector使う。
>>872 明示的に呼び出すrealloc()と違い、std::vectorは突然サイズの拡張が
かかったりするから、ポインタではなくiteratorを呼び出して使う方がよい。
サイズが拡張すると、多分今まで指してたポインタは無効になる。
>>873 push_backしたり、insertしたり、resizeしなければサイズの拡張はないわけだが。
>>874 あ、そういう仕様なんだ。分かりやすいね。
参照や代入するときはポインタ。
データを追加や破棄するときなんかするときは、iteratorってことね。
>>875 代入する前にresizeしておく事を忘れずにね。
配列みたいな使い方したいんだったら。
ラジャー
>>876 STLのメソッドってresizeで統一されてるみたいだけど、
addとかdeleteとかで統一のんが格好良い。
もしかして、add/deleteもあります?
878 :
デフォルトの名無しさん :03/02/18 16:49
>>877 ない
push_backやeraseで統一
例えばこんな感じ。やっぱり使いやすいね。 int main() { std::vector<int> v(10); int* p; p = &v[0]; for (int i = 0; i < 10; i++, p++) { *p = i; } // v[10] = 1; // エラー v.resize(11); v[10] = 1; // OK for (std::vector<int>::iterator pos = v.begin(); pos != v.end(); ++pos) std::cout << *pos << std::endl; }
>>875 std::vectorの内容をポインタで扱うのはCで書かれたライブラリやAPIを
呼び出すときだけ。他の場合は常にメンバ関数もしくはiteratorを使え。
882 :
デフォルトの名無しさん :03/02/18 16:58
質問です そろそろC++の勉強しようかと思ってます。 どれくらいで身に付くでしょうか? ちなみにVB、Delphiは経験有ります。 kylixでXWindowのサーバーソフトを制作経験もあります。 DelphiやったことあるならC#の方がいいですかね? メモリ管理も容易そうだし。
884 :
デフォルトの名無しさん :03/02/18 17:01
>>882 で、お前はなんのためにC++の勉強がしたいんだ?
経験ありますってのはかじったってこと? その調子じゃ、どれも身につかないような気がするな
889 :
デフォルトの名無しさん :03/02/18 17:25
>>888 学生の頃、DOSのCならやったことあります。
890 :
デフォルトの名無しさん :03/02/18 17:27
>>882 やめとけ! そんな質問するようなバカには一生かかってもムリだ。
class foo { ... public: void f(); }; class bar : pblic foo { public: void f(int); }; となっている場合で、 bar c; c.f() でVC6では不正な引数個数エラーがでるんですがコンパイラがバカですか?
using
>>892 派生クラスで(引数違いでも)同じ名前のメンバ関数を定義した場合
自動的に親クラスのものはアクセスできなくなるよ。
>>893 が言うように、アクセスできるようにするには、usingを使う。
class bar: public foo
{
public:
using foo::f;
void f(it);
};
C++第3版「15.2.2 継承とユーザー宣言」参照
895 :
デフォルトの名無しさん :03/02/19 11:10
mainがC言語の場合、C++のエラー処理って便利ですか? C言語からcatch出来るのか、とか知りたいです。 BCBの場合、throw Exception("文字列");とか出来ますが、 標準では、throw exception;でエラー内容入らないんですよね?
> C言語からcatch出来るのか できない。 > 標準では、throw exception;でエラー内容入らないんですよね? std::type_info::name()で種類、std::exception::what()で内容を伝えることができる。
897 :
デフォルトの名無しさん :03/02/19 11:33
>> C言語からcatch出来るのか >できない。 てことは、mainはC++が良いわけだね。
898 :
デフォルトの名無しさん :03/02/19 11:35
>std::type_info::name()で種類、std::exception::what()で内容を伝えることができる。 throwのコード希望。
>>895 ふつー、 throw std::runtime_error("hogehoge");
グローバルインスタンスなどの初期化の為にmain()はC++でかくのが望ましい、 とC++3rdにあったような気がするが記述が見つからん。
901 :
デフォルトの名無しさん :03/02/19 12:49
902 :
デフォルトの名無しさん :03/02/19 12:56
pure virtual member を作らずに、抽象クラスを定義できますか? いまのところ 下の様に代用しています。 class A の foo を宣言するのが面倒なのです。 ちなみに A のインスタンスを持ちたい時は A を継承したクラスを定義しなさい A を継承する時は必ず B も同時に継承しなさい ってことを書いてみようと思います。 class A { private: virtual void foo() = 0; // ←邪魔な感じ }; class B { public: virtual void foo() = 0; } class AB : public A, B { public: virtual void foo(){} };
903 :
デフォルトの名無しさん :03/02/19 13:13
メソッドのインターフェースだけベースクラスに持たせる場合って、 virtualですよね。 でも、その中の実装しなくても良いですよ、っていうメソッドはどうするんでしたっけ。
>>902 根本から設計腐ってるんじゃないかって気がするが。
一応あるクラスのインスタンスを直接生成されることを防ぐだけなら
コンストラクタをprotectedにしておけばいい。
特定のクラスからしか継承されたくなければコンストラクタをprivateに
した上でfriendで継承していいクラスを指定。
>>903 virtual void foo() = 0;
>>905 何故かBorland C++ 5.02Jでは、
>エラー : Test.cpp(171,18):Class 'B' is abstract because of 'B::Comp() = 0'
となるよ。
>>906 = 0 は pure virtual functionで、実装しないといかんからね
実装しなくてもいいってのは作れない。
virtual void foo() {}
のように、空の実装を用意しておけばいいわけだが。
なるほど。 >virtual void foo() {} これはクラス宣言にも書けたような気がしたけど、 >virtual void foo() {}; だと、リンクで、 >致命的エラー: (1,1):Out of memory になっちゃう。
間違いでした。 >virtual void foo() {}; でコンパイル通りました。
>= 0 は pure virtual functionで、実装しないといかんからね >実装しなくてもいいってのは作れない。 「派生クラスで」という単語が抜けてるので完全に間違えているように見えるが
914 :
デフォルトの名無しさん :03/02/19 15:35
MFC の CHttpFile でRead(void * lpBuf, UINT nCount)関数を使おうと思ったのですが lpBuf のバッファの確保の仕方がわかりません。どうやったら確保できるのでしょうか。
どうしてあえてMFCスレを避けてマルチするんだろう
916 :
デフォルトの名無しさん :03/02/19 16:22
>>915 MFCな人が激減してるからでわ?
ところで、C++のmemset(&?, 0, sizeof(?))みたいなのは何がありますか?
次スレのテンプレを少し整理しました。現スレのテンプレに足りないと
思われるものがありましたら、
>>918-960 の間に貼り付けてください。
よろしくお願いします。
>>916 いや単に 0 を代入するだけならstd::fill_n()の方がいいな。
charのfillベンチ。やっぱりfill_nは効率が悪い。 memset = 34588 fill_n = 257876 intのfillベンチ。ほとんど差はない。 memset = 856209 fill_n = 843708
なにをあたりまえの事を・・・
922 :
デフォルトの名無しさん :03/02/19 22:15
何故intとcharでそんなに違うのか分からないので教えて下ちい。
>>922 CPUのアーキテクチャによっても違うと思うが、例えばPen4では
char型は1バイトずつfillするのに対し、int型は4バイトずつfillできる。
memset()は元々何バイトずつかfillするように最適化されていると
思うから、多分データ型によって変化するfill_nではcharは不利
だったのだと思う。
これと反対の現象が、qsort()とstd::sort()で起きていた。qsort()
はバイトコピーらしく、char型のsortでは差はなかったが、int
やdoubleではstd::sortに水をあけられていた。
もちろんこれらの事はすべて処理系依存であるから一般的
な事は全く言えない。あくまでもベンチマークを取った特定の
環境の下での話。
>922 まったく処理系依存だけれん >923にくわえて 奇数アドレスのアクセスは遅いよん。 前はアクセスすらできんかったが・・・ charだと奇数アドレスに触りますよん。
>>924 charなら偶数アドレスも奇数アドレスも変わらないのでは?
shortとかintとかなら遅いのはわかるけど。
>>924 処理系依存の話ね。
基本的にマシンワード単位でマシンワード境界に合わせてアクセスすれば
どの処理系でも速い。
簡略化していうと、CPUは常にマシンワード単位でメモリにアクセスするので、
それより小さい単位でのアクセスは変換作業が入る。
ずれてるときはまたがる2ワードに対するアクセスになる。
で、「前は」ってどこの話よ(笑)
バスエラーが起きるかどうかは製品ラインごとに異なるもの。
intel内だってx86とitaniumで違うしね。
>>925 いくらCコード中でcharでもレジスタはどうなん?
1BYTEのレジスタあるけど、厳密な意味で1BYTEとってんの?
int型のレジスタでとってマスクしてんじゃないの?
680x0系のCPUは奇数アドレスからワード以上を読み出そうと 例外が発生していた。 Cでポインタを使ったプログラムを書く時も特別な注意が必要 だったような。そんなCPUはまどろっこしくて使えないワ!
930 :
デフォルトの名無しさん :03/02/20 00:04
便乗質問ですが、 32bit系のCPUでQWORDだとDWORDより早い気がするのは何故? 気のせい?
>>930 32bit系って・・・386からPentium4の間でさえ10数年近くあるぞ
>>931 QWORDって出たのMMX以降でしたっけ?
早いのはパック命令のおかげですかな?汗やらんから・・・
>>928 境界に沿わないアクセス許してるCPUの方が少ないと思うんだが。
IA-32の場合でも、例外にはならなくとも遅くなるから普通は避ける。
>>930 Pentium以降のデータバスは64bit。
QWORDの方が早い(速い、だろ?)って意味がわからんが、
パック命令は1命令で複数回の演算を行うんだから、
専用に最適化すれば速くて当たり前。
レジスタ <-> メモリ間の転送速度も、別にパック演算命令
使わんでも64bit転送を使えるんならそっちの方が速い。
つか、思いっきりスレ違いだな。
934 :
デフォルトの名無しさん :03/02/20 11:10
クラスのメンバーにクラスを宣言すると、 メンバーのクラスの生成と破棄は自動で行われますか? delphiだと、コンストラクタとデストラクタで自分でやらなきゃならなかったんですが。
後、分からないのが、staticでクラス変数宣言出来るのでしょうか。 やっぱ、クラスのポインタの変数宣言しか無理なのかな。
>>934 まず質問する前にデバッガでコンストラクタとデストラクタの動きを追うがヨロシ。
staticなクラス変数は宣言できますが何か?
ごめんなさい。 コンパイルは両方出来ました。 後は、デバッガ。 というより、みんなどうしてんのかな。自分変なことしてないよな、を確認したかっただけです。
938 :
デフォルトの名無しさん :03/02/20 14:35
質問スレ31の981です。
こんな質問をしたら
981 名前 : デフォルトの名無しさん Mail : 投稿日 : 03/02/20 03:04
STLのvectorについて質問です。
fread()の様に配列にデータを流し込むタイプの関数からデータを受け取りたいのですが、
vector<char> vc[100];
fread(static_cast<void *>(&vc[0]), 100, 1, in );
こんな感じで &vc[0]をポインタにして受け取っていいのでしょうか。
983 名前 : デフォルトの名無しさん Mail : sage 投稿日 : 03/02/20 03:11
>>982 C++関連のスレいってログ嫁。
と言われてしまいました。
過去ログは一応探したつもりで、STLスレでfread()がらみの質問もあったのですが
それではきちんと整合が取れるか(size()を問い合わせたりしても正常に動くか)
までは言及されていないようでした。
ご存知の型、ご指導下さい。
>>938 >vector<char> vc[100];
vc(100)です、質問スレ982も私が書いたもので
この訂正をしてあります。
>>938 それは処理系依存なんでやらない方がよい。
begin〜endまでが連続したメモリー上にあるとは限らん。
素直に一時的なバッファを用意してやる方が吉。
Effective STL第2章参照
>>940-941 レスありがとうございます。
こんなテストのコード書いてみると
FILE *in = fopen("ファイル名", "rt");
int filesize = 0;
vector<char> vc;
vc.clear();
fseek( in, 0, SEEK_END );
filesize = ftell(in);
fseek( in, 0, SEEK_SET );
printf("vector size : %d\n", vc.size());
printf("vector capacity : %d\n\n", vc.capacity());
vc.reserve(filesize);
printf("vector size resized to %d\n\n", filesize);
printf("vector size : %d\n", vc.size());
printf("vector capacity : %d\n\n", vc.capacity());
printf("-- fread() -- \n\n");
fread(static_cast<void *>(&vc[0]), filesize, 1, in );
puts(&vc[0]);
printf("vector size : %d\n", vc.size());
printf("vector capacity : %d\n\n", vc.capacity());
結果 vector size : 0 vector capacity : 0 vector size resized to 366 vector size : 0 vector capacity : 366 -- fread() -- (略)、ファイルの中身が表示される vector size : 0 vector capacity : 366 のように、sizeは0のままで、いつか破綻しそうで気持ち悪いですので アドバイスのように自前でバッファを管理することにします。
>>942 >Effective STL第2章参照
レスありがとうございます。
以前立ち読みはしたのですが、stringの便利さについては異議なしですが、
vectorはまだ便利さが理解できません。
Effective STLを見たところ、vectorを渡す、
つまりvectorから例えばconst char *に渡すときには
&v[0]でいいよ、ということは分かるのですが、
vectorにたいして書き込みたいときはどうするの?
ってことは書いていなかったような気がします。
もし、fwrite()を使いたいのならこれでいいのですが。
stringではoperator =があるので、代入も簡単ですが。
>>943 reserve() ではなくて resize() でしょ。
int main()
{
int filesize = 100;
std::vector<char> vc;
vc.clear();
std::cout << "vector size : " << vc.size() << std::endl;
std::cout << "vector capacity : " << vc.capacity() << std::endl;
vc.resize(filesize);
std::cout << "vector size resized to " << filesize << std::endl;
std::cout << "vector size : " << vc.size() << std::endl;
std::cout << "vector capacity : " << vc.capacity() << std::endl;
}
ちなみに reserve() ってのは何かと言うと、std::vectorの要素数 を変更した場合は常にメモリの再割り当てが行われるわけでは ない。 STLの実装にもよるが、通常 capacity() 以上の size() にしようと すると、capacity() は size() の2倍のメモリを確保して再割り当て するものが多い。 つまりは効率のため。要素を一個 push_back() する度に再割り当て してたら遅くて仕方ないから、余裕を持ってメモリ確保されている 訳です。その確保されてるメモリを返すのが capacity()。
949 :
デフォルトの名無しさん :03/02/20 17:41
VC++ 6.0で分割コンパイルに挑戦したら 'class'で示される型として既に定義されてますと出てきますた。 --------------------- A.h class A { }; --------------------- A.cpp #include "A.h" --------------------- B.h #include "A.h" #include "C.h" class B : public A { C *a; }; --------------------- B.cpp #include "B.h" ---------------------
950 :
デフォルトの名無しさん :03/02/20 17:42
C.h #include "A.h" #include "B.h" class C : public A { B *a; }; --------------------- C.cpp #include "C.h" --------------------- MAIN.h #include "B.h" #include "C.h" --------------------- MAIN.cpp #include "MAIN.h" int main() { B *b; C *c; } --------------------- 雛形はこんな感じなんでつが、原因と解決法はいかがなもので? ソース、ヘッダ共に全部別ファイルでつ。 連続投稿スマソ
>>950 簡単に言うと、C.hはA.hとB.hをインクルードしているが、B.hもA.hを
インクルードしているので、class A の定義が2回されてしまうから
エラーが出る。
レスありがとうございます。
>>946 >P.74
確認してみます。
>>947 >reserve() ではなくて resize() でしょ。
そのようでした。
そこだけ直したところ
vector size : 0
vector capacity : 0
vector size resized to 366
vector size : 366
vector capacity : 512
-- fread() --
(略)
vector size : 366
vector capacity : 512
となり、すっきりしました。
>>948 >ちなみに reserve() ってのは何かと言うと
解説ありがとうございます。
STL標準講座のvectorメンバ関数表にはなぜかresize()がないけど
その後の解説にはreserve()とresize()がありました、見落としていたようです、済みません。
>>951 どーもです。
あの・・・インクルードガードって何でつか?(大恥)
>>952 どーもです。
その対処法が951氏が言ってるインクルードガードなんでつか?
>>954 例えば、A.hは
#ifndef CLASSA
class A {
};
#define CLASSA
#endif
としてやってご覧。こういうのをインクルードガードという。
956 :
デフォルトの名無しさん :03/02/20 18:21
俺 #pragma once が大好きなんだが、gccにobsolete とかいわれるので腹が立つ。ほっといてくれよ。
>>957 gccを再コンパイルすればいいじゃん。
それよりgccのワーニングを細かく抑制するほうほうが知りたい。
>>959 そんな荒いやつじゃなくて、VCみたいに番号で細かく指定したいんだが。
>>960 gccを再コンパイルすればいいじゃん。
つーかキリのいい番号取ったやつ次スレよろ。
「962番」はキリのいい番号だよな、みんな
次スレマダー?
966 :
デフォルトの名無しさん :03/02/27 15:18
Write a program that adds all values stored in the array val and displays the total. Modify the program to calculate and display the total of each row.
967 :
デフォルトの名無しさん :03/02/27 15:18
Write a program that specifies three one-dimensional arrays named price, quantity and total. each array should be capable to hold ten elements. using a for loop, input values for the price and amount arrays. The entries in the total array should be the product of the corresponding values of the price and quantity arrays. After all the data have been entered, display an output as a table in the following. total price quantity
価格、量および合計と命名される3つの一次元の配列を指定するプログラムを 書きます。各配列は10の要素を保持するのに有能に違いありません。 使用、1つの、ループ、価格に対する入力価値および量配列のために。 配列の合計中のエントリーは価格と量の配列の対応する値の製品であるべき です。 データがすべて入力された後、下記中のテーブルとして出力を表示してください。 価格量の合計
970 :
デフォルトの名無しさん :03/02/27 17:04
プログラミングを始めたんですが、わからないことがあるので教えてください。 開発環境:C++(VisualC++.NET)です。 #include <stdio.h> main() { printf("Hello!\n"); } このようなプログラムを作成して実行したところ、一瞬だけウィンドウが表示されるのですがすぐ消えます。 このあとに何を書き込めばとまるんでしょうか??
>>970 int i;
scanf("%d", &i);
973 :
デフォルトの名無しさん :03/02/28 00:33
>>970 >開発環境:C++(VisualC++.NET)です。
どこから見てもC++じゃないだろ
976 :
デフォルトの名無しさん :03/03/12 21:09
#include<cstdio> int main(){ std::printf("Hello!!\n"); return 0; }
VC++ にあるかどうか知らんけども getch() とか。 あちきは BCC だがこれよく使う。
>>970 はコマンドプロンプトを触ったことがないのとかと小一時間…
979 :
デフォルトの名無しさん :03/03/12 21:28
>>977 VC++にはgetch()はないから_getch()だろ。
_getch() か、そっちのが処理系依存ぽくていいな。
このスレはレベルが乱高下するな。
それにしても
>>970 はひどすぎる。