1 :
v(^・^)v :
04/08/09 11:30 C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
テンプレートライブラリ(STL含む)に関する質問は
専用の別スレにお願いッス。
過去スレ、関連スレ、関連リンクなどは
>>2-20 あたり
2 :
デフォルトの名無しさん :04/08/09 11:31
3 :
v(^・^)v :04/08/09 11:32
4 :
v(^・^)v :04/08/09 11:33
5 :
v(^・^)v :04/08/09 11:33
6 :
v(^・^)v :04/08/09 11:33
7 :
v(^・^)v :04/08/09 11:34
8 :
v(^・^)v :04/08/09 11:34
9 :
v(^・^)v :04/08/09 11:35
10 :
v(^・^)v :04/08/09 11:35
連続投稿規制に引っかかってむしゃくしゃしていた. スレが立てられるなら何でも良かった. 今はあらかじめ串を用意しておくべきだったと反省している.
11 :
v(^・^)v :04/08/09 11:35
STLつかうと一気に実行ファイルサイズが10倍に?!
12 :
v(^・^)v :04/08/09 11:36
>>11 環境によるだろ。
俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力
ランタイムを使用するようにして使っているが、例えばstd::vectorを
使っても使わない時と比べ10Kほどしか増えない。
13 :
v(^・^)v :04/08/09 11:36
>>12 すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。
14 :
v(^・^)v :04/08/09 11:38
C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。 とかいうエラーが出るんだけどこれってどうすればいいの?
15 :
v(^・^)v :04/08/09 11:38
>>14 #include <stdafx.h>
後死ね。
16 :
v(^・^)v :04/08/09 11:39
>>15 言葉が悪いな。それで教えているつもりか。
まぁヒントぐらいにはなったな。
うむごくろう。
17 :
デフォルトの名無しさん :04/08/09 11:39
これでテンプレは終わりかな。
18 :
デフォルトの名無しさん :04/08/09 11:40
イベントハンドラの記述に悪戦苦闘してます。 あるイベントに対応するハンドラを関数ポインタで設定しておき、 ウィンドウプロシージャからその関数ポインタを呼ぶようにしてます。 ですが関数ポインタは型に厳しくて、 typedef void (*EventProc)(CEvent&); これだとクラスのメンバ関数は突っ込めないし。 typedef void (CEvent::*EventProc)(CEvent&); こっちだとメンバ関数はOKだけど自分以外のクラスの関数ポインタはダメだし。 それに多重継承しているクラスのメンバは型が合わなくてコンパイルエラーになります。 何かよい解決策はありませんか?
20 :
デフォルトの名無しさん :04/08/09 11:44
class CMainWindow : public CWindow { CButton btn; public: void CMainWindow ::Init() { btn.pClickEvent = (CEvent::EventProc)OnClick; } void CMainWindow ::OnClick(CEvent& e) {} }; btn.pClickEvent = (CEvent::EventProc)OnClick; この部分は関数ポインタでは無理なんでしょうかね・・・。
#exclude <stdio.h>
staticにする
関数ポインタじゃなくて仮想関数呼び出しにしろ。
>>23 それも考えたんですがそれだとハンドラからメンバへのアクセスってコンテクスト経由ですよね。
もっといいアイデアがあるんではないかなーと思ってるんで今の所保留にしてます。
>>24 そうですね。仮想関数なら実装は簡単なんですよね。
でも派生しないとハンドラ書けないじゃないですか。
それにCButtonを派生してハンドラ書いてもはっきりいって不便ですよね?
ボタンのハンドラはやっぱりウィンドウに記述したいじゃないですか。ってわがままかなぁ。
>>26-27 あーテンプレートって手もあるんですねー。ちょっと見てきます。
ありがとう。
統合失調者が前スレ1000を取ったようだが乙
あー地鎮祭が既に終わっているー!!無念(藁
前スレ1000=29
それにしても2000円札っていまだに見ないね。
そりゃ、引き篭もってたらお目にかかる機会はないだろうな。
2000円札って2000年限定だっけ?
>>18 boost::functionとboost::bind、boost::lambdaのあたりを使う
boost.signalsも手か。
2000円札ってプレミア付いてる?
スレッドセーフなコンテナってどうやって実装するべきなんでしょうか? struct A{ A(const A& a) { lock(); assign(a); unlock(); } ~A() { lock(); release(); unlock(); } }; たとえば上のようにした場合、タイミングによっては破棄されたコンテナを コピーしようとしてしまう事がありますよね? コンテナが保持するオブジェクトへのアクセスのみロックで保護して、 コンテナ自体へのアクセスのロックは利用側が気をつけるしかないんでしょうか?
コンテナかどうかは関係ないかと。 通常のスレッドセーフ対策と同じ。
41 :
デフォルトの名無しさん :04/08/09 17:19
age
>>40 そういわれても分からないから質問してるんです。
通常っていうと、保護したいオブジェクトにアクセスする前後で
lockとunlockをするというだけだと思うのですが、
それはオブジェクトを利用するクライアント側でコードを書かなきゃならないので
言ってしまえば面倒であると言う事なのですが。
STLPORTとかで提供されるスレッドセーフなコンテナと言うようなものは、
コンテナへのアクセス自体は自分で保護しないとならないのでしょうか?
>>42 >そういわれても分からないから質問してるんです。
逆ギレ キター。
>通常っていうと、保護したいオブジェクトにアクセスする前後で
>lockとunlockをするというだけだと思うのですが、
そのとおりです。必要な場所でロックするように実装すればOK。
>>42 それはスレッドセーフというよりも寿命管理の問題じゃないの?
>>39 のコードだと「タイミングによっては」完全に破棄された後でコピーされてしまう
ことがあるわけだけれども、それはスレッドの問題ではなく、寿命管理が全くできていない
からだと思うし。
参照カウンタを儲けてアトミックに操作するとか、そういう普通の方法でよいと思うけど。
参照カウンタは関係ないな デストラクタに入った直後にコピーコンストラクタが呼び出されると、 カウント0のオブジェクトをコピーしようとする事になるから
>>45 コピーコンストラクタを呼び出す側が参照を保持してるから、
ゼロにならないと思うけど・・・
どういう状況を想定してまつか?
>>46 は「参照がゼロにならないから、そもそもデストラクトされない」って意味でした。
参照カウンタによる寿命管理って普通そういうものですよね。
強制的に delete したりしたらどうしようもないけど。
private: void assign(const A& a) {p=a;++p->c;} void release() {if(--p->c){delete p;p=9;}} struct counter {int c;} *p; }; 39の例だと、こうした場合には (スレッド) 処理 // コメント (0) A::~A() (0) A::lock() (1) A::A(const A&) (1) A::lock() (0) A::release() //p->c=0, p=0 (0) A::unlock() (1) A::assign() // error ということになる。 ・・・と思ったけど、Aのインスタンスをカウンタで管理すると言う事かな?
/p=a/p=a.p/ /p=9/p=0/
50 :
デフォルトの名無しさん :04/08/09 19:58
>>48 >・・・と思ったけど、Aのインスタンスをカウンタで管理すると言う事かな
そういうことです。
「コンテナの寿命管理」なんて設計段階でやっておけば十分なような気も
しますけど、元々のネタ(
>>39 )がそういうお題なのでしようがない。
++ とか -- はスレッドセーフじゃないのでOS 固有の何らかのAPIで
アトミックに実行する必要がありますが。
そこで boost::shared_ptr ですよ。
>>53 スレッド周りの対応が山盛りでおなかいっぱい。
>>54 調べてみた。
boost:shared_ptr は、同一のインスタンスについては、多重の読み込みしかスレッドセーフではない。
スレッド毎にコピーを作ってあげれば、参照カウントは共有され、かつ変更に対しても安全になる。
このスレはセーフですか?
レスごとにスレを分割すればOKです
初心者でもうしわけないのですがやっぱりC++とC#を将来使いこなしたいのであれば、 C言語を勉強する必要があるのでしょうか?
見たんだけれどC++でできる事はほとんどC言語でできるっぽいってのはわかったんだけれど、 C#ってのはどうなんかと思って。 C++とC#を将来使いこなしたい ってのをCC#を将来使いこなしたい にしとけばよかった。スマソ ほかのスレでC++は得意だけれどC#は苦手とかC#はいけるがC++はダメポとか いうレスみたんで。。 得意な方からいわせるとやはりC++とC#は違うのですかね? 違うと言うことになればいきなりC#から勉強できるのかな??
>C++でできる事はほとんどC言語でできるっぽいってのはわかった こんな奴がC#やっても時間の無駄
>>62 ならC言語だけでデザインパターン23種類全部書いてみい。
俺なんかもっとすごいこと知ってるぞ!!! C++でできることも、C#でできることも、Javaでできることも、 みーんなアセンブラ使っても出来るんだぞ!!!!!!! インターネットもリナックスもみんなアセンブラしてるんだぞ!! 友達のスーパーハッカーもアセンブラだって言ってたぞ!!!!
嬉々として書くほどは面白くないよ。
>>63 すみません。今日が初めての日なんで・・・
夜からずっとやってますが根性だけはあるんでアドバイスお願いいたします。ペコ
C# < C++ < C
C → C++ → C# ありがとうございますです。ペコ 調べ直していろいろさらに分かり、思ったのですが、Cはもう古いそうなんで 思い切ってC++から勉強したいと思います。 C++やっているみなさんから言いマストやはりそれは無謀でしょうかね? ちなみに今高校1年生ですので難しい数学はやったことないレベルであります。汗。
カキコ修正でごんす。 CがわからんとC++ほとんどわからんらしいっす。 いままでスマソ
数学云々より向いてるか向いてないかの問題 そしてなんでもかんでもすぐ人に聞く奴は向いてない
>>71 >そしてなんでもかんでもすぐ人に聞く奴は向いてない
禿堂
>>72 いや全く。
とりあえず手元にPCはあるようですから、実際に動かしつつ勉強すればいいですな。
書店で適当な入門書を見繕ってきて、まずは1冊を読み通しながら。
gccならネットから無償で入手できるし、学生さんならMS製品もアカデミック価格でしたっけ?
74 :
デフォルトの名無しさん :04/08/10 08:02
#include <iostream> #include <string> using namespace std; int i,k; int main() { string str[4][2]; str[0][0] = "就職 "; str[0][1] = "活動 "; str[1][0] = "会社 "; str[1][1] = "訪問 "; str[2][0] = "集団 "; str[2][1] = "面接 "; str[3][0] = "学校 "; str[3][1] = "推薦 "; for(i=0;i<4;i++){ for(k=0;k<2;k++){ cout << str[i][k] << endl; } cout << "\n"; } return 0; } これってどうよ?
スレッドセーフといえば、以前、COM のオブジェクトを実装するときに、 Release のスレッドセーフな実装でさんざん悩んでドツボにはまったことがある。
>>67 根性あるなら我慢して真剣にCを1ヵ月勉強しなさい。
それで身の振り方もわかるようになるだろう。
Cでやった事はJavaなりC++なりC#なりで必ず役に立つ。
それに1つの言語をマスターすれば他の言語を覚えるのに時間はかからない。
>>71 72 73 77
本当にありがとうございます。
実は10時間くらい調べて聞いたのですがまだ調べたりなかったようです。ペコ
77さん本当に参考になりましたっす。C言語の入門書慎重に選んで熟読しプログラミングは覚えるより慣れろ
らしいのでがんばってやっていきたいと思います。
>>77 BASICやアセンブラの場合は、他の言語覚えるのにまだまだ時間かかると思うけどな。
81 :
デフォルトの名無しさん :04/08/10 15:29
C#のparamsって便利だよな。
>>79 日本語の勉強もしておけよ。
仕事でプログラミングをする積もりなら読解力と文章構成力が必要になるからな。
>>80 そうか?アセンブラ知っていればCは楽勝。とくにポインタでつまづくことがない。
>アセンブラ知っていればCは楽勝 そうかなぁぁぁぁ?
>>84 アセンブラ理解できるセンスがあればCは理解できそうな気がする。
C++はまた別のセンスが必要だけど。
センスってなんだ。 勉強すりゃ誰でもできるわ。
>>86 は世間知らず。
困ったことに勉強しても出来ない奴はごまんといます。
>>85 センスというか相性だね。C++やり始めたらあまりの難しさに根をあげてしまう香具師は
いくらでもいる。反対にそんなに難しく感じずあっさりと身につけてしまう香具師もいる。
>>86 考え方が甘い
センスが要求されるのはある程度より深いところの話で、普通に使うだけならちゃんとした学習すれば誰にでも出来る。
できない人間はセンスだとか抽象的な表現を使う法則。
>>86 >>89 君はどうも努力万能主義だね。君の考え方に従えば、100人いれば100人が
努力すれば全員東大に合格して、エリートコースを歩めるという風に読める。
で、君は無事に東大を卒業してエリートコースを歩いているかね?それとも
ただの妄想ですか?ププ
>>91 努力すれば誰でも東大に受かるなんて風には、とても読めませんが。
>>91 F1は誰にでも乗りこなせるものじゃないが、運転免許程度なら取れん奴のほうが珍しいだろ。
C++は神に選ばれたものだけが使えるエリート専用言語なんだよ
>>94 >>95 同一人物ですか。東大とは拡大解釈しすぎかもしれんが、だからと言って君は
C++を舐めすぎ。エピステーメーみたいになれるんかよ?
>>97 同一人物じゃないし、C++を舐めてはいない。
妄想もたいがいにな。
>>98 妄想はお前の方。逃げるなよ。誰も脳無しのお前を責めたりしないから。
マ板でやれよ
まぁ、夏だからな
あぁ、ヘンな奴の相手してしまった。
100は逃げました
>>101 同一人物なのにそうでないと言い逃れするとはチキンな野郎だ。
嘘つきは相手をしても無駄なエネルギーを使うだけなので放置。
OK。95には悪いが、俺=95ってことでこの話題終了。
夏満開
ぁぁデムパに構いたい
嘘つきは、泥棒の始まり。
2chの電波は単なる子供の場合が多いから、もっと優しくしてやれよ。
char_traits<T>::copyとchar_traits<T>::moveってどうちがうんですか? どっちもバッファのオーバーラップが許されないとあるのですが、 だったらmoveの意義が無い気がするのですが。
男割だ
>>116 moveは重なってても大丈夫のはず。
何の記述を見たのですか?
>>82 日本語の勉強も必要なんすかぁ〜 了解です!
Cと日本語がんばります! ありがとうございました。
>>122 VC6に付いてるMSDNには許されないと書いてあるな。
>>116 オーバーラップがないのが確実なら
オーバーラップが許されないほうを使うほうが速い。それだけ
VC6 MSDNの和訳ミスということで。
こんな程度、訳せないようじゃあ、他のところも全く信用できないな。
まあ、原文が間違ってるところもあるし。
ファイルサイズを取得するにはどうすればいいのですか? 今はifstreamでファイルをオープンして最後までなめる処理を してるんですがあまりにもナンセンスなんで・・・ string strLogFileName = "hogehoge.txt"; ifstream in; in.open(strLogFileName.c_str(), ios::in); if (in.is_open()) { // サイズを見る uint nCount = 0; char c; while (!in.eof()) { in.get(c); nCount++; } } in.close(); cout << nCount << endl;
あ、最後の出力のとこがnCountのスコープはずれてましたね。
std::ifstream i(strLogFileName.c_str(), std::ios::binary); if (i.is_open()) { i.unsetf(std::ios::skipws); std::istreambuf_iterator<char> it(i); size_t s = std::distance(it, std::istreambuf_iterator<char>()); }
スコープ外したらコンパイルエラー(ry
せめて読むんじゃなくてseekしようよ。 で、普通はANSI標準じゃないけど POSIX標準なstat/fstatを使うんじゃないかなあ。
>>132 C++の標準にファイルサイズという概念はない。環境依存。
>>136 fstreamではseekは推奨できないんじゃないか。
>>134 i.unsetf(std::ios::skipws);は必要無いんじゃないか?
>>137 概念は無くともファイルが存在すれば、
その格納データ量という意味で意味づけはできるんじゃない?
141 :
デフォルトの名無しさん :04/08/12 01:38
ファイルサイズ。 fseek()で終端に位置づけてftell()で位置を取得で終わりじゃん。 テキスト、バイナリの区別は必要かもしれないが、 その辺は調べてちょ。
boost使えば簡単じゃん。 次期標準だろ。
プゲラ
boost::filesystemにファイルサイズはない。
本当にファイルサイズが必要なのか? たとえばifstreamを使って読み込むなら、 スペースのスキップや改行コードの変更によって 読み出せるデータ量が変わってくるんだから 132のように一文字ずつ数えるしかないんじゃ?
バイナリモードでfopenしてfseek,ftellじゃ駄目なの?
ファイルサイズ・・・。 定番の釣りだな。アフォクサ。POSIXで答えでてるじゃん。
アフォクサいのに釣られてるよ、この馬鹿。
たまに見かける、「iostream系だけで解決したい厨」。 iostreamだけ使えとは誰も言っていないにも拘らず、定期的に湧く。
150 :
デフォルトの名無しさん :04/08/12 13:32
147が釣りに見える
みんな、お盆休みは有効に使おうよ。
class A{ // 省略 }; class B{ // 省略 }; class C : public A, public B{ // 省略 }; ポリモフィズムの事なんですが、 A* a = new C; は、期待どおりの動作をし、 B* b = new C; は、期待している動作をしてくれない、 (つまり、多重継承の場合、ポリモフィズムにできるのは1つ目に継承したクラスへのポインタだけ) というような事を、以前、本かサイトで見た(読んだ)ような気がするのですが、 調べなおしてみても、どうもそのような事が書いてある部分を見つけられず、 以前見た(読んだ)と思っているのは、ただの勘違いのような気がしてきました。 B* b = new C;は可能か不可能か教えてください。 更に、 class D{ // 省略 }; class E : public C, public D{ // 省略 }; C* c = new E; これは可能でしょうか? お願いします。
>>153 >B* b = new C;は可能か不可能か教えてください。
可能。
>C* c = new E;
>これは可能でしょうか?
可能。
やってみてから聞け。
なんで試さないんだろう・・・
>>154 >>155 コンパイルが通るかは試しましたが、ちゃんと動作するかどうかとなると、
規格では駄目でも、たまたま動いちゃったりするかもと思ったからです。
どうもありがとうございました。
そもそも「ポリモルフィズム」の話題じゃないような気がします。 これは継承と、基底クラスのポインタへの代入というだけでは?
>>153 「期待どおりの動作」が何を指して言ってるのか分からないので
C++言語的には正当な行為だとしか言い様がない。
まあ
C* c = new E;
こんな事してたらおおよそ期待通りの動作はしないだろうけど。
規格で駄目なら普通はしない。 趣味のプログラミングなら話は別。
>>157 >>158 申し訳ないです。
言われてみれば、153に書いた例では、単に基底クラスへのポインタに代入ができるかどうかしか問題にしていませんね。
良い例が思いつかず、クラスの中身を全部省略してしまいましたが、
基底クラスには仮想関数が宣言してあって、継承したクラスを「基底クラスへのポインタ」に代入し、
仮想関数を「基底クラスへのポインタ」から呼び出す事ができるかどうか。
また、基底クラスに仮想関数がない場合でも、継承したクラスを「基底クラスのポインタ」に代入すれば、
基底クラスに含まれるメンバ関数とメンバ変数(publicであれば)を「基底クラスへのポインタから」操作できるかどうかなどの事が聞きたかったです。
もっと具体的(実践的)に、現在、知りたかった事は、インターフェース・クラスは、一番最初に継承されていなければいけない物なのかどうかです。
↑↑↑ 誤爆スマソ
あらら...orz
ファイルサイズの話は決着付いたの?
>>144 CVSにはもう追加されてます。
次のリリースからつかえるでしょう。
>>160 > 仮想関数を「基底クラスへのポインタ」から呼び出す事ができるかどうか。
できる。というか、仕様書読め。
> また、基底クラスに仮想関数がない場合でも、継承したクラスを「基底クラスのポインタ」に代入すれば、
その用途のためには、規定クラスに純粋仮想関数(実態はないが型の定義だけしてある)を
定義しておく必要がある。
> もっと具体的(実践的)に、現在、知りたかった事は、インターフェース・クラスは、一番最初に継承されていなければいけない物なのかどうかです。
別に。
>>160 それも自分でコード書いてみればすぐに分かる事じゃない?
少なくとも返事を待つよりは早く結果がでるぞ。
呼び出される関数について、オーバーライドはインスタンスの型によって決まり、
オーバーロードは呼び出し時のポインタの型によって決まる。
>>160 > 仮想関数を「基底クラスへのポインタ」から呼び出す事ができるかどうか。
悪いけどこんな基本的なこと人に聞く人にC++は向いてないよ。
>>165 POSIXで確定だよ。
今調べてみたが、フリーのVC++ToolKitにも
ちゃんとstat.hヘッダーが含まれていた。
今はファイルサイズに限定した議論になっているけど、
実用から見るとタイムスタンプ・属性などの情報もいずれ必要になってくるだろうし。
ANSI標準でのファイルサイズ取得に固執する行為は、初心者呼ばわりされるだけ。
171 :
デフォルトの名無しさん :04/08/13 00:28
以下のパターンAとパターンBの違いについて教えて下さい。 パターンAとBの違いは、Baseクラスの関数にvirtual指定があるか、ないかです。 ■パターンA class Base { virtual void Func(); // 仮想関数 } class Deliver { void Func(); } ■パターンB class Base { void Func(); // 仮想関数 } class Deliver { void Func(); }
>>171 質問に真摯に答えると、vtableが出来るからsizeofの値が違う。
できれば質問の意図を教えて欲しい。
>>171 違いって見たまんまだろ
パターンBのBase::Func()は仮想関数じゃないだけ
もしかしてDeliverはBaseから派生させたかったのか?
>>172 171に対してそれは無理な相談だ
真剣にレス付けようと思っていたが、 先にリロードして正解だった。 >173がシンプルに説明をしてくれている。 後はBase::Funk()が仮想関数でないということは、どういうことかを 考えればよい。 つまり仮想関数であることにより期待される動作(これは勉強するべし) を数え上げれば、それがすなわち2つのパターンの違いである。
好意的に解釈すると、 Base* a = new Deliver; a->Func(); したときにBaseとDeliverどっちのFunc()が呼ばれるかを書いて欲しいんだろうな。
177 :
>>171 :04/08/13 01:14
>>176 あ、そういうことです。
と、いうことは、
パターンAの場合は、基底クラスが呼ばれて、
Bの場合は、派生クラスが呼ばれるということでいいんでしょうか?
なんで自分で試してから発言しないのかを教えてくれないか?
>177 だから仮想関数とは何かを勉強しなよ。 >176が好意的に書いてくれた丁寧なレスの内容なんて、 本読むなりサイトの記述をチェックすればすぐにわかること。 調べたけどわからなかったからここで聞いているんですなんて いうのは却下だよ。それは自分の無能さを公に宣言するような ものだからな。
180 :
デフォルトの名無しさん :04/08/13 02:35
あるメンバ関数からしか呼ばない関数も そのクラスのprivateメソッドとするべきかどうかで迷ってます。 クラス宣言が見づらくなるという、つまらない理由で 単なるstatic関数としてのみ扱うのは横暴でしょうか
>>180 意味がわかりません。
もっと詳しく、読んで理解できる日本語で説明するか、コードで語ってください。
>>180 *.cppにstaticで書いてるってことね。
関数内で関数定義が出来ればいいんだろうけど、出来ないんだよね。
そういう場合、俺はstructのoperator()で擬似的に関数内関数にしてる。
>>182 > そういう場合、俺はstructのoperator()で擬似的に関数内関数にしてる。
不要なハックは感心しない。
>>182 そうです、すいません
モジュール内でstatic(=ローカル)な関数の意味でした
うーん、無理矢理、関数内関数っぽくしちゃうわけですか
元々、切り分ける意味が薄い関数なんですよね。
再帰や、ちょっとしたまとまった処理程度で。
確かに散らすよりは気分はいいかも…
早速試してみます、レスありがとうございました
>184 そもそもprivate関数とモジュール内staticな関数の違いとして、 メンバにアクセスできる、できない、があるんだが。
>>183 STLと同じ流儀なんだから標準的技法なんじゃないかと
static関数がstaticメンバ関数と受け止められたんだろう。 俺も一瞬そう解釈した。
わざわざstaticにしないで namespace {} で囲っちゃえば?
namespaceで囲うと、文字数が増えるので出来れば別の方法教えてください。
>>186 何のためにoperator()が使われているか理解してないんだね。
関数内関数(←全然違うw)を模倣するためじゃないことくらい分からないと。
181大暴れだな
>>182 は別にハックでもなんでもない常套手段だと思うけど
>>190 ん?無名namespace使えばいいだろ。
なぜこの状況でnamespaceが出てくるのか誰か解説してください。
staticの意味が・・・
>>192 確か、コンテナ内部で使われるんだっけ?
フォローお願い。
>>196 static関数に頼らないC++的な解決法とか・・・?
200 :
デフォルトの名無しさん :04/08/13 07:29
staticでいいと思う
>>177 逆だ
オーバーライドとオーバーロードの区別をしろ
ポリモフィズムを理解しろ
んー、人それぞれだとは思うけど 無理に「C++流」にせず、「C流」で構わない部分ってのもあるとは思う。 staticもそうだけど、stdioの関数群とかキャストとか。
cout より printf
てゆーかsprintf使えなくなって stringstream使えとか言われたら 俺絶対泣くし。
static キーワードでファイルローカルな宣言をするのは正式に deprecated ですよ。 stdio.hとか、strstreamとか、リテラルからchar*への変換とかと同等。
(・3・)エェー 僕の知らない英語使わないでYO! deprecated 【形】 《コ》〔仕様{しよう}などが〕廃止{はいし}される可能性{かのう せい}がある、 廃止予定{はいし よてい}の、 将来{しょうらい}のサポートが保証{ほしょう}されない(ので使用{しよう}すべきでない)、
>>167 どうもありがとうございます。
>>168 ポリモフィズムの時のデストラクタのように、
試してみるだけでは気付かない事があるかも知れないと思って聞きました。
(ここで聞くより本やサイトで調べろって言われれば、そのとおりなんですけども)
皆様、ご迷惑おかけしました。
今度こそ、消えます。
>>208 だから「聞く」とか「本やサイトで調べる」とかじゃなくて、
その前に、自分でコード書いて実行すれば結果が分かるだろう?
っていう話をみんなしてる訳で・・・
>>208 >ポリモフィズムの時のデストラクタのように、
>試してみるだけでは気付かない事があるかも知れないと思って聞きました。
それこそ、試した方が簡単に、確実に、良くわかるだろ・・・
試してみるだけでは気付かない事があるかも知れない
212 :
デフォルトの名無しさん :04/08/13 09:54
関連して質問させてください。 static関数よりも無名namespaceを使うべき、って聞いたことがあるんですけど、 (規格書にもそう書いてあった気がする。) (1) なんでか知ってますか? (2) みなさんはどっち使ってますか? とりあえずワシは、規格書をもう一回読んできます。
>>211 同意。
まず試すことはとても重要。
でも、試して大丈夫だからといって安心してはだめ。
質問するときは
「こういう目的のために、こういうコードを書いてみました。試したら上手く動きました。でも正しいか不安です。教えてくれ。」
って感じでよろしく。
>>212 1. deprecated
2. neither
試した姿勢が文脈から感じられない質問って教える気無くすもんだよ。 質問する側は相手からうまく情報を引き出すコツを身につけるべきだ。 相手の為ではなく自分の為にな。
>>214 1. なんで deprecated になったかを知りたいのです。宜しくお願いします。
2. それはそれでアリでしょうね。JAVAみたいだけど。
>>216 staticは使う場所によって意味が幾つにも分かれてしまう(のでわかりにくいと言われている)から減らすため
>>217 へえ。そんな理由だったんだ。
だったら、なんでクラスメンバにstaticなんてキーワードをあてたんだろう。
矛盾してるよね。
上でも起きてるように staticというキーワードに複数の意味を持たせる事で 実際に混乱してるからね。 でも、絶対に「非推奨」が「不可」にはならないと思うけどね。 Cが無くならない限り。 むしろ(単語の意味はともかく)、staticメンバのするために、 既存の「static」というキーワードを利用したのが混乱の原因なんだから。 関数内staticな変数だって C++がマルチスレッドを前提とした言語にならない限り 無くなることはないだろうし。
>>218 file local = static
ってのは、staticって単語の誤用だからでしょ。
infinite existence = static
に統一したんでしょ。
>>219 > 関数内staticな変数だって
> C++がマルチスレッドを前提とした言語にならない限り
> 無くなることはないだろうし。
そんなことはないです。
マルチスレッドだってstaticなlock変数は極めて有効です。
>>215 > 相手からうまく情報を引き出すコツ
2chで一番有効なのは、
その場の人間達を小馬鹿にするような口調で間違った主張を披露して、
知識をひけらかすことに命を賭けてる厨が「正解」を携えて突っ込んでくるのを
待つって戦法ですね :-)
小細工の必要は人はきのこれない悪寒。
いや、だから extern宣言は関数スコープでもファイルスコープでも同じように書けるのに infinite existence変数の記法は関数内外で違う書き方が推奨されるってのがね。 違うのはスコープ(可視性)だけで、寿命その他は同じなのに。 (初期化タイミングは違うけど、「スコープが初めて有効になった時に初期化される」という意味では同じ)
>>220 クラスメンバと infinite existence って違う概念のような気がするなあ。
グローバル変数だって infinite だし。だからグローバルな static関数/変数は非推奨にしたって考えればいいのかな。
マルチスレッドで使うstaticなlock変数と、auto変数じゃないstatic変数って別ものじゃないかなあ。
再入可能性の制御ってこと?
まあ、ここでどうこう言ったって標準化委員会の目にとまるわけでもないし std::や#include <c...>あたりから、なんとなく Cとの互換性(というよりCしか知らない人の移行しやすさ)を軽視する方向のような気もしてるけど それならそれで仕方ないかなって気もするし。
226 :
デフォルトの名無しさん :04/08/13 13:51
>>223 オート変数へのstatic qualifierが「変更する」のは、
寿命でしょ。スコープは変えないよ。
qualifierの行う変更について、
static: 寿命
extern: スコープ(defaultだから基本的に意味なし)
と統一したんでしょ。
で、名前のスコープはnamespace使えと。
> 違うのはスコープ(可視性)だけで、寿命その他は同じなのに。
はとんちんかん。
グローバル変数の元から持っている性質とオート変数の
static qualifierが変えた性質が同じだからって何だって言うの?
>>224 > クラスメンバと infinite existence って違う概念のような気がするなあ。
infinite existence: クラスメンバの性質の一つ
オブジェクトが存在しなくても存在し続けるメンバ。
staticなオート変数が関数実行中でないときも存在するのと同じ。
後半については何言いたいのかサパリ
>オート変数へのstatic qualifierが「変更する」のは、 >寿命でしょ。スコープは変えないよ。 なにわけわかんないこと言ってるの? auto変数は常にauto変数であって、決してstaticではないよ。 関数スコープのローカル変数に、autoとstaticの2種類があるだけ。
>>227 要するに、
「いろんなタイプの変数や関数が存在するけど、とりあえず寿命がinfiniteなものに付けるキーワードはstaticでいいや」
って標準化委員会が考えたってことだね。
変なのぉ〜とは思うけど、まぁ理解はできる。
今までCを使っていたんだけですが、理由があってC++を使うことになりました。 プログラムの中でソケットを扱うのですけど、Cでは直接socket()等のシステム コールを叩きますよね。 でもC++でそれをやるとC++らしくなくなる気がします。 特にselect/pollで多重化して非ブロックにして…、なんてのをやると 「オブジェクトは何所行った?」って感じがするんですよね。 そこで聞きたいのですが、みなさんはC++でネットワーク関連のプログラム を書くときどういう設計にしますか。sourceforge.netで調べていたら cppsocketというソケットのクラスラッパがあったりするので そういうのをみなさんも使用(または自作)しているのかなと想像しているのですが。 ソケット周辺だけでなく、どうもC++を書いているとどこでシステムコールの ような低レベルインターフェースを叩くか迷うんです。理想と現実というか…。
C++らしい手段が提供されてなくて、Cの流儀で書く事に抵抗があるのならラッパーを書くしかないじゃないか。
ソケットがオブジェクト化されててもあんまりうれしくないぞ。 所詮通信路でしかないんだから、そこはそれで割り切って、 オブジェクトのシリアライズ経路のひとつとして考えたほうがいいと思う
>>231-234 レスありがとうございます。
ACEってのは気になるますね。
サイトの方に文章が大量にあるので、いまから読んでみます。
本も出てるみたいですね。
一方で無理にオブジェクト化すると標準入出力と同列に扱えなかったり
するんですよね。
>>232 , 234さんらはやはりその手のライブラリを使うのでしょうか?
いろいろ考えてるとソケット自体をオブジェクトにするのでは無くて、
もっと上位のクラスを作って、その中で生のソケットを扱うのが良いのかなぁ、と。
例えばHTTPServerやFTPClientのようなクラスを用意して、その中で
プロトコルとソケットを管理するような感じ。
結局Socketクラスを作っても
Socket sock;
sock.setsockopt(HOGEHOGE);
sock.bind(Foobar);
みたいなことをやり始めると結局やってることはC流とは変わらないし。
最後、文章おかしいけど勘弁(意味は伝わるでしょう)。
でもSocketクラスのデストラクタが有効に使えるでしょ
>>237 デストラクタでソケットを閉じるということですか?
ソケットを閉じるときって結構デリケートな処理が必要になったりしますよね。
相手の為にできるだけ早く閉じたかったりすることも。
あ、そういうことをクラス内に隠蔽すると嬉しいという話か。
非同期IOなんかも隠蔽出来るとうれしいかな。
その場合select/poll等の関数は誰が保持しますか?
>>234 のような専用クラス?
240 :
デフォルトの名無しさん :04/08/14 10:17
>>239 黙れ。ここはCスレじゃないんだからそんなことにこだわるな。
ソケットをストリームに組み込むとだいぶ変わる。
>>240 いやいや、そうでもない。
特にサーバアプリの場合、完全に環境依存。
ちょっとやそっとのことで汎用的なラップをできるものじゃない。
ヒントをいうと、あまりカプセル化しすぎないこと。 メンバ変数に直接アクセス出来るようにしておく事をお奨めする。 デストラクタ機能はあくまでオマケ感覚のつもりで。
Javaのsocketが大失敗こいてるからなあ・・・
>>245 そうか?
プラットフォーム、実装が複数ある中では異例の成功だと思うけども。
>>244 なぜに死すべしや?
ついでに書くと、ソケットハンドルをいつでもAttach/Detachできるようにしないとかなりツライ。
デストラクタ処理がかえって邪魔になる事もあるからね。
newしろや
>>246 まさか。あんなのtoy programでしか使わないよ
>230 QtのSignal/Slotでいい感じじゃねえか。
>>247 デストラクタ処理がかえって邪魔になる事もあるからね。
なりません、まだ使われる可能性があるのにインスタンスを破棄するアホでもないかぎり。
>>252 同期型ソケットしか使ったことない厨は1回氏ね。
非同期ソケットでも、ソケットの寿命とオブジェクトの寿命を同一にすればいいだけの話だが
>メンバ変数に直接アクセス出来るようにしておく事をお奨めする。 タコ助だな
どうせsetsockopt()みたいなのを呼んだり環境依存のフレームワークに 生のソケットを渡したりするから、生ソケットにアクセスする手段は 必要だって。完全なカプセル化じゃなくFacadeと考えた方がいい。
サーバソケットからacceptして生成した新インスタンスに setsockoptし忘れて・・・なんてことが 環境依存で起こりまくりですよもう
サーバプログラムを書いた事ないヤシが多いのか、このスレ?
>>255 通信プログラム初心者は黙ってた方がいいね。
259 :
デフォルトの名無しさん :04/08/15 00:29
C++の勉強を始めようと思って、こういうコードを書いたのですが #include <iostream> int main() { std::cout << "hello\n"; } こういうエラーが出てきます。どなたか解る方がいましたら教えてください。 cstdlib(22): error C2873: 'exit' : シンボルを using 宣言の中で使用することはできません。 cstdlib(19): error C2873: 'abort' : シンボルを using 宣言の中で使用することはできません。 cstdlib(22): error C2039: 'exit' : 'operator``global namespace''' のメンバではありません。 cstdlib(19): error C2039: 'abort' : 'operator``global namespace''' のメンバではありません。
sockoptの挙動が環境ごとに違うことは知らない奴が多そう あとsignalも
長時間かけて小出しに煽ってるところを見ると 必死でググりながら調べてるのかな? 勤勉で結構。
263 :
デフォルトの名無しさん :04/08/15 01:03
>>261 すみません、<cstdlib>をインクルードしても駄目でした。
再インストールでしょうか。。。
環境依存部をラップする事が不可能って断言してる香具師いるけど、wxWidgetsとか、想像も出来ない世界にすんでるんだろうな
>>264 > 環境依存部をラップする事が不可能って断言
具体的にどのレス?
おまけに粘着(w
全プラットフォームの完全な仕様があれば作れるけどさ、
そんなこと稀だし、ドキュメントに不備あるし、
OSのverupやパッチで動作変わったりするし
だから結局
>>256 のいうような形になると思うんだ
想像がつかない奴もいるようだが
>OSのverupやパッチで動作変わったりするし だからカプセル化するんじゃねーのか? つうかメンバ変数に直アクセス出来るようにしとくってギャグか?
メンバ関数でやれることは、限りなく「お約束」処理だけだよ。
>>269 は、ソケットプログラム作ったことないの?
>>270 > メンバ関数でやれることは、限りなく「お約束」処理だけだよ。
んなわきゃない。
俺はネットわープログラミングは専門外のゲーム屋だが、メンバ変数を
直接触らせるような設計にはしてないぞ。機種固有のメンバ関数を定義
することはあるが。
実務経験があるから偉いってわけじゃなし、「ソケットプログラム作った
ことないの?」なんていわずに、もすこし具体的な指摘をしとけ。
あとネットワークの話に絞りたいなら、スレ違いだから続きは
よそで頼む。
スレ違いのようでスレ違いじゃないと思ったが
ラッピングの目的にもよるような気がしてきたなあ
javaやmfcみたいな、大勢向けのフレームワークなのか、
ちょっとした共通化を施したいだけの話なのか・・・
>>269 > だからカプセル化するんじゃねーのか?
仕様が決まればカプセル化できるのはアタリマエのような・・・
(と別のスレで似たことを書いたな)
>>270 ゲーム屋はそこで動けば済む話だから楽だよね。
ますます具体論が消えてきたな。
分かったことは、頭の弱い人は、 > ヒントをいうと、あまりカプセル化しすぎないこと。 > メンバ変数に直接アクセス出来るようにしておく事をお奨めする。 > デストラクタ機能はあくまでオマケ感覚のつもりで。 このくらい低い目標を持った方がいいということ。無理はいかん。
面罵変数をpublicにするってそんなに悪ですか?
>>270 お約束なるものをコードで表現するのがクラスでありメンバ関数では?
約束(仕様)に沿って提供する機能(メンバ関数)を設けて、
その実装(内部仕様)は外部から見えなくするというのがクラスではないかと。
お約束以外にいろいろできるようにするというなら、そもそもクラスを使う
意義がなくなるような気がするんです。
メンバ変数を外部から操作できてしまうと、メンバ関数の動作において
状態を把握・管理できかねる状況が生じませんか?
なんでもありにするなら、最初からクラスにせず、普通にCのライブラリのように
直接的に使うほうが楽な気もします。
>>276 場合によるが、ソケットやファイルでスクリプタを public にするのは
かなり終わってると思われ。
具体論って特定の問題の解決方法ってこと?
それだとそれに最適な実装方法を持ち出して、それで終わりだからなー。
とはいえ
>>278 は何もわかってないな
> お約束以外にいろいろできるようにするというなら、そもそもクラスを使う > 意義がなくなるような気がするんです。 これも頭痛いな。
>>279-280 コテハンつけてくれ。
メンバ変数を公開しないというのは、それを公開すると状態の一貫性を
保ちにくくなるから。たとえば文字列クラスで文字列を記憶するバッファと、
文字列長をメンバ変数にしていた場合、それを公開したら容易に矛盾
する状態を作れてしまう。
ソケットも同様で、ソケットを直接ユーザに見せたらソケットのオープン・
クローズ状態などをライブラリ側で把握できなくなってしまい、エラー処理や
assert() による実行時検査が事実上不可能になる。
Win32 のハンドルのように、すでに OS 側で管理機能が入ってる場合は
ともかく、生のソケットやファイルでスクリプタを直接ユーザに露出すると
誤用に対してきわめて脆弱なライブラリになってしまう。小規模なプログラム
ならそれでも良いんだが、規模がちょっと大きくなったり、複数のプログラマが
共同で作業する場合には、そのエラー検出・バグ取りの時間が馬鹿にならん。
>>281 そういう奴にsocketを触らせる時点ですでに間違ってると思う。
>>281 で、終了でいいんじゃない?
後はOOP一般論スレにでも行って。
279その他は、とにかくsocket(または他のリソース)のすべての機能を網羅、分類するための ラッパーとしてだけにしかクラスを使う事が出来ないんだよ。 抽象化とかそういったことはハナから頭にない。
対象プラットフォームの挙動や仕様があらかじめ決まってる、 静的な世界のことしか考えてない人たちがライブラリ設計しちゃイカンと思う
仕様が流動的に変化するプラットフォームなんてあったらまともに追従する事は不可能ですがなにか。
スレが伸びてると思ったら、バカが一匹沸いて必死に自演してたのか
>>285 そういうことだね。
C++使って書かれsocketプログラムというのを何個かみたことがあるけどありゃC++じゃねぇ。
クラスというより名前空間でソケット汎用関数を用意するイメージの方が近いかもね。
プラットフォーム依存をなくすための抽象化を なんでそこまで張り切るのかが分からん ガチガチに作っても、OSのパッチひとつでダメになるのは目に見えてるのに その例がjavaのsocket。 抽象化の工数はもっと意義のあるところに使おうぜ。
>>289 そういうことならOOスレもスレ違いだな。初心者スレあたりが妥当だと思うよ。
>>291 不必要なところまで低レベルな機能を提供しなけりゃいい。
socketなんてクラスはsocketそのまんまだし(.NETも然り)
>>290 結局そこに行き着くと思うんだがなあ・・・
このスレで頑張ってる抽象バカって、単純に
socket_some_func_01(socket, params);
を
socket->some_func(params);
に置換して満足してるんだろうか。
この程度で抽象化なんてほざいてたらイタいが。
>>293 javaのsocketの歴史を見ると笑えるよ。
だんだん低レベルなメソッドが追加されてくの。
NIOではとうとう分離しちゃったけどな。つまるところ、破綻。
サーバ上で動くことを求められるJavaが初心者用socketクラスだけで事足りるわけがない。
初心者用ソケットクラス作って満足してる人たちが大半なのに
>>295 > だんだん低レベルなメソッドが追加されてくの。
メンバをpublicすることとは、全く別の話だが?
>>294 > このスレで頑張ってる抽象バカって、単純に
> socket_some_func_01(socket, params);
> を
> socket->some_func(params);
> に置換して満足してるんだろうか。
プラットフォームの違いを、型システムで扱えるのだが?
C++スレなんだからACEの話してくれないかな。 Javaなんてどうでもいいから。
>プラットフォームの違いを、型システムで扱えるのだが? 意味わからん。 覚えたての単語を使ってみようなんて思わなくていいから。
>>294 満足してるのはお前だけ。お前用のクラスは
class socket { public: int socket; };
だけで良いじゃん、どうせメンバ関数すべて標準関数へのスタブにするんだろうし。
そろそろいいんじゃない?どうせ折り合おうと思って無いでしょ? 考え方が違うんだろうし、無理に意見一致させる必要も無いし。
>>294 みたいな単純な置換は、C++初心者の勉強にはちょうど良いかもしれんね。
実戦でやられると迷惑なだけだが。
C++はJavaを生み出すための単なる足がかり。 こんなクソ言語を使ってるダメプログラマは腹をくくって死ぬべきだ。
308 :
デフォルトの名無しさん :04/08/15 21:37
typedef aaa<bbb> ccc という定義があった場合に、これをどのように理解すればいいのでしょうか? aaa<bbb>をcccとして置き換える、というところまでわかりまっす。 でもaaa<bbb>の括弧の部分がわかりません。 これは、C++独自の仕様なのでしょうか? どなかた、ご教授お願いします。
ただのテンプ(ry
310 :
デフォルトの名無しさん :04/08/15 21:39
>>309 それではさっぱりわかりません!!!!!
ただのテンプレ(ry
312 :
デフォルトの名無しさん :04/08/15 21:45
>typedef aaa<bbb> ccc という定義などない
typedef basic_string<char> string; のような宣言のことだろうな
314 :
デフォルトの名無しさん :04/08/15 22:11
><313あ、そうです。
315 :
デフォルトの名無しさん :04/08/15 22:12
まちがえました・・・
× ><313
○
>>313
316 :
デフォルトの名無しさん :04/08/15 22:13
CORBAの質問はここでOKですか?
だからテンプレー(ryだって言ってんだろが
318 :
デフォルトの名無しさん :04/08/15 22:16
テ○○○ートだってば
320 :
デフォルトの名無しさん :04/08/15 22:27
321 :
デフォルトの名無しさん :04/08/15 22:30
CORBAのCORBA::W_String_varって何? std::stringからCORBA::W_String_varに変換する方法を教えてください。
質問なんですが、 DWORD* Dw; ::GetFileSize(FHnd,Dw); こう書くと"値のない変数を参照しました。"と警告がでます。 値があればいいのだから、 DWORD* Dw = 0; ::GetFileSize(FHnd,Dw); こう書けってことですか? それとも他に書き方があるんでしょうか?
DWORD Dw; ::GetFileSize(FHnd,&Dw); じゃダメか?
>>322 、324
出来ましたじゃねーよ
お前はCやめるか必死でポインタ勉強するのどちらかだろ
GetFileSizeとか書いてる場合じゃねーよ
C++とOOPの基礎を習得しようとするにはどの本を買って真剣に読めばいいんですか?
自分のレベルにあった本をその都度読んでいけばいい。
しつもーん class B { private: ~B() {} }; class D: public B { //~D() {} }; これがコンパイルを通ってしまうんだけど標準的にはどうなの? ちなみに、コメントを解除するとちゃんとエラーになるんだけど。
コンパイラ名とバージョンをかかないと、情報小出し君といわれちゃうぞ
>>329 おそらく
D d;
と実際に変数を定義すると、その段階で D::~D() をコンパイラが作ろうとして
コンパイルエラーになるんじゃない?
>330 まあ悪名高き某VC6だけど、 タダのVC Toolkit 2003でも試したら、警告は出たけどコンパイルは通った。 >331 それならVC6でもエラーになったけど。 D *d = new D; delete d; この場合だと通ってしまいます。
CodeWarrior for Win ver.8.3でチェックしてみた。コメントを解除 せずともD d;の時点でコンパイルエラーになって通らない。 ポインタに書き換えてもコンパイルエラーになって通らない。
12.4 Destructorより
5
デストラクタが暗黙的に宣言されているクラスがinaccessibleな
デストラクタを持った基底クラスを持っている場合、プログラムは
不適格(ill-formed)である。
多分
>>329 は、D d;としてもD* d=new D;としても通らないのが正しい。
>>332 悪名高くないだろVC6。
何と比較して言ってんの?
テンプレート特殊化に対応してないコンパイラはたくさんあるけど、 forのスコープがあんなにひどいコンパイラはVC++6くらいだろ
けなすと玄人っぽいじゃないですか。
VC++6は出た当初は非常に抜きん出ていたけど、今となっては…
逆にVC++6を付属のSTLのままで使ってる香具師がいたら知りたいぜ。
例外すら投げられないしな
>340 呼んだ?
>>336 forのスコープがあんなにひどいコンパイラはVC++6くらいだろ
えーっと、「・・・」が帰ってくるのを期待してたのかな?
forのスコープ問題って散々既出だけど、コンパイルスイッチで制御できるし
出た当時の仕様には準拠していたはずだよね。
VC6が出た時代背景も考慮に入れるなら、
叩けるところはnewがbad_alloc投げない事くらいでないの?
>>340 付属STLはパッチ出ててバグ修正されてるはず
Dinkumwareのページになかったっけ?
>newがbad_alloc投げない これはかなり問題ではないかと…
>コンパイルスイッチで制御できるし そうだっけ? 本当にそうだったら、これほどいつまでもウダウダ言われないと思うし、 #define for if (0) ; else for なんてのがまかり通る事もないと思うけど。
>>343 Dinkumwareのページ古くて、SP5以降だといくつか直ってたり修正ファイルの方が古かったりする。
結局差分とってソース追って正しいか確かめるのに大変だった。
>>344 _set_new_handler()でどうにかなるし。
>>345 forのスコープはコンパイラスイッチで変更できるが、変更した場合付属のライブラリ群の動作が保証されないとかだった気がするが。
>>347 new_handler 書いたり、アロケータ用意したりとかマンドクセ
using namespace std; ってやるのと、必要になる都度 std:: ってやるのとどっちがいいですか? あと、どっちの方が主流なコーディングですか?
どっちもやるけど、主に std:: って、その都度つけてる。 using namespace std; しちゃうと string, vector, list, map 等々、 ありきたりな名称で名前空間を汚されるのが嫌。てかうっかり名前 被らせて知らぬ間にバグを埋め込みそうで怖い。
そうですか やはり std:: ってやる方がいいですか。 せっかく分けた名前空間をごっちゃにしちゃ意味ないですもんね。 ありがとうございました
>>345 重要なのはコンパイルスイッチでの制御の可否じゃなくて、当時の仕様だ。
>>347 windows.hが通らないだけだった気がする
>349 ヘッダのグローバルな部分ではusing namespaceは使っちゃ駄目、絶対。 でも小さなソースファイルとか、関数単位ならそれほど問題ない。
>>353 自分でも using namespace std; って書いててかなり疑問に感じてました。
名前空間の持つそのものの利点が失われるので。
std:: とその都度打つ方が主流みたいですし、はっきりした利点もあるようなのでこれからはこう書いていきます
>名前空間の持つそのものの利点が失われるので。 名前空間の持つ欠点も失われるけどね。
欠点が失われるのはよいことでは?
ズレたレスにズレたレスがついて 次どうなるかまったく予測がつかなくなった例
得失点差による激しいバトルとなってまいりました
>>357 読んでても一貫して無くて、むきーっとなるなw
360 :
デフォルトの名無しさん :04/08/17 23:40
仕事で、UNIX環境での、C++のコーディングチェック&修正のための、ツールを、作りたいです。 で、やっぱ、こういうのって、文字列操作が、からんで、くるじゃないですか? ってことは、やっぱり、PERLがいいのでしょうか? それとも、C++? 皆さんも仕事で、コーディングチェックのための、ツールを、作っていると、思うのですが、 言語は、何が、おすすめでしょうか?
>>360 文字列操作なんて言ってるようじゃ無理ぽ。
そんなの、先人の作ったオプソのツールを活用せい。
それと、手段を目的にしてるようじゃダメだね。
>>360 > 皆さんも仕事で、コーディングチェックのための、ツールを、作っていると、思うのですが、
作ってないし使ってない。人が作ってるものを探してるなら C++ beautifier あたりで
検索かけてみ。
>>360 コーディングチェックって、具体的にはなにをするの?
ヘンな読点には突っ込まないのか。大人だなおまいら。
365 :
>>360 :04/08/18 00:29
みなさん、レスありがとうございます。 なるほど、人が作っているものが、あるのですね。 そうします。 >ヘンな読点には突っ込まないのか。大人だなおまいら。 すいません、リアル中国人SEなので。 話すのは流暢なのですが、文章苦手です。 在日10年で、この7月に永住許可、もらっちゃいましたよ。(帰化ではないですよ)
>>368 技術者の場でそういうネタを持ち込むはやめれ。
>>370 いやあ、技術に国境は確固として存在するよ。それに伴う偏見や雑言もね
見ていて、ウケないネタほど痛々しいものはないな。
373 :
デフォルトの名無しさん :04/08/18 02:47
質問です。 言語はC++です。 int型の数値をchar型の文字列に変換したいときは どのような関数を作ればよいですか? 同じように、 double→char など。 初心者の質問で申し訳ないですが 宜しくお願いします。
int n = 1; char c = 2; double d = 3.0; c = static_cast< char >( n ); c = static_cast< char >( d ); こういうこと?
>>374 374さんが書いたコードは、
int i;
char j;
j = (char)i;
といったかんじの普通のキャストとは
やはりどこか違うんでしょうか?
>>375 sprintfという便利なものが
あったのですね。
とりあえずがんばってみます!
ありがとうございました。
378 :
デフォルトの名無しさん :04/08/18 03:16
>>458 そういうことなら
ostringstream ってのがある
STLにatoiのc++っぽいのはなかった? boostかな? うわおれc++忘れてる
boostのlexical_castだな。
383 :
デフォルトの名無しさん :04/08/18 14:18
戻り値で構造体を返す場合、どれが最も優れていると思いますか? また他にもっと良い方法はありますか? A get( ){ return a;} const A a = get( ); この方法は値渡しがネックです。 void get( A& a ){ a = b;} A a; get( a ); この方法だと2行必要ですし、constが付けられません。
384 :
383の続き :04/08/18 14:19
A& get( A& a = A() ){ return a = b;} const A a = get( ); この方法はオーバーライドした際、バグの元になりやすいです。 例) A& get2( ){ return get();} A& get( ){ static A a; // TLSでも可 return a = b;} const A a = get( ); この方法だとなんだか無駄が多い気がします。 キャッシュミスも起こりそう。
386 :
デフォルトの名無しさん :04/08/18 15:16
>>383 NRVとは初めて知りました。
自分のコンパイラ(VC)で適用されるのか試してみます。
ありがとうございました。
VCなら条件付で6のころからNRV適用される
C++BuilderはNRVなんて無さそうだな。 あれほんとに何も最適化しないもんな。 定数式の最適化位だろ。
389 :
デフォルトの名無しさん :04/08/18 20:50
自作クラスの複数のメンバ変数から、任意に一つ選んで比較キーとして、STLのアルゴリズムに食わせたい場合どうすればいいの? class Personal { string name, sex, tel, email; int age; } 例えば、こんなクラスで、あるときはnameで、あるときはageでソートや検索をしたいという場合です。 operator== や operator< はクラスで1つしか持てないので、別の比較関数(or関数オブジェクト)を用意する必要があると思いますが、 どこで用意するのが管理しやすいでしょうかね・・・。 マネージャクラスを別に作って、そこにstaticな比較関数を持たせるのが一番楽かなと思っているんですが・・・ class PersonalManager { public: static bool AgeCompareLessl(Personal &p1, Personal &p2){ return p1.age < p2.age} ; } としておいて、 vector<Personal> v; sort(v.begin(), v.end(), PersonalManager::AgeCompareLess); これじゃぁ、あんまり頭よさそうじゃないですよね。 もっといい案あったら教えてください。
struct PersonalComparator { bool operator() (const Personal &p1, const Personal &p2){ return p1.age < p2.age; } } vector<Personal> v; sort(v.begin(), v.end(), PersonalComparator());
×PersonalComparator ○PersonalAgeComparator
>>390 それだとやっぱりメンバの数だけ、関数オブジェクトが出来てしまいますよね。
なんか分散しちゃうのが感覚的に嫌な感じ・・・。
>>392 ありがとうございます。そういう奴がほしかったんです。
templateつかってうまいことできないかなぁと。
とりあえずそこ読んで研究してみます・・・・。
c++でエスケープシーケンスはどうすれば使えますか? printf("\x1b[30m"); とか。 VC++.NETを使っています。
憂鬱とAcceleratedを教えてくれたひと、本当にありがとう。
397 :
デフォルトの名無しさん :04/08/19 00:06
intからstd::stringに変換するにはどうしたらいいですか? ちなみにコーディング規約でsprintf使用禁止になっています。 std::stringにそのようなメソッドはないでしょうか?
istringstream
あ、この場合 ostringstream だね
#include <sstream> #include <iostream> using namespace std; int main(){ stringstream ss; string s; int n; cin >> n; ss << n; ss >> s; cout << s << endl; return 0; }
>>389 メンバ変数ポインタと Boost Bind もしくは Boost Lambda を使う。たとえば名前をキーに
したければ
boost::bind(std::less<string>(), boost::bind(&Personal::name, _1), boost::bind(&Personal::name, _2))
あるいは
using namespace boost::lambda;
bind(&Personal::name, _1) < bind(&Personal::name, _2)
ってな感じで、望みの関数オブジェクトが作れる。
402 :
デフォルトの名無しさん :04/08/19 00:17
立派な規約じゃないか
自由に組ませてやれよ
>>397 sprintf 禁止でも snprintf なら OK とか?
ANSI使うなってことで、wsprintfならいいんだろう
>389 >401 ちなみにlambdaなら using namespace boost::lambda &_1->*&Personal::name < &_2->*&Personal::name こういう書き方もできますよ.
書式設定しなきゃならんし型安全性もないし拡張性もない sprintf なんかいるか!!
>>394 std::cout << "\x1b[30m";
410 :
>>397 :04/08/19 08:04
皆、レスありがとうござ(ry
>>409 できないです。
どうすればいいでしょう。
もしかしてVC++についているコマンドプロンプトみたいのを使ってるから?
412 :
デフォルトの名無しさん :04/08/19 09:37
なんだわかっているじゃん。 VC++付属じゃないけどな。
VC++で直接してもむりでした。 コマンドプロンプトでする方法ないですか?
そもそもエスケープシーケンスはNT系なら不可能。
ANSI.SYSの設定をしたらできるのでは?
ハゲシク デジャヴ
417 :
デフォルトの名無しさん :04/08/19 10:08
(ry
(r
(
424 :
デフォルトの名無しさん :04/08/19 22:01
フフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフウフフフフ
バッファあふれてるぞ?
char* はちゃんと初期化しる! って話かとオモタ。
C++ では for( int i = 0; i < 10; ++ i ){ ... } std::cout << i << std::endl; みたいな風に、for を抜けても i を参照することって許されてるんですか?
>>429 マジデスカ…
おのれ VC7.1 …
他にもこんな方法もある。 #define for if (0) ; else ; for
434 :
デフォルトの名無しさん :04/08/20 09:07
forループのスコープ云々って イテレータが2種以上あるとき無力だにょなあ map::iterator im = m.begin(); for( int i = 0; i < 10; ++i, ++im)... 結局こうなっちゃうし。 俺は古い仕様のままでいいと思うけど。
どっちでもいいけどどっちでもありうるのはいやだ
for ( int i = 0, map::iterator im = m.begin; i<10; ++i, ++im) {} でいいじゃん
for (xxx::iterator it = m.begin(), end = m.end(); it != end; ++it) なら通るんだけどねぇ
vc++.net2003で新しいプロジェクトを作ろうとすると テンプレートが16種類もあるんだけど どれが何用とか決まってんの?
一つは昼用、他は夜用。どれが昼用かは使ってわかってね。
>>436 int i = 0, map::iterator im = m.begin();
が、
int i = 0; int map::iterator im = m.begin();
と解釈されちゃうんだね。
forの初期化部には一つの型しか書けないわけか。
{ //こうでいいじゃん map::iterator im = m.begin; for (int i = 0; i < 10; ++i, ++im) { } }
結論: C++ は糞
Cとかだと普通にやるけどな>ブロックスコープのでっち上げ
スコープ便利やん 人にとって
>434 んなアンコモンケースに対応することの方がどうでもいい。
>>447 そうか?
つーか現状のfor構文の方に
不備があるだろ、どっちかって言うと。
for()内のカンマをセミコロンに、
セミコロンを別の適当な記号に置き換えれば
無問題になるし意味的にも自然だ。
僕のキーボードには適当な記号がありません。
そこでトライグラフですよ。
??=include <stdio.h> int main(int argc, char **argv) ??< printf("%d??/n", argc); ??>
たとえば:とか。
for(map::iterator im = m.begin; int i = 0;)(i < 10)(++i; ++im;) ...
do{ map::iterator im = m.begin; int i = 0;} whlie( i < 10){ ... ++i; ++im;);
int* p = static_cast< int* >( operator new( 10 * sizeof( int ) ) ); operator delete( p ); と、 int* p = static_cast< int* >( operator new[]( 10 * sizeof( int ) ) ); operator delete[]( p ); は何か違いがあるのでしょうか? あるのなら何を基準に使い分ければいいのでしょうか?
456 :
デフォルトの名無しさん :04/08/20 20:35
>>455 reinterpret_cast ちゃうか?
char EndChr[10] = "n"; int flag = 1; if (EndChr == "n"){ flag = 0; } このような式においてEndChr == "n"がfalseになります。 なぜなのでしょうか?
>>457 >>455 のような例では両者に領域の違いも何もないということですよね?
new 演算子で配列を確保場合、必要以上の領域を確保する可能性があると。
>455 そもそもoperator newはnewから呼び出される為の物だということを忘れるな。
>>458 アドレス比較してるから。char[10] の代わりに std::string 使うか strcmp() で比較。
あれ、分からなくなってきた… class C{ ... }; C* p = static_cast< C* >( operator new( 10 * sizeof( C ) ) ); for( int i = 0; i < 10; ++ i ) new( p[ i ] ) C( ... ); ... for( int i = 0; i < 10; ++ i ) p[ i ].~C(); operator delete( p ); と、 C* p = static_cast< C* >( operator new[]( 10 * sizeof( C ) ) ); for( int i = 0; i < 10; ++ i ) new( p[ i ] ) C( ... ); ... for( int i = 0; i < 10; ++ i ) p[ i ].~C(); operator delete[]( p ); はどっちも正しい?
464 :
デフォルトの名無しさん :04/08/20 21:14
アドレスが別だからじゃないの?
>>463 どちらも正しくないんじゃない?動くとは思うけど。
malloc でも動くけどね。
>>465 あ、スイマセン…
new( &p[ i ] ) C( ... );
です
467 :
デフォルトの名無しさん :04/08/20 21:55
>>443 まー確かに、全く平等な条件で選んでた言語かって聞かれると・・・・だな。
市場のデカさは間違いなく判断基準に入ってる。
468 :
デフォルトの名無しさん :04/08/21 00:12
今、C++を勉強しているのですが、オブジェクトが難しくて理解があまりできていません。 それで、オブジェクトの事を詳しく説明しているサイトがあれば、教えて頂けないでしょうか? よろしくお願いします。
「オブジェクトのことを詳しく説明しているサイトを教えてください」 は、人文で言うと、 「文化について詳しく説明しているサイトを教えてください」 くらい、条件が広くて絞り込めない。
>>468 C++関連の書籍を扱っている書店に行ける環境ですか?
Amazonなどの通信販売でも構いませんので、
まずは1冊、自分で良さそうと思った本を読破することをお勧めします。
高くて買えないという場合は、立ち読みしちゃうとか図書館を覗いてみるとか。
時にはネット以外の情報源に当たるのもいいですよ。
471 :
デフォルトの名無しさん :04/08/21 00:52
C++関連の本って大きい本屋じゃないと扱っていないんですよね。でも、探してみます☆ えっと、オブジェクトの事で知りたいのは、オブジェクト=オブジェクトとか、 クラスで、メンバ関数の引数でオブジェクトでの参照渡し、値渡しです。
ありがとうございます!!
今まであたりまえだと思っていたんだけど char hoge[256] = {0}; // hoge文字列の初期化 この書き方って一般的でない? レビューで「わかりにくい」と言われてしまったんだけど。 #memsetやるより良いと思うんだけどなぁ・・・
0限定なら別にどっちゃでも。
char hoge[256]; hoge[0]='\0'; 特に意味が無いのならこうすべきだ。 初期化指定子は無駄な領域も初期化するからな。
char hoge[256] = ""; これで
文字配列ならどうとでもなるな。 でも構造体配列だと・・・
あ、ごめん、ここC++だった。
>>476 char hoge[256];
hoge[0]='\0';
これってVC6のDebug(Releaseでは大丈夫だった)で起動するとこうならない?↓
hoge[0] : 0x00
hoge[1] : 0xcc
hoge[2] : 0xcc
・・・
hoge[255] : 0xcc
まあ、問題はないんだけど・・・。
え、C++でそんなお馬鹿コードが通るなんて聞いたことないぞ。 せめて for (int i = 0; i < 256; i++) hoge[i] = '\0'; だろ。
>>482 じゃぁコードが合っててコメントが糞ってことだな。
0で埋めるコードとしては、
>>474 のものが最も効率が良くなる可能性が高い。
>>483 おまえはたぶん回答者に向いてない。もうちっとROMで雰囲気つかめ。
>>483 C++ならせめて std::fill 使うだろ。
実はCしか知らん >485 テメーで解答してから言え ぼけ
>>483 がレビューで「わかりにくい」と言った人。
文字列操作しかしないバッファなら char hoge[128] = ""; で十分。
comdlgのopenフィルタ(W32API)のように、\0を区切りとして\0\0まで処理するような 関数を想定してるなら全部埋める必要があるだろ。0で埋めるってのはそういう話だと 思ったが。
>>483 1byteずつ初期化すると遅いから4byteか8byteずつ初期化しなさい。
この質問者のレベルだと、多分そこまで求められていない。
>>493 Cしか知らんて、Cでも配列の初期化は={0}で同じことできる。
これが通らないとか言ってるからROMっとけと言ってるんだ。
特殊な文字コードとかも使っていて、ダンプ出力するのに「フ」の字が入るのはちと困ってしまうのですがw
>>489 全部0で埋まりました・・・。こっちの方がわかりやすいかしら?
いや、やりたい事とコメントが微妙にずれてるから「わかりにくい」と言われたんだろ
>>496 いや、意図は、hoge[0] だけ0で埋めるという意味だよ。
全部埋まったのは、そのコンパイラがたまたまそうだっただけ。
俺も{0}で初期化は一般的だと思うけど、 レビューで文句言われたならとりあえず従っておいたら。 コメントが微妙にずれてるのがわかりにくいと言われたのなら直せばいいだけだ。
>>495 知らなかった、正直すまんかった。
で、スレ違いではあるがよければK&Rのどのへんにそういうのが載ってるのか教えてくれないか。
索引で配列関連を引いてみたが見つからなかった。
>>498 了解。コンパイラ依存という事で。
>>497 ,499
実際のコメントは○○文字の初期化、という感じで書いていました。(○○がわかると会社がばれる)
レビュアーの言う通りにmemsetで統一、という事になりそうなので訊いてみた次第です。
たくさんの意見蟻がd。
>>501 P.104〜P.105の
『指定した個数より配列に対する初期値が少なければ、残り要素は外部変数、静的変数および
自動変数については0になる。』
ここかー!ありがとう。ほんとK&Rは隅々まで読んどかないと変なとこで足下掬われるな
あれ、じゃあ = ""; も = {0}; と同じ扱い?
ちがうか。 "" の先頭アドレスから連続したメモリ領域がコピーされるんかな?
>>498 読め。だからおまえはちゃんとROMれよ!
std::fill使えって言う意見が1つだけってのも悲しいなぁ 所詮STLの知名度なんてそんなもんなんですな
なんです。マジでw。 ちょっと混乱中。
>>507 データ構造関係は、ほぼ使ってますよ。
Boostも使いたかったけど「実績」を証明するのがめんどくさかったので諦めましたが。
>>508 VC6 VC7 mingw gcc にて確認、全部0で埋まりました・・・。
すいません勘違いしました。 ={0}と=""は同じです。 どっちも={'\0'}です。
むしろhoge[128]={}で
>>507 なんで既出の意見を何度も繰り返す必要があるよ?
つうかこの場合={0}がstd::fillよかいいだしょ。
>>512 激しく同意。とでも言って欲しかったんじゃないか。
寂しい奴なんだよ。
>>498 コンパイラ依存じゃねーよ
{0}は残りの配列の要素(クラス、構造体のメンバ)も0で埋める。
516 :
デフォルトの名無しさん :04/08/21 05:31
メモリプールを作っていて疑問に思ったのですが、 Point* pt = (Point*)new char[sizeof(Point)]; *pt = Point(10, 10); delete [] pt; 1). 2行目のコードででptのコンストラクタが呼ばれますが、 ptはビット的な変化はあるんでしょうか? 2). ptのアドレスは変わらない様ですがこの行為は正当でしょうか?
char* buffer=new char[sizeof(Point)]; Point* pt=new(buffer) Point(10, 10); pt.~Point(); delete[]buffer; こういうことがやりたかったんじゃないのかい?
藻前ら、初期化の方法にこだわるのも結構だが、 あまりエレガントな記述を追求しても、 同じデータを再初期化する時に破綻するのがわかってんだから、 大人しく一般的な初期化をしとけ。 memset、ZeroMemory、std::fillで決着。 反論は受け付けない。以上。
>>474 知名度はそんなに高くないから「わかりにくい」という意見には
一理あるかもしれんけど、だからと言ってそこで memset を使う理由にはならない。
オーバーロードは分かりにくいから使用禁止って言うのと同レベルだよ。
>>519 最初期化、それは名高い変数の使いまわしと言うものですか!?
>>521 変数使いまわしも何も、クラスのメンバ変数が思い切り該当するっしょ。
std::fillってコンパイラちゃんと最適化してくれんの?
524 :
デフォルトの名無しさん :04/08/21 10:06
>>520 まったく同意見
519は論点ずれてるうえ
反論は(ry とわざわざ自爆する奇特なピエロ
525 :
デフォルトの名無しさん :04/08/21 10:09
>>523 それはやってみるしかない
同じ処理系でも条件次第で違ったりもする
アセンブラ読めない人と、実測できない人は、蚊帳の外
> 大人しく一般的な初期化をしとけ。 > memset、ZeroMemory、std::fillで決着。 これらは一般的な「初期化」ではない。 未初期化のPODに対して行う場合に限定して 「初期化」と呼べるかもしれない、くらいのものだ。
vector::clear
529 :
デフォルトの名無しさん :04/08/21 15:20
std::stringからchar配列に変換しようとすると、変換できませんとコンパイラが言います。 具体的には、 char hairetu[256]; std::string str = "ぬるぽ"; hairetu = str.c_str(); これでいけると思うのですが・・だめなのでしょうか・・・
strcpy(hairetu, str.c_str());
531 :
デフォルトの名無しさん :04/08/21 15:21
>>529 ネタ?
配列名には代入できない。strcpyを使え。
>>529 だめです。
char配列を文字列として使うなら、C言語の文字列処理を知るべきです。
>std::string str = "ぬるぽ"; ↓ >std::string str("ぬるぽ");
いつも思うんだけど、
>>529 の類ってどう考えてもネタだと思う。
文字列処理なんてどんな入門書にも書いてるし、これ間違えるなんてあり得ない
std::copy(str.c_str(), str.c_str() + str.length() + 1, buf);
std::copy(str.begin(), str.end() + 1, hairetu);
>535, 536 buffer overrun が気になる
539 :
>>529 :04/08/21 15:42
どうも、ありがと。 自分C++ラーなので、知りませんでした。 まじで、ネタじゃありませんが(あせ
std::copy(str.begin(), str.end(), hairetu); henkaku[str.length()] = '\0';
henkaku じゃなくて hairetuだた。
C++ならこうだろ。 std::vector<char> hairetu(str.begin(), str.end()); hairetu.push_back('\0');
こっちのが効率がいいかもね。 char const* const c_str = str.c_str(); std::vector<char> hairetu(c_str, c_str + str.length() + 1);
そういうのを見ると、Cを暗号化したものがC++と思えてくるな。
>>529 char carray[256];
std::string nullpo("ぬるぽ");
std::istringstream strstrm(nullpo);
strstrm>>setw(sizeof(carray))>>carray;
char *bgn = str.begin(); int len = std::max(str.length(), sizeof(hairetu) - 1); std::copy(bgn, bgn + len, hairetu); hairetu[len] = '\0';
minじゃね?
>>547 勝手に後ろを切り捨てちゃまずいだろ。
char hairetu[256];
if(str.length() >= sizeof(hairetu)) throw std::range_error("長すぎ");
strcpy(hairetu, str.c_str());
2chネラほどじゃないさ。
552 :
デフォルトの名無しさん :04/08/21 16:45
インクルードの次の行に gap::sweet texture; という記述があるのですが、 これはどういう構文なのでしょうか? 初心者で申し訳ない。
>>552 名前空間(またはクラス型) gap のメンバである sweet 型の変数 texture の定義。
インクルードの次の行であることには意味が無い。
554 :
デフォルトの名無しさん :04/08/21 16:48
グローバル変数ですよ
555 :
マイク ◆yrBrqfF1Ew :04/08/21 16:54
//header namespace gap { typedef void sweet(); } //sourcefile gap::sweet texture; //declare //omit gap::sweet texture //def { std::cerr<<"\0m0th3rfuck3r"<<std::flush; std::teminate(); }
つまり、 名前空間 gap のメンバである sweet 型の変数 texture を グローバル変数に定義しているということで間違いないでしょうか?
失礼。間違い。
ヘッダファイルの中で namespace gap{ void sweet::print() } としておいて、ソースの中で gap::sweet texure texture.print() となっているのですが、これは sweet型の変数textureがprint()という関数を 呼び出しているということであってますでしょうか?
>>559 いや、それだとコンパイル通らないはず。
ところで、そのプログラム全部ここで解説させるつもりなのか?
>>523 char*に対するfillはmemsetで特殊化している実装が多いです
>>562 大学卒業してないよ。
頭悪そうだと思っていたが、もういいかげん頭悪いんだとわかった。
もう触りません。スレ汚して悪かった。
566 :
デフォルトの名無しさん :04/08/21 17:19
えっと、C言語を使って現在ゲームをコツコツと作ってるのですが 複雑になるにつれ、クラスに纏めたいと思い、C++に手をだしました。 ただ、CもC++もまだ初心者で、中々苦労しています。 特に困っているのが、何をクラスにして派生クラスは何になるのか、メンバは何を持たせるか みたいな部分が中々把握できません。 基礎的な書き方のようなものは、本を買ってプログラム組んでみました。 こういったことに慣れるための良い練習法のようなものがあれば教えてください。
俺もコテハンデビューする
>>567 包含関係に気を配るとよろしいかも。
あと、Effective C++あたりが定番かな。
>>573 探してる暇があんなら、さっさとamazonで注文しろや
ただでさえ馬鹿が多いのにうんざりするのが一人増えたな。
578 :
デフォルトの名無しさん :04/08/21 21:10
以下の関数を修正して、標準出力ではなくて、st::stringに出したいのですが、 どのようにすればいいんでしょうか・・・ void Hage::OutLog(const char* fmt, ...) { va_list argp; va_start(argp, fmt); vfprintf(stdout, fmt, argp); va_end(argp); fprintf(stdout, "\n"); }
579 :
デフォルトの名無しさん :04/08/21 21:12
std::stringにタブがあるかどうかを調べるにはどうすればいいですか? std::string sss; sss = "abc<TAB>bbb"; ※<TAB>は制御コードのTABだと思ってください。 で、このストリングを、 sss.find();で見つけたいのですが、どうすればできますか? そもそも、find()で制御コードを検索することってできるのでyそうか?
cppllでつまんねえ喧嘩してるぞ。どっちもどっちだな。傍から見ていると。
>>578 vsprintfでも使え
>>579 if(sss.find('\t')!=std::string::npos)//見つかった
>>579 >※<TAB>は制御コードのTABだと思ってください。
嫌です。
>>580 典型的な宗教論争だね。2ch なら煽り入れて楽しむところだが。
11056 にはビックリしますた。
>>580 ,
>>585 そんなこと言ってないでお前らも参加しろよー
ほれ、よく言うじゃん、「踊る阿呆に、見る阿呆。同じ阿呆なら踊らにゃそんそん。」って。
その阿呆と違って本物の阿呆だから 触りたくないです
>>587 漏れにレスしたのは触ったことにならんの?
お前も阿呆、決定。
国語能力なさ過ぎ
道化師さんキター? VC6のときにお世話になりますた。
>>586 その「踊る阿呆に・・・」って阿呆なのが前提じゃないと意味無いと思う。
592 :
デフォルトの名無しさん :04/08/21 23:07
11063は、背伸びしすぎだな。 たぶん放置されるはず。
cppllの話題なぞ持ち込まんでくれよ
594 :
デフォルトの名無しさん :04/08/21 23:15
キモヲタ同盟に名称変更希望。
>>590 以前からちょこちょこ書き込んでますよー
なんかスレ汚しになっちゃったんでお暇しますー
|ω・)ノシ お休みなさいー
要するに 「継承するとき、いちいち基底クラスのprivateな定義まで読みたくねーよ」 って事か。 俺もprivate virtual使いだけど、一理ないこともないかも。
>>private virtual 見なくていい(普通の)privateとは分けて、しっかりコメントつけておかないと、 読み飛ばされる可能性が高いね。 ただ、C++使いとしては、アクセス指定とvirtual指定とが まるで関係ないということは知っておいて欲しい。 public virtual を派生先で private にしてオーバーライドとか、 逆に private virtual を派生先で public にしてオーバーライドとか、 いくらでも有り得るし、相応の効果がある。 実際に役に立つかとか、良し悪しはまた別にして。
>> private virtual @ cppll Doxygenのようなドキュメント生成ツールでは一般的にprivateなメンバは ドキュメント化されない。 だからドキュメントを信じてコーディングすると予期せぬエラー をうけることになるわけだ。だからprivate virtualはイクナイ。 でも、やる人の気持ちがわからないわけではない。 やるなら何らかの形で明示的に示してほしいなぁ。
>>598 そりゃDoxygenの問題だろ。提案すれば対応してもらえそう。
VC8、未だに例外仕様はnothrowしか出来ねぇ_| ̄|○
601 :
デフォルトの名無しさん :04/08/22 01:29
string ss = "aaaabbbb"; から、aaaaとbbbbを切り取って、それぞれstringに格納したいのですが、 いい方法はないでしょうか?
>>601 std::string::substr()
603 :
デフォルトの名無しさん :04/08/22 01:38
>>599 ありゃ? いいたいことが伝わんなかった…。
Doxygenでもprivateなメンバをドキュメントに含めさせることは可能なはず。
言いたいことはそれが可能かどうかではなくて、すべきでない場面が多々あるってこと。
例えばなんらかのライブラリを作って、それ用のAPIドキュメントを作るときは
privateなメンバを含めないでしょ、多分。
だって、それを使用するユーザは内部でのみ使用されるprivateなメンバを
意識する必要は無いし、しちゃいけない。
ところが、そのライブラリの中にprivate virtualな関数があると、ユーザ
privateな関数まで見てコーディングしなくちゃいけなくなる。
問題ありだよね?
>>604 C++ではprivateでもvirtualであればユーザーに関係有るんだから、
ドキュメント作るなら含めないといけないだろ。
Doxygenがそれには対応してないだけ。
private virtualが否定される理由としては理不尽。
>>604 template メソッドの場合は、規定クラスの公開メソッドのドキュメントに
「派生クラスでこれこれのメソッドをオーバーライドすること」と書くから、
大差ないと思うが。
なんにしても、どっちでも良いよ、そんなの。
>>605 そもそもprivate virtualの是非について話しているのに
>C++ではprivateでもvirtualであればユーザーに関係有るんだから、
という前提を持ち出すのも理不尽。
俺はprivateなのにユーザに関係することが問題だと思う。
多分、これはpublic, private等の捉え方の違いなのかな?
俺はクラスの使用者に対する可視性だと思っているから、privateなのに
使用者に見えることが気持ち悪い。
これを可視性ではなくてアクセス権として捉えるとprivate virtual肯定派
のいいたいことが理解出来る。
なんだかんだ言って
>>606 >なんにしても、どっちでも良いよ、そんなの。
に賛成。 消えます。
なんだ、せっかく飛び火したのにもう鎮火したのか?
>>600 nothrow は最適化に使えるけど、他の例外指定って使う価値あるか?
未処理例外で死ぬか、terminate() で突然死するか程度の差しか無いような。
C++はデフォルトの例外指定が throw(...) なので
一箇所でも指定していない関数があると誓約が途切れてしまうし。
>>609 void hoge(){ throw; }
set_unexpected( hoge );
で
C++ って、 class C { ... struct CImpl; CImpl* pimpl_; }; を class C { ... struct CImpl* pimpl_; }; と書く事って認められてるんですか?VC7.1じゃコンパイル通んないんですが…
あ、コンパイラ通らないってのは struct C::CImpl{ ... } ってやるとです。。
struct C::CImpl {} <-なにこれ? CImplはどこで定義してんの?
>>613 ;が抜けてるけど,それがCImpl(Cのインナークラス)の定義ってことなんでしょう.
gccだとこんな感じ.規格では???
class C {
struct CImpl; // (a)
CImpl* pimpl_; // (a)
struct CImpl* pimpl_; // (b)
};
struct C::CImpl {}; // (1)
struct CImpl {}; // (2)
(a)-(1) ○
(b)-(1) ×
(a)-(2) ○
(b)-(2) ○
>>614 Exceptional C++ では通して
(b)-(1)
の形式で書かれてるのですが、規格ではどんなもんでしょう…
struct CImpl* pimpl_; これは宣言じゃないんだから、 b-1が不可能なのは当然でない?
>>616 その説明だと本来は(b)-(2)も通っちゃいけないってこと?
質問です。 virtualなデータメンバって何故できないのでしょうか? あれば便利だとおもうのですが。
ちょっと「便利な状況」が思い付かないなぁ。 たとえばどんな感じに使いたい?
>618 いったいどういう挙動をするものなのか、まるで思いつかない。 protectedメンバ変数とか、参照を返すvirtual関数で満たされないものなのか?
>>617 (b)-(2)は(2)で宣言と定義を同時に行ってるんだから、問題ない。
>>618 参照を返す virtual メソッドで我慢しとき。
>>622 なるほど.616を理解できました.
>>615 Exceptional C++は誤植なのかもしれないですね.
>>624 > Exceptional C++は誤植なのかもしれないですね.
例えば何ページ?
みなさん、いろいろ意見ありがとうございます。やりたいことはこんな感じです
// あるライブラリで定義されてるクラス
class B {}
class B1 : public B {}
class B2 : public B {}
// 自分のクラス
class A
{
vritual B b:
void proc(){ b に対して色々な処理}
}
class A1 : public A { B1 b1;}
class A2 : public A { B2 b2;}
みたいな感じです。
>>623 >参照を返す virtual メソッドで我慢しとき。
この方法がよさげなので、ためして見ます。m(_ _)m
627 :
デフォルトの名無しさん :04/08/22 11:29
>>626 class B { virtual void age() = 0; };
class B1 : public B { void age() { fusianasan(); } };
class B2 : public B { void age() { mokorimoko(); } };
class A
{
B* sage;
void proc() { sage->age(); }
};
class A1 : public A { A1() { sage = new B1; } };
class A2 : public A { A2() { sage = new B2; } };
>>627 あ〜あ〜ぁあ〜ぁあ〜ぁあぁ。正にその通りです。
最初からインスタンス作ろうしたからダメなんだ。orz
muchas gracias、merci beaucoup、danke schon、grazie mille、非常感謝
>>611 上が class C 内に struct CImpl を宣言している。
下がグローバル名前空間に struct CImpl を宣言している。
初めて class/struct XXXX の形で現れた名前の宣言されるスコープは、
それが他の宣言中に含まれるか、単体で文になっているかで変わるらしい。
詳しくは規格の 3.3.1 -5- 。
ちなみに friend 宣言のときはまた別のルールになる。
>>627 class A
{
virtual B& sage() = 0;
void proc() { sage().age(); }
};
こっち(参照を返す virtual メソッド)のほうがいいと思う。
>>631 ポインタを保持するサイズが節約できる。
(
>>627 の例ではvtableと相殺するが、たぶんAにはvirtualなデストラクタが必要だろう。)
所有権の混乱を避ける。
(
>>627 のコードでnewしたB1,B2をだれがdeleteするべきなのか不明。)
ポインタへの代入忘れを防げる。
>>632 大したメリットが無いな。
sageオブジェクトが必要な時に、毎回仮想関数経由での取得による速度低下の方が俺は心配だ。
仮想関数での速度低下は都市伝説 本当にそれがネックになるケースは、プログラム効率で有名な話の8:2より はるかに小さいんだから、あんま気にしてもしょーがないだろ
実装やテストの効率を気にしたほうがいいな
636 :
デフォルトの名無しさん :04/08/22 15:51
std::stringクラスのfindメソッドで" - "を検索したいのに、"-"として検索されるみたいです。 " - "のような、空白を含む文字列を正しく検索するにはどうしたらいいでしょうか? string sss = "100-100"; sss.find(" - "); で検索すると、検索できてしまうのです・・・ORX
>>636 見つからなかった時の戻り値が string::npos だってのは知ってる?
638 :
デフォルトの名無しさん :04/08/22 16:00
(" - ") ↑顔文字に見える
検索されないけど。 - STLPort4.6.2
640 :
デフォルトの名無しさん :04/08/22 16:01
641 :
デフォルトの名無しさん :04/08/22 16:02
strstr(sss.c_str()," - ");
642 :
デフォルトの名無しさん :04/08/22 16:03
643 :
デフォルトの名無しさん :04/08/22 16:06
>>636 「検索できてしまう」って、 find() の戻り値はどうなってたの?
std::string sss( "100-100" ); std::string nlp( " -" ); std::search( sss.begin(), sss,end(), nlp.begin(), nlp.end() ) == sss.end(); これでは?
647 :
デフォルトの名無しさん :04/08/22 16:16
>>644 戻り値は"-"のある場所の3です。
>>643 はっとりくんって忍者はっとりくんのことじゃないですか?
648 :
デフォルトの名無しさん :04/08/22 16:18
649 :
デフォルトの名無しさん :04/08/22 16:19
実際にコードを書いた人は無視
>>647 検索されなかったって言っただろ。
いや、検索は出来たな。マッチはしなかったけど。
恥ずかしいんだけど、STLのバージョンってどう調べるの?
製品によって違うし 仕様のバージョンとかリビジョンならあるんだろうけど(auto_ptrとか) 番号がついてるかはわからん。
653 :
デフォルトの名無しさん :04/08/22 16:31
>>651 STLのバージョンってVC++のバージョンそのものじゃないの?
私の認識では、STLはVC++そのものということになっている。
ずいぶんいい加減なライブラリだな
>>630 >>631 さん
いちおう、目的は「Bに対する諸々の処理を一箇所にする」なのであとは
どっちが良いか色々ためしてみます。ありがとう。
そういやstd::strstrの第一引数の文字列が'\0'で終わってなかったら どうなるんだろうな?
>>636 使ってるコンパイラで↓のプログラムの実行結果を確認してください。
ちなみに g++ (GCC) 3.3.3 (cygwin special) では not found になります。
#include <string>
#include <iostream>
int main()
{
std::string s = "100-100";
std::string::size_type p = s.find(" - ");
if( p != std::string::npos ) std::cout << p << std::endl;
else std::cout << "not found" << std::endl;
return 0;
}
どうでもいいが、 cygming special じゃない?
>>658 お?そういえば前はそうだったような気がします。
でもこれは g++ --version からコピペしてます。
こないだ入った更新をインストールしたから、それで変わったのかもしれません。
660 :
デフォルトの名無しさん :04/08/22 17:48
>>657 様
自分の環境でためしたところ、not foundになりました。
findでは空白文字を含む文字列の検索は正しくできるけど、
find_last_ofは、空白文字を含む文字列の検索は正しくされないのでしょうか?
>>660 なんで
>>636 の時点で find_last_of() と書かなかった?
find_last_of() の仕様知ってるのか?
欲しいのは rfind() じゃないか?
662 :
デフォルトの名無しさん :04/08/22 17:55
これ、年金の財源にしようぜ
みすだす。。。すまそ・・・
665 :
デフォルトの名無しさん :04/08/22 18:30
template <class T> inline T* Create() { return new T; } こんな感じの関数を見たんですけどこれはどうやって呼び出すんですか?
int * hoge = Create<int>();
夏なんていらない
最近暑かったしね
672 :
デフォルトの名無しさん :04/08/22 19:23
熱雑音が強いな
673 :
デフォルトの名無しさん :04/08/22 20:22
virturalを指定しない(メンバ)関数って(派生クラスのメンバ関数で)オーバーライドできないの? テストコードを実装できるスキルがまだないので教えてください。
>>674 スキルがないんだったら今知らなくてもいいこと
答えは出来ません
非仮想関数の再定義が起こるようなら設計を見直すべき
>>675 ありがとうございます。
不安なら現時点ではvirtual指定しておいたほうが嬉しいことが多い、という理解で勉強を進めます。
677 :
デフォルトの名無しさん :04/08/22 20:39
>>676 という理解はお勧めしない。
virtual になれないメンバや virtual が効かない場面で
かえって深い混乱の原因になるからだ。
根を理解せずに使いたい人には C++ は向かない。ここを忘れるな。
>>676 そもそも、やたらと継承するな。てきとーに設計して、てきとーに継承するから
オーバーライドできるか否かで悩むことになる。
>>678 オーバーライドされる可能性があるメンバ関数と、未来永劫絶対にオーバーライドされない
メンバ関数を見分ける方法があったら教えてください。状況に依存とかいうのはナシの方向で。
素朴でアホな疑問すぎてスルーされてる? こういう疑問って無用なのかな・・・?
>>680 自分が今何を作っているのかを考えたら答えでるだろうが
場を見誤ったようです。すみません。無視して下さい。
685 :
デフォルトの名無しさん :04/08/22 21:14
>>681 いや、ご尤もな質問だぞ?
本気で聞くがまじめに考えたことあるか?? いや現在形で考えてるか?
688 :
デフォルトの名無しさん :04/08/22 21:35
689 :
デフォルトの名無しさん :04/08/22 21:38
このスレは末端のコーダが多いみたいだなw 設計なんか考えたこともない奴隷は気楽でいいよなw
690 :
デフォルトの名無しさん :04/08/22 21:42
>>688 何でそこで Java が出てくるんだよスカタン
692 :
デフォルトの名無しさん :04/08/22 21:47
>>691 dat落ちしているスレッドにリンクを貼っても見られないから、コピペしてくれ。
693 :
デフォルトの名無しさん :04/08/22 21:51
>>692 27 名前:デフォルトの名無しさん 投稿日:04/02/29 16:48
当方、以下のコードが通りません。どこが悪いかご指摘願います。
Metrowerks CodeWarrior 8.2 Pro for Winを使っております。
(hello.cpp)
class hoge
{
public:
hoge();
~hoge();
private:
struct impl* pimpl_;
};
struct hoge::impl{};
hoge::hoge() : pimpl_(new impl){}
hoge::~hoge(){delete pimpl_;}
int main()
{
hoge hage;
return 0;
}
694 :
デフォルトの名無しさん :04/08/22 21:51
693の続き (メッセージ) エラー: 宣言シンタックスエラー hello.cpp 行: 9 struct hoge::impl{}; エラー: 宣言シンタックスエラー hello.cpp 行: 10 hoge::hoge() : pimpl_(new impl){} 警告: 不完全な struct/union/class 'impl' の使い方が不当です。 hello.cpp 行: 11 hoge::~hoge(){delete pimpl_;} ちなみに struct impl; impl* pimpl_; とあらかじめ宣言すれば通ります。
規格の 3.3.1 ってどこで見られる? ググっても出てこねぇ…
698 :
デフォルトの名無しさん :04/08/22 21:58
あの時に解決したのはしたのだけれども、明確にどのようなときに globalでどのようなときにinner classなのか、また規格のどこに 根拠があるかがはっきりしたということで。
Exceptional C++ はなんだったんだろう… 本一冊を通してコンパイラを通らない規格外のコードを載せてたことになるが
>>700 いや、はっきりしてただろ。
28 名前:デフォルトの名無しさん[sage] 投稿日:04/02/29 17:16
>>27 'struct impl'の形はelaborated-type-specifierといって、でてくる文脈によって働きが微妙に異なる。
struct impl;
とかくと、そのスコープでimplが宣言され、
struct impl* pimpl_;
とかくと、「そのスコープを含む、最も内側の、非クラス、且つ、非関数宣言の」スコープ(この場合はグローバル名前空間)
でimplが宣言されたことになる。
詳しくは規格の3.3.1の5を参照すべし
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
703 :
デフォルトの名無しさん :04/08/22 22:22
例外だもん
下記要件を満たすスマートポインタの実装って無いですか? ・参照はリンクリストで管理(使用に付随するnewや埋め込みカウントが無い。) ・スマートポインタ間での自動アップキャスト可能 ・明示指定時のみスマートポインタ間でダウンキャスト可能 ・関数内定義クラスのポインタのハンドリング可能 なんか最後のが無理っぽい気もするんですが、どうなんでしょう?
newしないって?!
707 :
デフォルトの名無しさん :04/08/23 04:56
Foo a(10); Foo b = Foo(10); bの場合は一時オブジェクトが作成されてコピーコンストラクタによって、 メンバがコピーされますよね。 効率面から言えばbは非効率でしょうが、 bのような初期化を積極的に利用する状況ってどんなものがあるんでしょうか?
>>707 テンポラリが作られる場合、コンパイラはそれを積極的に最適化出来る
RVO でググれ
RVO→More Effective C++の第20項
VC++について調べたい人は、
http://blogs.msdn.com/slippman/archive/2004/02/03/66739.aspx g++のswitch
`-fno-elide-constructors'
The C++ standard allows an implementation to omit creating a
temporary which is only used to initialize another object of the
same type. Specifying this option disables that optimization, and
forces g++ to call the copy constructor in all cases.
規格的には、12.8.15。
あと、 T t( u ) を T t = u の代わりに使うのが普通。 T t = u は operator = ではなくコピーコンストラクタによるので混乱させやすいし。
RVOによる最適化を前提とすればaとbは効率面では変わらないって事ですよね。
あとは
>>710 氏の言うように可読性の向上ってくらいなんでしょうか。
privateなメンバをヘッダに書くのってどうなんでしょう。 たとえば、WindowsでIShellFolderを抽象化したディレクトリクラスを作るとして、 class directory { IShellFolder* sf; public: ... }; とすると、このクラスのクライアントコードがIShellFolderに直接触れなくても、 このヘッダを使うソースではIShellFolderを含むヘッダをincludeしないとならなくなりますよね? それを避けるための手段のひとつにpimplとかインターフェイスベースってのがあるんでしょうが、 手間も掛かるし、なんかどうも納得いかないんですよね。
>>712 インターフェースベースだと実装が変わってもクライアントの再コンパイルが必要ないな。
使うのは自分の中だけ。DLLなどで外部に公開しないんならメンバを含めてもいいと思うけど。
まあ、この場合みたいにポインタメンバだったら、先行宣言するだけで 実装の詳細が含まれるヘッダをincludeする必要はないけどね。 そしてその考え方の延長上にpimplがあったりする。 インターフェイスクラスはまたちょっと考え方が違うけど。 で、privateメンバも含めて実装の詳細をヘッダ(class定義)に書かなきゃいけないのは C++の採った効率上の妥協だと思われる。 すぐわかる利点のひとつに「スタック上に生成出来る」点がある。
715 :
デフォルトの名無しさん :04/08/23 18:16
>>702 あれっ、脳みそが解決前にタイムスリップしてた。回答してくれた人スマソ
BCCの「プロジェクト設定 - リンク」で dxguid.lib dxerr9.lib d3d9.lib d3dx9.lib をリンクしる
>>717 BCCはBCCDeveloper(?)を使わずにコマンドラインでやっているので
プロジェクトの設定とかないんです。
どうしたらいいのでしょうか?
マニュアルを読んで調べてくれい
>>719 ありがとうございます!
なんとかできました!
通常のコンパイル時のコマンドの後に
>>717 のライブラリ名を並べて書いたらできました。
bcc32 -W -emain.exe main.cpp c:\dxsdk\blib\dxguid.lib c:\dxsdk\blib\dxerr9.lib c:\dxsdk\blib\d3d9.lib c:\dxsdk\blib\d3d9.lib
となってかなり長くなりましたが。
でもわざわざこれを書かなくてはならないということは、
bcc32.cfgやilink.cfgでDirectXのライブラリの設定した意味があるのでしょうか?
標準C++以外の環境依存はスレ違いだぞっと。 で、bcc32.cfgに-Lをつけてディレクトリを指定し、 #pragma comment(lib,)を書いたヘッダでも用意しときゃ 少しは楽になるんじゃないかな。
非テンプレート関数でコレクションクラスを返すときってどうするのがいいんでしょうか? std::vector<int> func(); void func(std::vector<int>& collection); の二通りがすぐに考え付くのですが、後者の場合funcの中でclear()するべきなのか、 それとも後ろに追記するべきなのか。 コメントに書けばいいというのはそのとおりなのですが、前者ならその辺迷わないので悩みます。 std::auto_ptr< std::vector<int> > func(); というのもアリなんでしょうが、あまり誉められた形じゃない気もするし・・・
>>722 後者にして、後ろに追記する機能を関数としておけば、
clear() すべきかどうかは使う側で選べる。
あとは適切な関数名を与えてコメントは不要にすればいい。
724 :
デフォルトの名無しさん :04/08/24 11:29
C++でファンクションポインタはどう定義しますか? voidポインタは駄目みたい。
Cと同じ メンバ関数なら::*
>>722 俺は必ずin、out、inout修飾子をつけてる。COMのパクリね。
outならコレクションは初期化される、inoutなら初期化されない。
void func(/*[out]*/std::vector<int>& collection);
コメントアウトするするより#define OUTとかの方が良くないか?
>>727 726 じゃないけど、COM 相互運用のコードでは interface の宣言のときに
>>726 のような
コメントにするのがデファクトなので、それに則ってるわけです。
(要するに RPC の idl 風の記述にしてるわけ)。
別にそんなもんついてなくてもconstなしの参照/ポインタはout扱いでいいだろ。
>>730 [in, out] ってのもあるし。既存の何かを更新する関数とか。
サンクス
>>725 Cの関数ポインタ調べて書いたら通ッタ
733 :
デフォルトの名無しさん :04/08/24 13:18
C++の文法を覚えたんですが、次に覚えるのはなんですか?
>>733 STLとMFC。
STLは必須だから。
MFCは学習意欲を維持するため。
自分で課題を見付けることを覚えたほうが将来的には良い マジレス
>>733 決まったカリキュラムは無いから、好きにやってくください。
738 :
◆Z0vd5w812U :04/08/24 13:29
>>733 やる気を維持するために、見栄えがあるDirectXアプリ。MFC使って。
その後MFCを捨ててWin32で作る。
739 :
デフォルトの名無しさん :04/08/24 13:36
SWIGという環境を使うと、各種スクリプト言語からC++関数を呼べるようになると思うんですが 逆にC++ベースのプログラムから各種スクリプト言語を呼んでインタプリタ等で解析する、 そういうライブラリってありますでしょうか? Tclという言語は出来るようですが、RubyやJavaScriptのようなOOPがいいんですが。
Luaは組み込める
741 :
◆Z0vd5w812U :04/08/24 13:41
>>739 system()。
CreateProcess()でもいいかもしれない。
Ruby含めていくらでもそういうものはある。
>>739 Windows だけでいいなら ActiveScript で JScript や VBScript とかが使える。
Netscape 由来の Spidermonkey (JavaScriptエンジン) も悪くない。
745 :
デフォルトの名無しさん :04/08/24 14:03
746 :
デフォルトの名無しさん :04/08/24 15:11
スレ違いな質問によく丁寧に答えてやるな。
開き直ってる奴がいるな
>>733 KDE使ってQt+OpenGLでいいだろ。
いささかあれだが。
でもあれをスレ違いと言ったら それこそC++の文法ぐらいしか質問の幅がなくなると思う。 それはそれで不便だと思うけど。
質問です。
以下のコード(
>>752 )をコンパイルすると二つのエラーが出ます。
エラーの内容は下の通りです。
(1) エラー
request for member 'action' in 'sclass()', which is of
non-aggregate type 'SampleClass ()()'
(2) エラー
request for member 'doAction' in 'uc(SampleClass (*)())',
which is of non-aggregate type 'UserClass()(SampleClass (*)())'
この二つのエラーは同じ系統のものかと思いまして、一度に質問させて
いただきました。何かヒントか検索キーワードでも良いので、なぜ
これがエラーになるのか教えていただけないでしょうか。
特に(2)のエラーは納得できません。代替策はあるのでしょうか?
コンパイラ:g++ (GCC) 3.2.2 Red Hat Linux
752 :
>>750 からの続き :04/08/24 19:46
----------------------------- コードここから #include <string> #include <iostream> using namespace std; class SampleClass { public: SampleClass() {} void action() {cout << "SampleClass::action" << endl;} }; class UserClass { SampleClass sc; public: UserClass(SampleClass sc_) : sc(sc_) {} void doAction() { sc.action(); } }; int main(int argc, char *argv[]) { SampleClass sclass(); // SampleClass sclass; とすればエラーは出ないが、上記のように // 宣言しても引数無しのコンストラクタが呼ばれると思ったのですが… sclass.action(); // (1) エラー UserClass uc(SampleClass()); uc.doAction(); // (2) エラー } ----------------------------- コードここまで
>>753 C++ の最も奇妙な解析にはまっちゃってるな
なんか日本語だとむかつくな
>>751 スレの書き方・質問の仕方から察するに、プログラマに向いてない。
それが一番の問題。巻き添えを食うであろう同僚PGが気の毒。
>>751 こりゃまた強引なネタで C++ の話題に戻しにかかってきたねぇ・・・
もしネタじゃないなら、ネタじゃありません、とか書いておいた方が良いよ。
>>754 そうなんですか?
なにがおかしいのでしょう。
>>758 C++の話題に戻すのが目的でもありませんし、ネタでもないのですが
なにがおかしいのか教えていただけませんか?
みなさんのレスから想像すると、何か変なこと聞いてます、俺?
SampleClass sclass(); これは関数宣言
Exceptional C++ 項目42参照
>>756 のような態度を取る奴の同僚PGの方が、オレは気の毒だと思うな。
省略時コンストラクタがないクラスで operator new std::get_temporary_buffer どっち使うのが主流?
>>761 756 じゃないけど「・・・と思った」とか「納得いかない」っていうのは、
自分でアレコレ調べてみる動機としては結構だけれども、
単に「・・・と思ったけど違った。納得がいかない」っていう質問はちょっとアレだろ、
訊かれたほうも困るだろ、ということでは?
>>751-752 ちなみにエラーの意味はだいたいこんなところ。
(1) エラー
非集合体の型 'SampleClass ()()' として定義された 'sclass()' に対して
メンバ 'action' が要求されました。
(2) エラー
非集合体の型 'UserClass()(SampleClass (*)())' として定義された
''uc(SampleClass (*)())' に対してメンバ 'doAction' が要求されました。
レスしてくれたみなさんありがとうございます。
>>760 あ、言われてみればそうですね。
ということは
>>753 のいう奇妙な解析というのはこれのことだったのですね。
実引数の無い時は関数宣言と解釈されるから、そのときは特別扱いで
空の括弧はなし、と。
ということは(2)に関しても
UserClass uc(SampleClass());
SampleClass()という関数として解釈されてるということでしょうか?
しかし、次の行のuc.doAction()をコメントアウトするとコンパイル&実行
できます。ただし、SampleClass::SampleClass()は呼ばれていないようです。
こちらはどういうことなんでしょう。
>>762 (More) Effective C++なら持っているんですが、その本は持っていません。
明日大至急立ち読みしてきます。
>>766 UserClass uc(SampleClass());
これは 引数 void、関数値 SampleClass の関数へのポインタを引数に取る関数の宣言だ
(More) Effective C++ 持ってるのに分からないなんて終わってるなお前
>>766 uc っていう関数として認識されてる。この関数の型は UserClass()(SampleClass (*)())
SampleClass を返す引数無しの関数ポインタを引数とする、UserClass を返す関数。
型の記述を読めるようになった方が良いよ。
>>765 エラーメッセージの意味ありがとうございます。
>>767 , 768
なるほど、やっと理解できたようです。
たしかに型の記述が読めてないですね、精進します。
class Test { char a[10]; int b; char c[5]; public: func(); }; こんな感じのクラスがあったとします。 これのインスタンス class Test test; を定義して、例えば char c[5] の先頭アドレスを取得したいんですが、 良い方法はないですか?
>>772 class Test
{
char a[10];
int b;
char c[5];
public:
func();
char* get_address(int i) { return c + i; }
};
Test test;
char* p = test.get_address(5);
>>772 C++のクラスでもoffsetofマクロがそのまま使える。調べてみるべし。
>>775 先頭アドレスってそういうことだったのか?読みが深いな。
offsetofの一定義例によると、求められたオフセット値はsize_t
にキャストされているマクロになってました。
>>772 のc[5]のアドレスを指定されてそこに書き込む関数、
を考えると
static Test test;
SetAAA(const char *str)
{
Test* p;
size_t offset;
char* dest;
p = &test;
offset = offsetof(Test, c);
dest = p + offset;
strcpy(dest, str);
}
のような事をしたいのですが、この場合、安全なキャスト
はどのようになりますか?
dest = (char*)(p+offset);
と強引にやってしまってよいでしょうか?
>>778 C++を使うなら(char *)とやらずにreinterpret_cast<char*>(p + offset) と書くべき。
働きは変わらないが。
しかしなぁ、メンバへのポインタを使った方が楽だと思うんだけど。 まあいいけど。
>>780 メンバへのポインタはアドレスじゃないから、
>>778 への最適解にはならんな。
実際内部クラスへの委譲をするにはメンバへのポインタではなくoffsetofマクロ
を使ってアドレスを求める必要があるしな。ケースバイケースかな。
offsetofを使ったこと無いやつばっかだな・・・実際、あまり使うこと無いけど。 offsetofを使ってメンバのアドレスを求めるときは、 まずchar *にキャストしてそれからoffsetを加え、さらに実際のメンバの型にキャストするから えらい汚くなるのよん。 dest = reinterpret_cast<char*>(p + offset); じゃ正しく動かないねん。
783 :
デフォルトの名無しさん :04/08/25 09:09
for( iterator i = begin(); i != end(); ++i ) i->m_p = NULL; これを「for_each」を用いた式に変更したいんですが 出来るでしょうか?
関数オブジェクトを作って使う
class Test { char a[10]; int b; public: func(); char c[5]; }; Test test; char *p = test.c; ところでこれじゃだめなのか?
for_each(begin(), end(), bind(&T::m_p, _1) = NULL); とかか?
>>784 ,
>>786 mem_func1をパクってmem_assignを作りました。
ありがとうございました。
Class Hoge{ private: int hage; //他メンバ変数が「20」個 public: void func( int n ){ switch(n){ case CASE0: hage達に関する複雑な処理; break; case CASE1: hage達に関する複雑な処理; break; //以下延々と「30」個 } } }; case文が多いので、そこの処理だけを他クラスに切り分けたいと思ったのですが(Stateパターン?)、 切り分けたクラスからHogeのメンバ変数であるhage達にアクセスする良い手段は無いでしょうか。 ・getter/setterを20個ずつ用意する ・friendを30行書く ・メンバ変数を全て構造体にまとめ、切り分けたクラス達に渡す 思いついたのは、どれもいまいち _| ̄|○
内部クラスにしてfriend
>>788 ・必要なメンバ変数に相当するものを構造体にまとめ、切り分けたクラス達に(getter, setterで)渡す
に1票。インタフェイスが明確になるし。
vimでvi使うのってどうやるの?
:set compatibleじゃ内科? スレ違い
>>789-790 レスありがとうございます。
やはりそういうやり方(俺のより遙かに洗練されてますが)しか無いのですね。
リファクタリングの本なんか見ると、switch-caseは全てstateパターンに
しろと言いかねない勢いで記されていますが、こういう風に分けなければとなると、
かえって解りづらい気がしてしまいますねぇ・・・。
stateパターンに移行できるようなinterfaceで設計しておけばいいんと違う?
795 :
デフォルトの名無しさん :04/08/25 22:04
cygwinにgcc3.4.1が入ったので使ってみた。 「参照されないstatic変数・関数は削除される」という変更が入っているらしいので、 早速試してみたところ、たしかに削除された。 static int x = 0; // この定義に対する領域の確保は無い ふと思い立って、無名名前空間に置き換えたところ、変数領域の確保が出力された。 namespace { int x = 0; } // この定義に対する領域が確保される 無名名前空間によるファイルローカルな変数・関数は、 staticと同様に参照されない場合に削除してはいけないのでしょうか?
素人な漏れから見れば、static が削除されるのなら無名名前空間も削除されてしかるべきなように思えるが…
別に削除されてもされんでもどうでもいいとオモタ
std::localeあたりに削除されてほしいstatic変数がいくつかあるが きれいに消えるんだろうか?
消えてもせいぜい50kBくらいじゃないの? 消えたからって特になんの効果もなさそうな気が。
>>800 処理系によっては、いくつか main() 走る前にコンストラクタが動いて、
動的メモリ割当を行うオブジェクトがあったりする。メモリ管理に手を
入れる場合に、ひじょーに面倒臭い。
803 :
デフォルトの名無しさん :04/08/27 15:33
単なる関数ポインタ宣言なら「void (*pf)();」と書けますが、 「A」というクラスに「B()」というメソッドがあった場合の、 Bのポインタ変数の宣言を教えて下さいでつ。
A::*B
>>803 void B(); なら void (*A::f)();
807 :
デフォルトの名無しさん :04/08/27 16:24
今更ながらの質問なのですが、効率的なincludeの仕方ってあるんでしょうか? 例えばhoge.cppとhoge.hが共に、stdhoge.hを必要とする場合 hoge.hの先頭に#include<stdhoge.h>する方法と hoge.cppの先頭に、stdhoge.h>hoge.hの順で#includeする方法がありますが・・・。 後者は他でhoge.hを使う場合にも同順でやらなければと不便で、今まで避けていましたが、 世のライブラリを見ると、特定の順序でincludeせよという物も多く、疑問に思った次第です。
普通両方でインクルードするんでは?インクルードガードしてないと おかしなことになるだろうし、してあればコードの解釈は1回ですむ からそこまで効率が落ちるってことはないだろうし。
>>807 ファイルは単独で意味を持つ方が望ましいという観点から見ても、前者がいい。
>世のライブラリを見ると、特定の順序でincludeせよという物も多く、疑問に思った次第です。
標準ライブラリがそうでないように、そういう注文を付けるライブラリは怠慢だと思う。
hoge.hをインクルードしたらstdio.hの関数が使えるってのは嫌な話だ。
>>810 C++スレでそんな事を嘆くべきかな?
テンプレートが記述されたヘッダをインクルードする時に、
避けられないことだと思うけどなぁ。
exportつかいてえ
関数ポインタを引数に持つCライブラリ関数に、 C++のstatic宣言されていないメンバ関数を渡して、 実行させることはできますか? staticでないC++のメンバ関数の実行には、仮想関数など ランタイム時に決定される種類のものがある。だから、 Cライブラリ関数がそれを関知して動作することは不可能 →ゆえにstaticしか通らない。 と考えているのですが。
皆さんレスありがとうございます。
とりあえず唯一解みたいのが無くて安心しました。。
>>808 私の使っている駄目なIDEだと、cppの方にincludeしてないと
入力補助が働かないので、実利の面からその考えは納得できます。
>>809 さんのレスが、最も同感です。
ちなみに私が悩んだライブラリの筆頭がWTLです。
>>810-811 それもまた、もっともですよね…。かなり嫌ではあります…が。
>813 概ねその通り。 まあ、渡せない理由は 仕様的には、型が違う 実装的には、暗黙のthisが引数に含まれる からだけどな。
>>813 仮想関数などを使っていなくても、C 風の関数ポインタは
"this"が何であるのかっていう情報を持っていないので、
C風の関数ポインタを用いてメンバ関数を呼び出すことは出来ません。
>>813 プログラミング言語C++ 第3版 15.5
> メンバポインタは、変数ポインタや関数ポインタとは異なり、
> メモリの位置を指すポインタではない。
> メンバポインタは、ポインタというよりも構造体オフセット、
> 配列の添え字に近い。
みなさんすみません。 最初、スレッドの初期化等を抽象化する基底クラスを 用意し、派生クラスではrun()メンバ関数のみを実装 すれば、コンストラクタ内部で自動的に pthread_create(..., run, ...); が呼ばれてスレッドが生成される...みたいな スレッドライブラリを考えていたのですが.... スレッド生成はWin32ならbeginthreadex_だし、 Linuxならpthread_createだしで、けっこう相違が あるので、隠蔽したいんですよ...。 どういう設計にするのが妥当でしょうか? いままでCだけで書いて来たので、実際に応用しようと するといろいろわからないことが...
>>818 スレッドで実行される関数に少なくともポインタが格納できるサイズのパラメータが渡せるはずだから、
そこに this を reinterpret_cast して渡してあげて、スレッドの開始関数 (static) では単に
static int ThreadProc(..., void* arg)
{
return reinterpret_cast<ThisClass>(arg)->run();
}
>return reinterpret_cast<ThisClass>(arg)->run(); return reinterpret_cast<ThisClass *>(arg)->run();
>>818 どうでもいいけど、スレッドのクラスによるカプセル化は止めた方がいいよ。
ま、C中心だったのであれば、潔癖なカプセル化はしないだろうけど、念のため。
>>818 > スレッド生成はWin32ならbeginthreadex_だし、
> Linuxならpthread_createだしで、けっこう相違が
> あるので、隠蔽したいんですよ...。
差異の吸収はboostにやらせるのはどうでしょ?
>821 そうなの?漏れけっこうガチガチにカプセル化しちゃたけど 特に不便を感じた事はなかったな。。。 >818みたいに,いろんな場所で動かす事を考えると 大変になるって事? それとも漏れのカプセル化がまだユルユルだったのかな。
うう、819さんのおっしゃることが理解できないんです。 すみません。 reinterpret_castを使ったスレッド生成関数の startup_routineを作っても、pthread_createや 親クラスへもっていく方法がわかりません。 #include <stdio.h> #include <unistd.h> #include <pthread.h> class Thread { public: virtual int run(void *) = 0; protected: pthread_t t_; }; class TSub : public Thread { public: TSub(); int run(void *); protected: }; static void * stub_thread(void *pParam) { reinterpret_cast<Thread *>(pParam)->run(pParam); return NULL; } (つづきます)
TSub::TSub() { pthread_create(&t_, NULL, stub_thread, (void *)this); } int TSub::run(void *pParam) { sleep(3); return 0; } 我ながら....情けなくなるのですが、TSubのコンストラクタに 書いてある内容をThreadのコンストラクタかメンバ関数に もっていきたいわけです。
ちなみに今まではUNIX/Win32でほぼ1vs1になるように スレッドAPIを#defineで再定義していました。返り値なども。 ただ、スレッドプログラミングを進めるにつれ、 スレッドが使うヒープなどを終了時に自動的に回収したいとか、 pthreadそのままなのでprimitive過ぎて使いにくいとか、 いろいろ不満がでてきたのです。 Boost、恥ずかしながら今初めて聞きました。 ドキュメントを読んでみようと思います。
こうかな? class Thread { public: int Start() { return pthread_create(&t_, NULL, stub_thread, reinterpret_cast<void *>(this)); } int Join(void** value_ptr = 0) { return pthread_join(t_, value_ptr); } protected: static void * thread_func(void *pParam) { Thread *pThis = reinterpret_cast<Thread *>(pParam); return pThis->run(pParam); } virtual int run(void *) = 0; protected: pthread_t t_; }; class TSub : public Thread { public: TSub(); protected: int run(void *) { sleep(3); return 0; } };
上の return pthread_create(&t_, NULL, stub_thread, reinterpret_cast<void *>(this)); の stub_thread は thread_func の間違い。 ただ、今から書くのならば class IRunnable { public: int run() = 0; }; みたいなのを単独でインタフェイスとして定義して、Thread クラス本体と run を実装する クラスを分ける方がよいと思う (Thread::Start の引数として IRunnable* を取る)。
>>828 キタ━━━━(゜∀゜)━━━━!!
最初思っていたことは上記のコードでできそうです。
ありがとうございました。
で。IRunnableの話なのですが、Thread I/Fとして
のclass Threadから、run()を追い出すとどのような
メリットがありますか?
まずThreadクラスのインスタンスを生成/管理する
ThreadFactoryとかThreadPoolとか作っておいて...
それらとは別に作っていたクラス
(例えばScreenManagerとか)で、値の監視的要素が
出てきたら、おもむろにIRunnableをくっつけて
run()だけ実装して、
ThreadFactoryに「スレッドにdispatchしてくれ」と
頼む、みたいな感じでしょうか。Start()が参加で、
Join()が脱退みたいな。
ここは頻繁にカプセル化するな厨が現れるな。
831 :
デフォルトの名無しさん :04/08/27 21:44
プログラムの規模によるんだよ
ThreadとかWindowとか、OSの機関にかかわる部分や特有の機能はカプセル化するべきじゃない。 Socketとかコンソールとか、どのOSでも似たような機能を備えていそうなものだけカプセル化するべきだ。
833 :
デフォルトの名無しさん :04/08/27 21:53
>>832 グローバル変数はアプリケーションインスタンスの
インスタンス変数って考え方でいいじゃん。
あとアクセス制御をどうするかって論点に絞るだけ。
カプセル化の是非はOOスレでやれ。 ここはC++でどうやるのがいいか悪いかを論じる。
>832 ポータビリティを重要視したライブラリを真っ向から否定ですか?
>>832 プラットホーム間のポータビリティとは限らんでしょ。
スレッドやソケットはさすがに微妙だと思うよ。
もろシステムコールじゃん。明らかに他のジャンルと異質。
>>835 ポータビリティはOSの特色を生かせない低賃金がする言い訳
個々のOSの特徴や性能を100%引き出してこそプロ
CとかC++とかperlとか、 ポータビリティのある言語だからプロ向けじゃ(ry
ハードディスクの性能をフルにいかすには、ファイルシステムなんて(ry
840 :
デフォルトの名無しさん :04/08/27 23:20
移植性とか規格を隠れ蓑にしてる厚顔無知は確実に実在する 決して「切り込み隊長」的な仕事をしない
公然オナニー迷惑な「切り込み隊長」も確実に実在する
>>837 移植性を追及すべきか、アーキテクチャへの最適化をついきゅうすべきかを合理的に判断してこそプロ
追求を「ついきゅう」なんて書いちゃう俺はアマ
844 :
デフォルトの名無しさん :04/08/27 23:40
移植性は追求しろと
いやもうマ板の話の流れっつーか
847 :
デフォルトの名無しさん :04/08/27 23:45
848 :
デフォルトの名無しさん :04/08/27 23:49
何のかんの理屈つけては逃げ回るだけの敵前逃亡の専門家イラネ
なんのかんの理屈つけて、カプセル化、抽象化から逃げる池沼もイラネ お前が出来ないからって、他の人も出来ないと思うな
なぜ荒れる(w
ホイポイカプセル化しとけ
夏休みが終わりに近づいてるから
853 :
デフォルトの名無しさん :04/08/28 06:25
>>849 は、手段と目的を履き違える典型的な「切り込み隊長」(w
854 :
デフォルトの名無しさん :04/08/28 11:00
stringクラスには大文字を小文字に変換するメソッドとか その逆のメソッドはありませんか? MFC CStringのMakeUpper()やMakeLower()みたいな感じの。
ctype::tolower
std::transform(s.begin(),s.end(),s.begin(),static_cast<int(*)(int)>(std::tolower)); locale対応バージョンがうまく書けない。
面倒でつね… なんでメンバに実装されてないのかな…
858 :
デフォルトの名無しさん :04/08/28 12:10
>>857 派生クラス作っときゃええやん
使えるクラスができたら売るとか・・・
デストラクタで純粋仮想関数を呼び出したいのですがうまくいきません。 純粋仮想関数の中身を実装しないとコンパイル時に関数がないと言われるのですがなんででしょう? ↓ソースはこんな感じです。 #include <time.h> #include <iostream> class DyingMessage{ virtual void say1() = 0; virtual void say2() = 0; protected: ~DyingMessage(){ ( time(NULL) %2 ) ? say1() : say2(); } }; class JiipanKeiji : public DyingMessage { void say1(){ std::cout << "なんじゃこりゃー"; } void say2(){ std::cout << "おらぁ死にたくないよ、死にたくない、死にたくないよ・"; } }; class RAOU : public DyingMessage { void say1(){ std::cout << "我が生が(略"; } void say2(){ std::cout << "我が生涯に一片の悔いなし!ウオァァァアア!"; } }; int main(void){ JiipanKeiji jk; RAOU r; }
>>860 ~DyingMessage() が実行されるときには、ジーパンもラオウも既に死んでいる。
>860 コンストラクタとデストラクタ内では、仮想関数が仮想になれない。 デストラクタを仮想にしてそこに書くしか。
863 :
デフォルトの名無しさん :04/08/28 13:35
柴田望洋さんの、CプログラマのためのC++入門を買おうと思っているのですが 内容的に古いらしいのですが、大丈夫なのでしょうか?
>>861 まじで
台詞はいてからじゃないと名シーンが台無しに・・・。
>>862 すみません、virtual抜けてましたね。
でもデストラクタにvirtualつけてもやはりコンパイル通らないっす
って仰っているのはデストラクタにvirtualつけろってことではない?
それで実験としてDyingMessageのsay1とsay2を
cout << "犯人はヤス"; と定義してみたらと、
ジーパンもラオウも「犯人はヤス」しか言わなくなりました。
な、なにゆえ?
>>864 処理の順番はこうなる。
DyingMessage()→RAOU()→ラオウの生涯→~RAOU()→~DyingMessage()
~RAOU()のタイミングでラオウは天に還ってしまう。
コンストラクタとデストラクタの中では、 関数呼び出しは(virtualであっても)「そのクラス」として行われるよ。 DyingMessageクラスではsay1, say2の中身は存在しないから、 コンパイラのメッセージは正しい。 実行時にヌルポ(pure virtual function call)を出す実装もある。 細かい話をすると、デストラクタやコンストラクタが親クラス→子クラス と渡るときに、vtblのポインタが書き換わる。 これ、Javaと逆だから、多言語を渡り歩く人は要注意ッス。 Java方式もまたそれで問題あるんだけどね・・・
>>865 中身(インスタンス)はRAOUだから、say1、2はラオウのものを呼んでくれてもいいのに( ´Д⊂ヽ
>>866 >細かい話をすると、デストラクタやコンストラクタが親クラス→子クラス
>と渡るときに、vtblのポインタが書き換わる。
まじですか。vtblのポインタが書き換わるんですか。
main関数内と ~DyingMessageでのジーパン、ラオウのインスタンスのメモリアドレスが一緒だったんで、
ジーパンとラオウのvtblのsay1、say2が呼び出されてうまくいくかと思ってたのですが納得です。
結局のところ、どうしよう。
~DyingMessage上でラオウのsay1が実行させたいのですが。なんか考えます。
ありがとうございました。
>>867 > ~DyingMessage上でラオウのsay1が実行させたい
そうはいってもそのときにはもうラオウは居ないから、
ラオウに追加したメンバは触れないぞ。
生きているうちに遺言を作っておいて DyingMessage に保持させるといいかもしれない。
>>867 ~DyingMessageが実行される時には
「お前(ラオウ)はもう死んでいる」から
ラオウのメンバを無理矢理呼び出すのもダメだよ。
>>868 できれば、
>>860 のラオウやジーパンクラスのソースのようにsay1、say2のみを定義するだけで他は何も手を加えず、
後は親クラスのDyingMessageがsay1、say2を使って処理してくれるようなのが理想なんです。
できるだけ子クラスは記述しなければならないソースを減らしたいんです。
でも、確かにラオウは破棄されてしまうわけだから今回の場合は無理っぽいですね。
>生きているうちに遺言を作っておいて DyingMessage に保持させるといいかもしれない。
それはいいアイデアかもしれないっす。ありがとうございます。
C++のデストラクタは、リソース開放のためだけに使うと思ったほうがええよ。
>>858 std::stringの派生クラスを作る奴は糞。
class x : public std::string { public: ~x() { std::cout << "x::dtor" << std::endl; } }; main() { std::string* p=new x(); delete p; } 実行結果 x::dtor 問題なし。
>>874 お前が気にするのはそこなのか?
この場合問題なのはデフォルトコンストラクタしか使えんことだろ。
>>876 Oh! Me としたことが釣られてしまいましたNeー!
VC++6で.cppと.defファイルをDLLにコンパイルする方法を教えて下さい
VCのスレ行ってください
>>872 > std::stringの派生クラスを作る奴は糞。
まぁ、作るなとは言わんが、この場合は
tolower(std::string&);
toupper(std::string&);
っつーフリー関数にしておいた方が、何かと幸せになれる気がする。
boost/algorithm/string/case_conv.hpp
std::ifstreamで std::ifstream fin("somefile"); char str[1]; fin.getline( str, 256 ); // この結果勝手に256に拡張されるっぽい などとできてしまうのですけどこれって仕様ですか?
884 :
デフォルトの名無しさん :04/08/28 23:04
>>882 拡張をしないまま暴力的に 256 byte 書き込んできてしまうだけ
道路の拡幅工事を立ち退き交渉も予告もせずにおっぱじめるようなもの
何が起きるのかは、おそらくご想像のとおり・・・
一見ちゃんと動いてるようでもやっぱり危険なコードだったんですね。 今度から気をつけます。ありがとうございました。
886 :
デフォルトの名無しさん :04/08/28 23:28
>>872 uppercase_traits作るんでもいーけどさ、
stringとの混用を前提とする場合、他にどーしよーもねーだろ
>>886 そのuppercase_traitsって、何してくれるの?
>>886 >>880 でいいやん。
なんで継承したがる?
つうか良く考えろよ。今から分かりやすく説明するからな。
お前は機能XXXを追加したくなった。
機能追加は継承だという浅はかな考えからstringから派生することにした。
class MyString : public std::string{
public:
void XXX();
/* 他のメソッドは略 */
};
こうしちゃったらさぁ、機能XXXを使うには
必ずMyStringクラスを構築する必要が出来るよな
MyString mystr=std_string_variable;
mystr.XXX();
これってかなーりムダだよな。
890 :
デフォルトの名無しさん :04/08/29 01:10
>>889 ちっとも解りやすくないぞ。何が言いたいんだ?
アップキャスト後に追加メソッドを使うコンテキストでへ来ちまったら
ダウンキャストが必要になるのはどんな作りのクラスでも一緒やん。
継承を全面否定したいのなら、同意はしないが理解はできる。
STLのコンテナクラス(ここではstd::string)のデストラクタが
virtual じゃないんじゃね?
>>889 はJava厨の釣りと見た。
いや、機能追加したいがためだけに実装継承するぐらいなら委譲で何とかしろってのがセオリーじゃないのか?
コンテナには委譲を使うのが基本だね
public std::string ↑ メソッド追加するだけなのにpublic継承してる所が釣り
896 :
デフォルトの名無しさん :04/08/29 02:02
>>893 機能追加つーたら継承そのものやんけ
なんで「異常」な手段に拘るんだよ
それでこそ2ちゃんねら
↓まだ釣られる気かよ
継承に警鐘
∩___∩ |
| ノ\ ヽ |
/ ●゛ ● | |
| ∪ ( _●_) ミ j
彡、 |∪| |
>>899 / ∩ノ ⊃ ヽ
( \ / _ノ | |
.\ “ /__| |
\ /___ /
900!
以下何事も無かったかのように再開
あれ、叩かれてる。説明あかんかったか。 よし、じゃあXXXとか言わずにuppercaseで書いたるか。 struct MyString : public std::string{ void uppercase(); }; ほれ、出来た。これでMyStringの大文字化はラクショーさ。 ああだけど、std::stringを使ってる部分もあるんだった。 これも大文字化しないといけない。 継承で機能追加 MyString mystr=std_string_variable; mystr.uppercase(); std_string_variable=mystr; 外部関数で機能追加 uppercase(std_string_variable); これでどうやろう? 基本的に継承は仮想関数のオーバーライドのためか protectedなメンバに触りたい時くらいにしか使うべきではない。
904 :
デフォルトの名無しさん :04/08/29 03:03
>>903 ヘ(_ _ヘ)☆\( ̄なんでやねん!
>MyString mystr=std_string_variable;
おまえ追加機能つかうちゅーてる時に予めアップキャストしとくんかい
アフォ言いな、比べ方の条件がちゃうやないけ!
このアホさ加減 Java厨っぽいな 継承悪 コンポジットサイコーみたいな 思考停止したデザパタ厨
>>904 ?
じゃあstd_string_variableを大文字化するにはあんたならどうするん?
てかさっきから気になってたんやけど、アップキャストなんてしとらへんよ
アップやないし、そもそもキャストでもない
>>905 オレのことじゃないよな。俺は外部関数使えいうとるし
ていうか、マジに大文字化機能を追加するには std::stringを継承して、そのサブクラスにメンバ関数追加するのが一番だと思ってるんか?
908 :
デフォルトの名無しさん :04/08/29 03:13
>>906 ああ、確かにstd_string_variableの定義を隠したままだねw
909 :
デフォルトの名無しさん :04/08/29 03:15
>>907 同じことじゃん、所詮はthisの渡し方
色んな書き方ができる中で今回はどれって選ぶだけ
>>908 定義?
std::string std_string_variable;
これでいいのか?
>>909 いやいや同じじゃないよ。
継承メンバ関数追加バージョンのuppercaseはstd::stringに対しては使えないんだよ。
継承メンバ関数追加を他の2、3人の奴がやってみ
A君は大文字化を追加したUppercaseStringを作った
B君は最後の文字を取り除く機能を追加したChopStringを作った
C君はその文字列をurlエンコードする機能を追加したURLEncoderStringを作った
じゃあ、大文字化の機能と最後の文字を取り除く機能とurlエンコードする機能全部を使いたいとき
一体どれを使ったらいいんだい?
外部関数でその機能を作ればこんなアホな自体にならないと思うけど。
911 :
デフォルトの名無しさん :04/08/29 03:39
>>910 >これでいいのか?
ああ、それでいい。
派生クラスで protected にアクセスできなくなるのと
同根の仮定を勝手に持ち込もうとしていることが判ったからな
また3人て新たな仮定を追加するのかよ、いい加減にしろや
色んな書き方ができる中で今回は継承を選ばないって場合の例ばかり持ち出しては
継承そのものを否定しようとする態度はよくわかった
912 :
デフォルトの名無しさん :04/08/29 03:44
>>910 3人でよけりゃ仮想継承って手もあるなw
913 :
デフォルトの名無しさん :04/08/29 03:49
別に外部関数の方がよりよく実装できるというあんたの主張にケチなんかつけてない だから880には噛み付いてない さっきも言ったがあんた自分の態度に思い当たるフシあるんじゃないの?
>>911 >継承そのものを否定しようとする態度はよくわかった
あれ?継承そのものを否定なんてしてないけど?
というか、オレは継承しまくり人間だよ。
実装継承もよくするしね。template<class T> class A : public T とかもしまくり。
ただ今回のケース、(
>>854 ね
は継承してメンバ関数追加 (
>>858 ね
は愚の骨頂やん?
だからいってるんやけど?なんか気に障った?
ヘタな説明にイラついたんやとしたらあやまるわ。ゴメン。
915 :
デフォルトの名無しさん :04/08/29 03:52
洋書の著者にありがちな態度でもある罠
916 :
デフォルトの名無しさん :04/08/29 03:54
>は愚の骨頂やん? あんたのキャラクタか
>>913 じゃあなんでオレに噛み付いたんだよ。
>さっきも言ったがあんた自分の態度に思い当たるフシあるんじゃないの?
聞いてないし、フシも無い。
>>916 はは、関西弁なんて知らんからな。酷く疲れたぜ。
>>890 890 が ToLowerCase, ToUpperCase を追加した MyStringUL を作った。
俺が EUC, SJIS の相互変換できる MyStringES を作った。
で、両方の機能が使いたくなったらどうする? 気がつくと似て非なる
互換性のない文字列型がたくさん出来てることになりかねんぞ。
ねじ・くぎのような「部品」として使うクラス、プログラミング言語 C++ で
言うところの具象クラスは、可能な限り安易な仕様を早期に固めて、
安易な拡張はしない方が良い。まして継承は最悪の選択肢の一つだ。
>>919 virtual で多重継承して、C++の繊細さを堪能するというのもアリだと思うぞ。
堪能ってのは、実質デバッグの堪能だけどな。
ま、無理ではない。
ま、普通、自分で作るなら、 iterator使ったgeneric function書く。> toupper
>>920 すでに MyStringUL 使って書かれてるコードが大量にあったら、MyStringES に
クロスキャストするの? それは死にそうだ。
汎用ライブラリじゃないなら、普通はそのプロジェクト内だけで使う。 890 が ToLowerCase, ToUpperCase を追加した MyString を作った。 俺が EUC, SJIS の相互変換できる機能を、 MyString に追加した。 となるわな。インフラグループとかが、普通にやってることだ。
std::string を継承する フリー関数を作る どちらかでしか実現できないことなら仕方ないが、どっちでも実現できて 一方にはかなり痛いデメリットがある場合には、選択肢は自ずと決まると 思うんだが。
>>923 機能追加はなんでもかんでも継承だ、という安直な考えを持った、
オブジェクト指向習い始めて3日目くらいの奴がそのグループに多いとやっちゃうわな。
だけどそんなフツウを、世の中のフツウと勘違いしたらダメだ。
926 :
デフォルトの名無しさん :04/08/29 11:14
>>924-925 とりあえずやってみたらって言うのをずいぶん調子に乗って拡大解釈してるな、おまえ
選択以前のことを言ってるところへあーしろこーしろと思考まで代行してくれなくていいんだよ
それとも最後まで代行をやり通す責任感があって言ってるのか?
人が自分で物事を考えるときに金切り声で騒ぎ立てるのがただうるせえんだよ
物作ってるより人に暴言吐いてる方が楽しい奴が何か憶えたのを使いたくてこっち来たのか?
>>926 何切れてんだお前?
責任とって欲しいならそもそも2chに来るなよ。
お前のプロジェクトには、カスタマイズされた文字列クラスもないのかよ。 文字列操作系のグローバル関数満載かよ。 どんなプロジェクトだよ(w)
現在激しい電波を受信しています。ご注意ください。
多重継承のメモリ解放で疑問があります class A { ... }; class B { ... }; class C : public A, public B { ... }; A, B, C全て仮想デストラクタを持っている C* pc = new C; B* pb = pc; delete pb; デストラクタは正しく呼ばれるが、pbのアドレス(pc != pbは確認済み)でメモリが解放されておかしくなる と思ったのですが、operator newとdeleteをオーバーライドしてトレースしてみたところ operator deleteではpcのアドレスが来ました。 delete pb;ではpbが指すのがCのオブジェクトなのかBのオブジェクトなのか区別できないはずなのに どうしてpcのアドレスが求めることができたのでしょうか?
>>926 浅はかな考えを指摘されたからって逆切れするなよ
>>928 お前の糞プロジェクトを中心にものごとを考えるなよ。
937 :
デフォルトの名無しさん :04/08/29 11:52
>>935 浅はかかどうかをお前が決めてやらなくていいんだよ
自分の設計に同意を求めたくて余裕なくしてるのはお前だろ
>>937 明らかに継承の方が劣ってたじゃん。
>自分の設計に同意を求めたくて余裕なくしてるのはお前だろ
この一文がどっから出てきたのかわからないけど、そっくりそのままお返しします。ノシ
942 :
デフォルトの名無しさん :04/08/29 12:17
>>940 >この一文がどっから出てきたのかわからないけど
じゃ、何を必死になってるんだよ
>>942 必死になっているのはあなた一人に見えます。
あなたが「必死だな」と判断したのはどのレスですか?
レス番で教えてください。できれば理由も添えてください。
さっきからageてる人が、口調からしても必死に見える。
どっちも必死だよ、外でやっとくれ
かぶりまくったw自演認定されそう
継承の美しさを追求するあまり、 工数が増えたりするのはアフォらしいってのは、 みんな賛成してくれるだろ?な?駄目?
950 :
デフォルトの名無しさん :04/08/29 12:30
継承って美しいか? むしろ泥臭い。 最適解なら泥臭くても使う。 それは継承でもグローバル関数でも変わらない。
>>928 STL はコンテナ系も便利だが <algorithm> も便利だよ。
うわーい。こんな雰囲気なら漏れさんでも飛び込み参加できそうな予感。 class MyConstants { static const std::string TEST_TEST1; static const std::string TEST_TEST2; static const std::string TEST_TEST3; } こういうクラスから継承するときはどうするのが普通なの? private virtualあたり? class MyTest : public MyTestAbstract, private virtual MyConstants { } 教えてね♪
オブジェクト指向プログラミングでいうところの継承と、 C++でいうところのclassの継承は 似てるようで全然違うよ。 手段と目的を履き違えないようにね☆
>>955 何が違うの?
C++のクラスはOOPLのクラスと同じように扱う事もできるのに。
>>C++のクラスはOOPLのクラスと同じように扱う事もできるのに。 扱うこと「も」できるのに。 この「も」が重要。
似てるようで全然違うよ。 ~~~~~
templateと組み合わせたgenericな・・・というのは詭弁。 違いはせいぜいスタックに生成できる事と、デストラクタの存在くらいなもんだ。
>>955 >手段と目的を履き違えないようにね☆
無粋なやっちゃな、そこを敢えて履き違えるのが粋ってもんだろ?
Java厨はスルーね
>>964 上司がPGあがりのPMだったら、厨房扱いされて査定に響く怖れアリ。
template <typename T> class C{ ... }; を、T を省略して template <typename> class C{...}; と書く事って認められてます? テンプレートパラメータに template 入れるときに省略したいんだけど…