1 :
v(^・^)v :
02/09/18 19:42 文法が汚くてもいいから、懐の広い言語を望むあなた。そんな
あなたにぴったりの言語、C++。
(´∀`).。o(関連URLは
>>2-5 の辺り)
2 :
デフォルトの名無しさん :02/09/18 19:44
松本コンチータ
3 :
v(^・^)v :02/09/18 19:50
4 :
v(^・^)v :02/09/18 19:52
5 :
v(^・^)v :02/09/18 19:52
6 :
デフォルトの名無しさん :02/09/18 20:05
C++にはクラスとかSTLとか色々ありますけど、最低限どれを覚えれば C++を使いこなしているといえますか? あと、C++を覚えただけじゃプログラムは作れないと聞きましたが、 他にどんな事を知る必要がありますか? 数学関係とかの知識なら大丈夫だと思います。
>6 //が使えれば大丈夫。
9 :
デフォルトの名無しさん :02/09/18 20:19
>374 名前:デフォルトの名無しさん sage 投稿日:2002/09/18(水) 03:03 >オブジェクトを直接宣言する場合と、 > CTest oObj(Hoge); >一旦ポインタの形で宣言しnewする場合は、 > CTest* pObj; > pObj = new CTest(Hoge); >どのように使い分ければいいのでしょうか? >375 名前:デフォルトの名無しさん sage 投稿日:2002/09/18(水) 03:10 >スコープを外れても残したい時はnew 前スレで↑を見て「なるほど」と納得していたのですが、 newするしたらdeleteしなければならない、となぜかわからずでも覚えてるの ですが、この場合スコープ抜けちゃうとdeleteできませんよね? 本にはnet<->deleteとセットで書かれているので 理解できません。どうしてでしょうか?
>>9 コンストラクタでnewしてデストラクタでdeleteするとか。<スコープ抜けてからdelete
>>6 ちょとずれるが,C++プログラミングとSTLプログラミングは何となく毛色が違うと思う。
自称C++プログラマがListクラスとか作っててアフォかとオモタ。
切れた。
だからSTLバリバリの人はSTLプログラマと名乗って欲しい。
で,「C++を使いこなしている」とは
・
>>8 ・クラス
・iostream
ぐらいでよいのでは?
・new delete ・例外 も。
>>10 ということは変数をクラスに持たせるということですよね。
そうすると、クラスに
CTest oObj(Hoge);
で宣言するのと
CTest* pObj;
pObj = new CTest(Hoge);
で宣言しnewするのとはどのように使い分ければいいのでしょうか?
と
>>9 の代わりに質問してみるテスト
>>13 ポインタ宣言しておくのは多態性を実現したい時とか,
生成を遅らせたい時とか場合によっては生成しなくてもいい時とか。
>10 えっとさっきの例で話すと、 CTest *pObj(Hoge); pObj=new CTest(Hoge); って領域確報しちゃうとスコープ抜けたら 領域は確保されたままですが、*pObjはもう使えないですよね? スコープ内でdelete pObjとするならわかるのですが、 この例だとスコープ抜けたらdeleteできないんじゃないんでしょうか? deleteする必要はあるんですよね?
>>15 func()
{
CTest* pObj;
pObj = new CTest(Hoge);
return;
}
だと思ってるの?
たぶん前スレ375はそういう風には捕らえてないと思われ。
>16 元質問者の方のオリジナルのコードは VCでMDIを作成する時に自動作成される↓なんですが、 CMultiDocTemplate* pDocTemplate; pDocTemplate = new CMultiDocTemplate(IDR_MDITYPE, RUNTIME_CLASS(CMDIDoc), RUNTIME_CLASS(CChildFrame), RUNTIME_CLASS(CMDIView)); この例だと>16に書かれている形式と同じですよね? もちろんこの後deleteはありませんでした。 スコープ抜けたらdelete pDocTemplateはできないでしょうし、 なぜdeleteしなくていいのか、というのが悩みの種です。
>>17 deleteしてないんだったらしてないんじゃない?
>>18 CTest* pObj; // どこか(グローバルとかクラス面罵とか)
---------------------
pObj = new CTest(Hoge); // どこか
だと思ったんだと思う…。
>>19 deleteしなくてメモリリークは起きないの?
pDocTemplateをその後一切さわってないの? どこかに登録とかしてるはずなんだが。 もし、そうでないならリークしてるかnewをオーバーライドしてる
>19 じゃなぜ>17のコードはdeleteしてないんでしょうか? >21を見るとnew したら deleteしなきゃいけないんですよね? 少なくとも>17のコードはreturn TRUE;までの間に delete pDocTemplate; という文はありませんでした。 deleteしなければメモリリークが発生するというなら どこでdeleteしてるのでしょうか? 話しがVCに流れてますがVCスレへ戻った方がいいでしょうか??
ちなみに、この場合無限に生成される物じゃないから リークしても別に構わない程度の物だとは思うが。
>>17 「元質問者」さんに聞いて見るのが吉なのでは?
>>23 何かかたくなに「deleteしなきゃいけない」って思いこんでるみたいだけど,
deleteしないコードは動かないってわけじゃないですよ。
実装がちゃんとしてる環境ではdeleteしなくてもプログラム終了時には解放されますよ。
(細かく突っ込まないでね。fjじゃないんだからさ)
あとC++の話題だと思うんで大丈夫だと思います。
>22 確かに基底クラス(CObject)でオーバーライドされてました。 void* CAge::operator new(size_t nSize) { return malloc(nSize); } こんな感じです。 私は「malloc」のことよくわかっていないので これ以上追求できないようです。 基本的にnew したら deleteしなければならないのは確か。 ということはわかりました。 またおいおい覚えていきたいと思います。 ありがとうございました。
>27で結論付けたはずが >26を読ませてもらったところ間違いだと早速気付きました。 newすればかならずdeleteしなくてはならないというわけではない。 に訂正いたします。 実際私のレベルではこれ以上ついていけないっぽいので 例外を除いてdeleteは必ずしろっ、 と覚えておきますw ありがとうございました。
>>27 mallocはメモリを確保する命令。確保した後はfreeで解放しなければならない。
>>29 いや,deleteはしなきゃいかん。
が,deleteしてないからといって「動かない」というわけではない。
しかし,「動く」と言っても,「完全に設計どおりに動く」というわけではない。(
>>28 が指摘してるけど)
>>30 deleteしない終了時に解放されるのはメモリだけということですか。
deleteして終了するのとdeleteしないで終了するので違いがあるということですね。
最後の行訂正します。
しかし,「動く」と言っても,「完全に設計どおりに動く」というわけではない。(
>>28 が指摘してるけど)
↓
しかし,「動く」と言っても,「完全に設計どおりに動く」とは限らない。
「設計通りに動くかもしれないし動かないかもしれない」(
>>28 が指摘してるけど)
>>33 そういうことです。メモリ以外の資源はリークする可能性があります(使っている場合)
deleteしたときしなかったとき…の動作については10氏の通りだが、
>>23 特に CMultiDocTemplate に関して言うなら、こいつはコンストラクタの中で自分を
CDocManagerというクラスのオブジェクトに自分を登録しておいて、
// pDocTemplate = new CMultiDocTemplate(IDR_MDITYPE, ... );
// ここの中でDocManagerに登録↑
で、例えばCDocManagerのデストラクタの中からdeleteが呼ばれる
ようになっているのでとりあえず心配は要らん。
>36 あぁ、なるほど、 全て納得いきました。 そいういう流れだったんですね。 全部納得いってすっきりしました。 ありがとうございました。 感謝。
ごちゃごちゃしてきたな。さかのぼって始めらへんのやつ
>>15 をコピペしてみよう。
答えが出てないみたいだから。
15 :9 :02/09/18 20:28
>10
えっとさっきの例で話すと、
CTest *pObj(Hoge);
pObj=new CTest(Hoge);
って領域確報しちゃうとスコープ抜けたら
領域は確保されたままですが、*pObjはもう使えないですよね?
スコープ内でdelete pObjとするならわかるのですが、
この例だとスコープ抜けたらdeleteできないんじゃないんでしょうか?
deleteする必要はあるんですよね?
私の質問が続いているみたいだったので顔を出しました。 まず、 >25 これは私が書いたコードではなくVC++というツールが吐く スケルトンです。 なぜMDIスケルトンがnewを使うかを確認するために、下記にコード変更 staticCMultiDocTemplate oDocTemplate( IDR_TEST33TYPE, RUNTIME_CLASS(CTest333Doc), RUNTIME_CLASS(CChildFrame), RUNTIME_CLASS(CTest333View)); AddDocTemplate(&oDocTemplate); ビルドして実行すると、予想に反して何事もなく動作しました。 (アプリ抜けるときに例外発生するけど、もともとnewを想定した>36辺りの処 理の問題だと思われます。あまり重要でないと思う。) →普通のオブジェクトでいいものを何でnewしてるんだろう? →Win9X系のリソース(640KByteの)問題で、ヒープにCMultiDocTemplate のエリアを確保したかったのでは?(子ウインドが何枚開かれるのか分か らないので) と言うことでリソースメータを起動して、オブジェクトの場合とnewの場合と で、それぞれ子ウインドを1000枚開いて比較。 →結果、リソース使用量変わらず。 ここまでやって、”なんか知らんがnew使った方がいいんだろう。” という結論に達しました。また気が向いたら解析することにします。 (今度はこっちがスレ違いに、、、)
よく考えたらstaticもヒープに取られるんだっけ? >42 ではリソース問題の確認にならない可能性大。
MFC のことはよく分からんが、
>>42 > 普通のオブジェクトでいいものを何でnewしてるんだろう?
その CMultiDocTemplate っつーのをクライアントが動的に生成できる
ようにするためなんでは。
しかし、おれは 36 の説明じゃ訳分からんかったよ。42 の
> AddDocTemplate(&oDocTemplate);
で分かったけど。36 もこのことが言いたかったんだね。
>>43 > よく考えたらstaticもヒープに取られるんだっけ?
んなことはない。
>>44 うお、じゃstaticはどこに取られるんだ?急に足下がおぼつかなく
思えてきたYO…。
data とか bss とか。
>>42 CWinAppのメンバ
CDocManager* m_pDocManager;
オブジェクトにCDocTemplate*渡されてポインタ管理が任されているみたいだね。
それで
CDocManager::~CDocManager()できちんと解放されているようだ。
delete m_pDocManager;
はCWinAppのデストラクタで呼ばれている。
staticにするとアプリ終了時に2重にデストラクタが呼ばれるから例外が呼ばれる
ようだけど。
48 :
デフォルトの名無しさん :02/09/19 03:20
ちょっと話ズレるんですけど、実体で持つ場合とポインタで持つ場合の違いで クラスAがクラスBをメンバに持ちたい時 実体持ちの場合のクラスAのサイズ=sizeof(クラスA)+sizeof(クラスB) ポインタ持ちの場合=sizeof(クラスA)+sizeof(ポインタ) となって、実体持ちだとコピーの時にオーバーヘッドが発生 という事であってますか? 更に突っ込んで、実体持ちだとクラスBの実装が変わってサイズも変わったりすると クラスAに関しても再コンパイルが必要になるけど ポインタ持ちだとクラスBの再コンパイルだけでいいって事であってますか?
全然違う
50 :
デフォルトの名無しさん :02/09/19 09:53
CreateWindowで作ったボタンのフォントを変えたいのですが CreateFontしてGetDCしてSelectObjectしてみたのですが変わりません やり方的にはこれでいいんでしょうか?
>>48 49> 全然違う、だけじゃアレなんで (w
> 実体持ちの場合のクラスAのサイズ=sizeof(クラスA)+sizeof(クラスB)
実体持ちの場合のクラスAのサイズ=sizeof(クラスA) だが?
というツッコミは置いといて、48 の言いたいことは、
実体持ちの場合のクラスAのサイズ=sizeof(クラスA - クラスBのメンバ) + sizeof(クラスB)
ってことだろうけど、メンバを4バイトとか8バイト境界にアライメント
させてる場合は、違ってくる可能性がある。
> 実体持ちだとコピーの時にオーバーヘッドが発生
ポインタ持ちだとオーバーヘッドが発生しないわけでもない。
クラスAのコピーコンストラクタの作りによる。
> ポインタ持ちだとクラスBの再コンパイルだけでいいって事であってますか?
これは合ってるかな。この場合は、クラスAを定義しているところで
クラス B を定義しているヘッダファイルをインクルードしないようにね。
まちがえた。 > > ポインタ持ちだとクラスBの再コンパイルだけでいいって事であってますか? > これは合ってるかな。 合ってない(w クラス A の定義をインクルードしている、他のファイルは再コンパイルの 必要がない。クラス A の実装ファイルは、(たぶん クラス B を使っているので) 再コンパイルが必要だろう。
C++のコンパイル速度はこれ以上速くなりそうもないな。
再三スマソ。 ようするに、クラス A の実装からクラス B の実装が見えるのなら再コンパイル。 見えないなら不要、ということ。クラス間の依存はできるだけ減らすようにがんがれ。 ちなみにおれは、pimpl パターンがお気に入りだ。
>>54 何を基準にして「これ以上」なのか知らんが、書き方に気をつけると、それなりに
は速くなる。インターフェースと実装を分離して、ヘッダファイル間の依存関係を
減らすとかさ。
(あと gcc は遅すぎ)
57 :
デフォルトの名無しさん :02/09/19 13:59
今家(linux)で作ったプログラムを学校(solaris)コンパイルしています。 でも、家では警告だけだった char* a = NULL; を char* a = (char*)NULL; に直さないと駄目になりました。 なぜでしょうか?また直さないでコンパイル通したいのですが駄目ですか?
>>57 C++だから NULLが(void *)0などと定義されているためエラーになったの
だろう。
検索かけてNULLを0にしる。
もっと簡単な方法があった。 #undef NULL const int NULL = 0;
>>57 ちょっとstddef.hを覗いてみて欲しい。次のような行が書かれてないか?
#ifndef NULL
# if defined(__cplusplus)
# define NULL 0
# else
# define NULL ((void *)0)
# endif
#endif
コンパイル時間って何かに影響すんの?
>>58 , 59, 60
みんな、がりがとう。自分で
#define NULL((void*) 0)
と定義してたのが不味かったみたいです(w;
63 :
デフォルトの名無しさん :02/09/19 14:55
メンバ関数ポインタを作ろうとしているのですがうまくいきません 下の(a.*pP)()のところでコンパイルエラーになってしまいます 書き方が違うのでしょうかおしえてください class A{ private: int a; public: void (A::*pP) (); A(){pP = Print;} void SetA(int s){a = s;} }; int main() { A a; a.SetA(100); (a.*pP)(); //error return 0; }
>>61 開発効率
とくにバグとりのときに、
1. バグをとる
2. コンパイルする
3. テストする
のサイクルが遅いと嫌。
すいません A::Print() がぬけてました
>>61 コンパイルに12時間もかかるプロジェクトとかやったやつ、いる?
そんな本読んだよ。
大体平均的なコンパイル時間ってどのくらい? 規模にもよるとは思うが。
pPがAのメンバなのだから (a.*(a.pP))(); こうしなければならないんでは。
ビルドに1時間かかるプロジェクトってどんなもんよ? 100万行くらい?
>>72 ああコンパイル出来ました
ありがとうございます。
なるほどこのようになるのか。 class A { private: int a; public: void (A::*pP)() const; A() { pP = &A::Print; } void SetA(int s) {a = s;} void Print() const { std::cout << "a = " << a << std::endl; } }; int main() { A a; void (A::*pP2)() const; pP2 = A::Print; a.SetA(100); (a.*(a.pP))(); (a.*pP2)(); }
>>70 手元のテンプレートライブラリ使いまくりの C++ 20,000 行のコードで、フルビルド
2分30秒。Pentium III-M 800MHz / VC6 / 最適化 速度優先
C++ が危険なのは、注意して書かないとファイル間に依存関係が容易に発生
してしまい、ひとつファイルを書き換えたらフルビルドに近い状態になってしまう
こと。上でも誰かが言ってた pimpl イディオムや、インターフェースと実装の分
離を徹底しないと、規模が大きいプロジェイクトでは破綻するよ。
pimplはテンプレートの旨みを2つ消す ・インライン展開 ・コードの短縮、簡略化
インターフェースと実装の分離でよい本ある? 具体例のあるやつ。
>>78 プリコンパイル済みヘッダは適切に設定してる?
テンプレート使いまくり、33万行のC++コード
Pentium III 800MHz / VC6 / 最適化 速度優先
でフルビルド2分。
遅レスだけど前スレ982と984へ。 intやらshortやらも含めて全てのクラスの基底にvoid型のクラスがあるという仮定での話。 この仮定の下ではvoid *はvoidを指すポインタと言う事ができる。
>>81 抜かりはないつもりだったんだが、設定ミス見付けた(w
修正後は 40 秒に短縮。Thanks.
>>79 前者は、それは使いどころを間違ってる。pimpl を使って実装を隠すべき
なのは、もともと仮想関数経由で呼ばれるような部分。
>>84 勿論そんなことわかってるよ。
ただ、テンプレート使いまくりでのコンパイル速度の低下の
解消法として使った場合は
>>79 のようになるだろ?
>>85 テンプレートの場合には、ヘッダ間の依存関係は (それほど) 発生しないと
思うんだが。気のせい?
コンパイルが遅いとかいうのは処理系依存の話だよねえ
>>87 フルビルドの場合はそういう側面が強いが、
差分コンパイル(という言い方あるよな)なら処理系に依存しない
テクニックがあってよくネタになる。
上の pimpl イディオムとかな。
>>87 処理系間の比較みたいな話になると、逆にこのスレの方が良いかも。gcc スレ
や VC スレだと、その処理系以外の話はスレ違いだからねぇ。
90 :
デフォルトの名無しさん :02/09/20 22:46
VC++ って、メンバ関数テンプレートの特殊化はできなかったっけ? class Foo { public: template<class T> void func( const T& obj ); }; template<> void Foo::func( const int& obj ) { } // これがエラー int main(){ Foo().func( int() ); return 0; } foo.cpp(5) : error C2511: 'func' : オーバーロードされたメンバ関数が '<Unknown>' にありません。 というようなエラーになるんだけど。
C++コンパイルおせーな。 2分や40秒もかかるのかよ。
昔は一晩がかりでしたが何か
昔結果出るまでに1週間かかったことありましたが何か
しまった。コンパイルの話じゃなかった。スモァソ。 プログラム作って穴開けてもらって実行してもらって結果もらうまでが1週間ですた
おじいさん、昔話ばっかり言わないでよ。
昔はマイコンにつきっきりでフロッピー入れ替えながらコンパイルしましたが何か
カーネルのリビルドやユーザーランドのリビルドは時間かかるぞ〜 この間のリゾルバの騒ぎのときは、リコンパイルに20時間かかった。
> template<> void Foo::func( const int& obj ) { } // これがエラー じゃなくて template<int> void Foo::func( const int& obj ) { } だったりしなかったっけ。
>>90 VCはまだクラス定義の外でのスペシャライゼーション定義には対応してないよ。
さいでしたか… しかたがない、非メンバ関数でやることにします。 でも、クラス内で specialization できても意味ないよねぇ。 たんなる多重定義と変わらんもん。
>>101 まったく無意味でもないかな
ユーザーによるクラス定義外でのスペシャライゼーション
定義を可能にすることは、隠蔽されるべき非公開メンバへの
自由なアクセスを許すに等しいからね。
なるほど。その視点は気づきませんでした。 ということは、非メンバ関数のテンプレートでも friend にしたら 同じ問題をかかえるということか。
struct A { int a; }; struct B : A { int b; }; void func(A arry[4]) { for(int i = 0; i < 4; i++) arry[i].a = 0; } void test(void) { B m[4]; func(m); } これコンパイル通るのっていいの?
>>104 何か問題?
func(A arry[4])はfunc(A *arry)と同等で
func(m)ではmが標準変換でB*に変換され
B*からA*へのアップキャストは標準だから
コンパイルは通るのが正しい(↑のようにポインタの変換だから) でも、一般的に、親クラスの配列(の先頭要素へのポインタ)が求められているところに 子クラスの配列を渡してはいけない。参照扱いでも同様。 理由はEffective C++(Moreかも)に書いてあったと思った。
よくよく考えればそうだった。 実はそれが本題でなく… 後少し時間をください。
template<class T> struct A { T a,b; }; struct B : A<int> { //関数だけ }; template<class T> void func(A<T> *a) { } void test(void) { B m[3],*n; func(m); // NG func(n); // OK } 'B [3]' から 'A<T> *' に変換できません。 と言われます。なぜm[3]を*mと解釈してくれないんですかねぇ?
stringの配列の個数分ループさせるロジックを使いたいのですが、 配列の個数を取得する方法がわかりません、教えてアルゴマン。
vector使え
テンプレートを使うとキャストされないんでしょうか?? func<int>(m); func(&m[0]); なら可能なんですが、他の型同様にfunc(m)で素直に渡したいと考えいるので・・・ なんとかfunc(m)で渡す方法はないですか? 飯買いに行ってきます。
bcc では通った。> func(m);
C++ 3rd の 13.3.2 [3] によれば 「テンプレート引数の推測によって決まったテンプレート関数引数には、 格上げ、標準変換、ユーザー定義変換を適用することはできない」とある。 ということは、引数の推測の際には、継承関係などは全く考慮されない ということではないか。
>他の型同様にfunc(m)で素直に渡したい のであれば、 inline void func(B *a) { func<int>(a); } でも定義しておけばよいかと。
ということは func(&m[0]) も本当なら駄目っていうことになるか。
>>108 実際問題として、変更されたら困ることが多いからだろう。struct B にメンバ変数が
あったら func 内で a[1] とかに触ると、確実に値を壊すし。
っつか継承を使うなら配列は忘れて vector 使え。その方が身のためだ。
>>117 継承との関わりで、配列とvectorの間に特別な違いは無いと思う。
どっちを使っても一緒。
そして、継承するようなオブジェクトの実体はvectorなどに入れるべきでは
ない。m1, m2, m3という3個の変数と同じ程度の気持ちで配列に入れるのは
問題ないけど、vectorを使う、ということは実行時に値を追加したい、
ということで、その場合はvector<B*>かvector<shared_ptr<B> >を使うべき。
>>118 > 継承との関わりで、配列とvectorの間に特別な違いは無いと思う。
いや delete[] の罠がある。
保守
かなり遅くなってしまいましたが、レスを。 色々やって見ましたが駄目でした。 func(T *a)で取って、内部でA<T>に変換するこで妥協を… こんな感じに↓ template<class T> void func(T *a) { A<T::value_type> *b = a; // (;´Д`)ハァハァ・・・な処理 } やっぱり標準変換ということで引っかかってるようでした。 func(&m[0])は通るのに・・・ 標準変換とかでエラーをだすのはVCだけなんかな?bccはOkらしいし。 STLは覚え中なんで今度の機会に・・・。 mで渡すのにこだわっていたのは&m[0]でしか渡せないのは 非常に分かりにくいと思いまして。(実はもう少し複雑) ご迷惑お掛けしました。そしてありがとうございました。 寝ます。
>>121 // (;´Д`)ハァハァ・・・な処理
どんな処理やねん(w
123 :
デフォルトの名無しさん :02/09/23 14:46
下記のようなプログラムを書いたのですが、コンパイルエラーが出ます。 エラーの中身を見るとchar型にint型を入れることができないと言うことなのですが どうすればよいかイマイチわかりません。わかる方、教えてください。 main() { int a,b,c,title; char file[64]; char name[64]; FILE *fp; a=0; b=1; c=10; title=10; for(int x=0;x<title;title++) { name=title".dat"; strcpy(file,name); fp=fopen(file,"a"); for(a=0;a<c;++a) { b=b+b; printf("%d\n",b); fprintf(fp,"%d\n",b); } fclose(file); } }
エラーの原因は name=title".dat"; <-- ここ C++は int(整数) から文字列への自動変換はサポートしていないので 自分で、やらなければならない。 しかし、このプログラムにはそれ以外にも title=10; for(int x=0;x<title;title++) fclose(file); などなど、バグだらけだからもう一回初めから作り直した方が 良いと思ふ
>>124 ありがとうございます。
一から書き直します
みんなstringをintにするのどうしてる? それと逆の場合。
string → int ... atoi() int → string ... stringstream
>>126 > みんなstringをintにするのどうしてる?
> それと逆の場合。
その時次第。
129 :
デフォルトの名無しさん :02/09/23 17:14
boost::lexical_cast
>>123 さんの場合は snprintf が最適解かもっすね。
snprintf( name, 64, "%d.dat", title );
# snprintf がなければ sprintf っすか。
# C++ というよりは C なので sage
#include <boost/lexical_cast.hpp> #include <string> void f(){ std::string s = "10"; int i = boost::lexical_cast<int>(s); i += 2; s = boost::lexical_cast<string>(i); }
意外に多くのレスありがとう。
ちなみに俺は、
>>127 さんと同じです。
もちろん、ケースにもよりますが。
実は、ちょっとatoiはなんか古臭い感じがして、
stringstreamは大げさな感じがしていたのですが、
ちょと安心しますた。
lexical_cast は、"0x10~ とかの16進数を扱えない気がしたが
>>133 lexical_castは内部でstringstreamを使ってるので、ちょこっといじれば出来るようになる。
>>135 おいおい、文字列を扱う部分をフル実装しなけりゃならんの?
136==あふぉ
とりあえずlexical_cast.hppを見れ。激しく短いぞ。
>>138 激しく短くても、lexical_cast<const char*>を特別化したら
自分で中身を全部かかなきゃだめと言ってみるテスト
>>139 それは仕方ないかと。
lexical_castは拡張を予想して作られたものではないだろうし。
何進数でも使えるように lexical_cast を書き直せば良いと。
template<typename Target, typename Source, class Manip> Target lexical_cast(Source arg, Manip manip) { # ifdef BOOST_LEXICAL_CAST_USE_STRSTREAM std::strstream interpreter; // for out-of-the-box g++ 2.95.2 # else std::stringstream interpreter; # endif Target result; if(!(interpreter << manip << arg) || !(interpreter >> result) || !(interpreter >> std::ws).eof()) throw bad_lexical_cast(); return result; }
>>143 C++のキャストの構文と違うからダウト
145 :
デフォルトの名無しさん :02/09/24 12:25
template<typename T, class Manip> class manip_adapter { T val; Manip manip; public: manip_adapter(const T& v, Manip m) : val(v), manip(m){} friend std::ostream& operator<<(std::ostream& os, const manip_adapter& rhs) { return (os << rhs.manip << rhs.val); } }; template<typename T, class Manip> manip_adapter<T, Manip> make_adapter(const T& v, Manip m) { return manip_adapter<T, Manip>(v, m); } int main() { std::string temp( boost::lexical_cast<std::string>( make_adapter(make_adapter(100, std::hex), std::showbase))); std::cout << temp << std::endl; return 0; } おもっきり実装依存だが つか、ここまでするくらいなら素直に stringstream 使えって言われる罠
本で安全のために記号定数よりconst定数を使う事の方が多いと書いてありましたが, なぜでしょうか? マクロは危険? 副作用はありますが, #define N_MAX 100 とかなら安全のような気もしますが constの方が,コンパイラが厳密にミスを見つけてくれるということでしょうか?
名前空間の安全性の事かなぁ?
>>147 >>148 に追加
マクロはコンパイラではなく、プリプロセッサで処理される。
処理系によってはconstやenumにしておけばデバッガから
シンボルとして追えたりするので便利なことも多い。
マクロの場合は#undefすれば再定義できるので危険。
他になんかあるかな?
float f; f=100.0/3.0; warning C4305: '=' : 'const double' から 'float' へ切り詰めます。 なぜに? 小数の計算は,元々doubleで計算されるから?
100.0f/3.0f
string s; s="metjgetijgse;9gjser;0gj;sejge09u4g5;4sejgso4ejmo;gnje;oirjge905gjm;e0j5g:;ejmg;e5jge5jg;0erjg;erjhgo59rhjg;rhjgn0p;strhjg"; 可能?
155 :
デフォルトの名無しさん :02/09/24 18:20
マクロ定数とconst定数の話だけど、 const定数は宣言した分のメモリ空間しか占有しないけど マクロ定数は利用されているところに展開されるから いっぱい使われてると、その分メモリ圧迫するとか そういう事ってあったりするんでしょうか? というか、そういう違いを吸収するのがコンパイラの性能なんでしょうか?
>>155 > const定数は宣言した分のメモリ空間しか占有しないけど
その代わり変数アドレスをそこら中にばらまくことになるから、大差ない。
文字列の場合はそうともいえない。
const std::complex<zero> zero(0); と #define ZERO std::complex<double>(0) はエライちがいじゃないか。
>>158 一方が const で他方が非 const だと、全く意味が違うと思われ。
(言いたいことは分かるが)
const int GLOBAL=0; のような定数宣言をヘッダファイルに書いて、 これを複数の cpp ファイルにインクルードしたとき、実行時には cpp ファイル毎に定数のためのメモリが取られるんでしたっけ。 (最適化で変わることもある?)
俺はやっぱ名前空間の問題が一番大きいと思うな。 #define はめったなことじゃ使わないで欲しい Winプログラムしてると泣けてくる
int i=0; a[6]={1,1,1,1,-1,1}; while(a[i] != -1) { //処理 ++i; } この場合,別にi++でも問題ないよね? 普通は,どっちを採用した方がいいんだろうか?
>162 ++i
>>161 #define N '\n'
cout << "a=" << a << N;
ウマー
endl使えよ!
>>165 素直にendl使えよ。
ところで、streamって<<演算子呼ばれたら勝手にflush呼ぶんだっけ?
>>167 <<演算子じゃなくて、endlん中でflushしてるんじゃなかったっけ?
手もとにソースがあったので、glibcでの実装。 ostream& endl(ostream& outs) { return flush(outs.put('\n')); } operator<<()ではflushしてないっす。
std::coutの直後にstd::cinを呼ぶとflushされる。
171 :
デフォルトの名無しさん :02/09/24 22:58
>>160 gccでconst intの場合を試してみたら、Cの時は実体が作られたけど、
C++の場合は最適化すると実体が消えるみたい。
最適化をしなくても、constを付けるとファイルスコープになるらしく、
hoge.c(cc):
extern const int i;
int main(void) {
return i;
}
moge.c(cc):
const int i = 1;
fuga.c(cc):
const int i = 2;
とすると、Cでコンパイルするとmultiple definition of 'i'に
なって、C++でコンパイルするとundefined reference to 'i'に
なった。
ちなみに、Cで最適化ありの場合、
static const int i = 0;
int main(void) {
return i;
}
をコンパイルすると、return i;はxorになって、iはどこからも
使われていないのに、iの実体だけは作られていた。
Cのこの挙動の理由が分かる人いない?
>>171 > 最適化をしなくても、constを付けるとファイルスコープになるらしく、
> とすると、Cでコンパイルするとmultiple definition of 'i'に
> なって、C++でコンパイルするとundefined reference to 'i'に
> なった。
仕様だ。C++ では、const つけるとディフェルトはファイルスコープになる。
>>173 > ディフェルト?どういう意味?
D-Felt だ。手触りがいいフェルトなんだよ...、って Typo だよ、いちいち指摘すんじゃねー。
176 :
デフォルトの名無しさん :02/09/25 00:02
素直にstringstream使えよ
>>168-170 Thx.
なんでそんなこと聞いたかというと、
>>165 はstd::flushを呼び出してないので、
画面に表示されないこともあるのかなぁ…と。。。
でも、どこかで、'\n'を書き込んだら自動的にフラッシュされるとか
書いてあったような気がする。。。
自信がなくてスマソ
178 :
vcpp6 :02/09/25 12:05
すみません。質問させてください。 クラスのメンバ関数のデフォルトの引数は、 class A{ void func( int = 1 ); }; void A::func( int i ){} ↑以外の方法で指定できますか? ホントは↓のように指定したいのですが、エラーが出ます。 class A{ void func( int ); }; void A::func( int i = 1 ){}
class A { void func(); void func( int i ); }; void A::func(){ func( 1 ); } void A::func( int i ){}
180 :
vcpp6 :02/09/25 12:21
オーバーロードですか。ソースが長くなりますね。
まあ、ほんの2行ですが。
>>179 さん回答どうも
引数が複数あるときはその引数数×2行分長くなりますね。
>>180 まぁ、しょーがないよ
class A{ void func( int ); };
と宣言されたメンバ関数を
a.func(); と呼び出すことは不可能だもんよ
コンパイラは
void A::func( int i = 1 ){}
なんてされてるなんて知らないからね
182 :
vcpp6 :02/09/25 12:31
レスどうも。
>>181 さん
なんか、インラインなら出来そうですが、
インラインはやめたほうがいいでしょうか。
メモリを食うとか、何とか、デメリットが有ったような気がします。
↑この辺忘れてしまったので御教授お願いします。
183 :
デフォルトの名無しさん :02/09/25 12:36
WindowsでFindWindow関数の第一引数は そのアプリケーションのウィンドウ名ということですが、 他の方の作ったアプリケーションのウィンドウ名の 取得はどのようにすればよいのでしょうか?
>>172 なんか、先に宣言してから定義するとグローバルになるっぽいけど、
何だかなあ。
>>182 インライン(ヘッダに実装がある)ならば技術的に実装は可能だろうけど、
仕様がそれを許してないから意味無い
>>171 >gccでconst intの場合を試してみたら、Cの時は実体が作られたけど、
>C++の場合は最適化すると実体が消えるみたい。
やっぱりそうですか。
宣言の数がかなり多いので、cpp ファイル毎に領域が取られると
すると無駄になってしまいますよね。最適化を考えない場合は
素直に extern したほうが無難ですかね。。
以前 const 定数について、& 演算子で定数のアドレスを取るなど
しない限りにおいては、#define のように値が定数の使用個所に
埋め込まれる(ことがある?) というような話を聞いたことが
あります。激しくうろ覚えですが、最適化の話だったかも
しれません。
>>188 C++だとconstはデフォルトでstaticだから、
アドレス参照などで必要にならない限り実体を持つ必要はない。
念のために書いておくけど、実装上は&を使うかだけでは判断できない。
複合型やdoubleなんかの場合は使っただけで割り当てられる場合もある。
#define KAKOU a '[' << a << ']' cout << KAKOU(a) << N; ウマー
cout << a '[' << a << ']'(a) << N;
#define KAKOU (a) '[' << (a) << ']'
つーかどうみても189じゃなくて,190だろうが
externがよくわからん俺はドキュでつか? (どっかに実体があってって話わわかるけど、 あんまり使えないっつーこってす。)
よく使う実体(Appインスタンスとか)をexternしてるけど
コード 44 (0x2C) で終了って正しく終了できているのですか?
>>196 それか、mainをint型にして0で終了汁
VC++をつかってます. C:\Windows\デスクトップ\Hossaka\新しいフォルダver2\visual.c(190) : warning C4715: 'mean' : 値を返さないコントロール パスがあります って警告がでます.どうしたらいいのでしょうか?
>>199 int func1( int i )
{
if( i )
return 3; // 警告。i == 0 では何も返さない。
}
こういうこと
>>199 >>200 みたいになってない?
だから
int func1( int i )
{
if( i ) return 3;
return 0;
}
に汁
int hoge() { ・・・ switch(i) { case 1: return 1; default: return 0; } } これは警告オプションとかきつくしたりしても警告出ませんか?
3項演算子だったら大丈夫 (i?1) return 1:return 0; そっちは知らんけど,必ず実行されるならいいんでない? おすすめはしないけど
>>204 それを書くなら return (i == 1) ? 1 : 0; だろう。
ワラタ
int mean(unsigned char c[]) { int i,buf; buf=0; for(i=0;i<27;i++){ buf+=(int)c[i]; return(buf/27); } } ってなってます
それは、 int mean( unsigned char c[]) { return c[0]/27; } とどう違うのか?
ワラタ
ワラタ
extern int A; と extern "C"{} でなぜ同じキーワードを使うのかワカラン
>>189 >C++だとconstはデフォルトでstaticだから、
>アドレス参照などで必要にならない限り実体を持つ必要はない。
なるほどです。
このことは言語仕様で決められているとかではなくて
各コンパイラが、こういうケースでは実体は必要ないと
解釈しても良い(実体を生成しなくても良い)という
ことでしょうか。
>念のために書いておくけど、実装上は&を使うかだけでは判断できない。
>複合型やdoubleなんかの場合は使っただけで割り当てられる場合もある。
例えば double 型の定数に記憶が割り当てられるか
どうかは、それぞれのコンパイラの解釈に依るという
ことですよね。
>>160 const はデフォルトでは static linkage だから、それをヘッダに書くと
翻訳単位毎に別々の実体が割り当てられるが。
既出もいいところだったな。すまん。 ところで extern で const int a; とかとったとしても printf("%d", a); というプログラムをコンパイルすると「変数 a のアドレス」が出てくる。 オブジェクトコードのサイズだけ見ると printf("%d", 1); も全く変わらんぞ。
intで比べてもしょうがないだろ(藁
大抵ポインタのサイズはintと同じだから extern const char str[]; cout << str << endl; と cout << "asdfghjklqwertyuiopzxcvbnm" << endl; が同じだったら考え直す
>>215 アセンブリ言語のコード吐かせて比較汁。
220 :
引きこもり :02/09/26 16:51
お前らintって聞いたらinteger思い浮かべるか? interrupt思い浮かべるか?
int86ならinterrupt int32ならinteger
integer interruptはINTって大文字じゃなきゃ。
21でもinterruptかな
IRQは俺だけか、、、
>>224 > IRQは俺だけか、、、
俺もだよ。68系は IRQ だからな。でも、68系のソフトウェア割り込みは、SWI か TRAP だから 86 みたいに混乱 (はしてないようだが...) は無いね。
intをあえて日本語で言えば整数となるだろう。 しかし、断じてこれはintegerではない! intはintなのだ。ひとつの単語なのだ。 あ〜int、愛しのint・・・
>>228 TeXnicianですね( ̄ー ̄)ニヤリッ
>>227 >しかし、断じてこれはintegerではない!
分かる気がする…Pascalとかでhoge:integerという表記を見るとなんか違和感がある。
hoge:intじゃないのか、と。たまに人のDelphiのソースいじったりすると、hoge:intと書いて
コンパイラに怒られています…(;´Д`)
charも混ぜてください
231 :
デフォルトの名無しさん :02/09/27 06:08
>>230 ほんとうは文字列でもなんでもないくせに、自分の所在をchar *で表すようなやつはダメ。
232 :
デフォルトの名無しさん :02/09/27 18:24
>>231 BYTEならいいですか?typedefで見せ掛けだけですが・・・
ofstreamでバイナリで開いてもバイナリで書き込んでくれませんが
こんなにファイルサイズが勿体無い仕様にしたのは何故でしょう?
233 :
デフォルトの名無しさん :02/09/27 18:41
>>233 ofstream fout("aaa.a",ios::out|ios::trunc|ios::binary);
fout<<0x12345678<<'\n';
fout.close();
とやってもファイルには
305419896
と書かれるのですが・・・
文字列はstringだってママンから習わなかったの?
いやバイナリで開いてるんだから数値を直接入れてくれてもいいのかなと
neta ha sine
238 :
デフォルトの名無しさん :02/09/27 19:05
バイナリで 78 56 34 12 0a ってなればいいかなと0aは'\n'でし
でも fin>>iで iのサイズとれば値を取得できるような・・・
連続カキコすいません テンプレート関数内でTのサイズ計れなかったですか? 計れるのならばバイナリで直接数値をぶち込んでも問題はないかと 時間なのでもうすぐ帰ります
243 :
デフォルトの名無しさん :02/09/27 23:13
>>232 > typedefで見せ掛けだけですが・・・
身分詐証、それがイカンのよ。
>>236 >いやバイナリで開いてるんだから数値を直接入れてくれてもいいのかなと
ネタとしか思えん…
「バイナリを使えば何でもできる」 そう純粋に信じていた無垢な時代が、漏れたちにだって……なかったなあ
XMLなんて文字ばっかり
釣れた釣れた ってそろそろ来るんだろうな・・・。
248 :
デフォルトの名無しさん :02/09/28 06:37
C++でpimplイディオムを利用すると自分が敗者になったような錯覚を覚えます。 どうしたらいいでしょうか?
漢なら全部テンプレートにしろ。 cppファイル1つにhファイルが2000、とかの状況に萌えろ。
>248 pimpl をただの構造体として使っているとか? メンバ関数も持たせて、処理を移譲するようにしてやると少しは オブジェクト指向らしくなると思う。 オレは昔は純粋仮想関数からなるインタフェースクラスを継承することに 美を感じていたが、最近では多態が不要なところでそれをやるのは ダサいと思うようになってきた。そういうところは、pimpl を使って 処理を移譲するほうが美しい。
>>251 ただの構造体隠蔽として使う方がまだ美しいと感じる。
ガワと中身という違う物を実装しているとはいえ、
見てくれ(インターフェイス)が同一な物を2度作らなきゃならんのがダサいと思う。
>最近では多態が不要なところでそれをやるのは
同一の理由により、インターフェイス継承もやりたくない。
pimplなんて使うのはダサい!!! 男は黙ってコンパイルせい!! Pentium 166MHzで!!!
構造体ってなんだっけ? ・・・・あ、structureのことか。 日本語キモくって最近使って無かった(w
>>254 国賊め!!!
北朝鮮に拉致されてしまえ!!!
257 :
デフォルトの名無しさん :02/09/28 17:27
仮想でない関数はクラスの外で宣言できるようになっていれば、 データ構造だのprivate関数だのを外に晒す必要も無くなるだろうに。 あとメンバtypedefやメンバconstの類も。 operator newがあれば前方宣言だけでインスタンスまで作れる。
>>257 そのかわり間接参照が一回増えるのが嫌…っつー時代に設計された言語だ。
そこを責めてくれるな。
C++処理系には前処理だけを行なうスイッチが用意されている。 Visual C++の場合 cl /GX /P smp1.cpp -/Pスイッチで前処理だけしてsmp1.iファイルを作る というふうに本に書いてあったのですが,意味がわからないのですが・・・ あと,cstdioとかは,ネームスペース名は,std;ではなくてどういうのになるんでしょうか?
260 :
デフォルトの名無しさん :02/09/28 19:09
std::ostream に NULL 終端ではない char[] を指定文字数分だけ出力したいのですが、スマートな方法はありますでしょうか? 考えた方法は 1.バッファを確保し strncpy 後に NULL を追加して <<(ostream&, char*) うまくいくだろうけどバッファの動的確保のコストが気になる。 2.ループで指定文字数まで <<(ostream&, char) うまくいくだろうけど効率悪すぎ 3.std::setw 指定文字数より長い場合には何もしてくれない 4.同期化された静的バッファにコピー後に <<(ostream&, char*) バッファ長より長い文字列の場合に結局ループしながら書き出さなければならない & 同期化のコストもちょっと気になる。 何か良い方法はないでしょうか?
>>261 そんな冷たい事言わずに…
「ない」って言い切るくらい凄腕な方なら、私が考えた例よりも
効率の良い方法とかもいくつか思い浮かんだりするでしょう?
トレードオフの問題も絡めて、私の愚考よりも少しでもいい方法とかあったら
教えてください、よろしくお願いします。
260=262です。よろしくお願いします。
264 :
デフォルトの名無しさん :02/09/28 19:25
>>258 スタック上にインスタンス作ったり、operator newが無かったりする時は、
クラスの定義が必要、となっていれば、別にオーバーヘッドは無いだろ。
>>260 単純に
basic_ostream::write( const char_type *, streamsize )
でダメなのか?
int n; cout << (cin >> n) << endl; なんか変な数値が出るんだけども,cin関数の戻り値が表示されてるってこと?
>>262 効率の良い方法を求めてるわけ?
答えは簡単。
ostreamを捨ててどっかからファイルクラスを拾ってくる。
これ、最強。
>>266 MSDNより
cin
extern istream cin;
このオブジェクトは、標準入力からバイト ストリームを抽出します。オブジェクトが生成されると、cintie() を呼び出し、&cout を返します。
struct A { }; struct B { friend void func(A& a) { } }; struct C { friend void func(A& a) { } }; void test() { A a; func(a); } これってエラーにならんのね(VC)
funcはクラス外で宣言されたものとみなされるから、かな?
>>270 struct B と C のどっちのfuncを呼んだのだろう?と思って
舌のようなコードにしたら、Bが呼ばれてた。
struct B
{
friend void func(A& a)
{
printf("struct B\n");
}
};
struct C
{
friend void func(A& a)
{
printf("struct C\n");
}
};
…Cのほうは?
class と struct の違いって何よ?
>>272 デフォルトのメンバがprivateかpublicか。
>>272 structはprivateなメンバがないクラスを記述するのに使うとよい。
>>264 operataor new というか、ファクトリを前クラスに定義しろって話か?
できそうな気はするが、多重定義や名前空間に絡んで、予期せぬ名前解決された
ときにリンクするまで(あるいは実行時エラーが出るまで)トラブルが判明しないとい
う嫌なバグを作り込みそうな気がする。
VC以外はどう?
bcc, gcc共にコンパイルできず。 funcがすでに定義されてると。
>>266 iostreamはストリームの状態を表す為にoperator void*()とoperator!()をオーバーロードしてるんだよ。
std::cout << (cin >> n) << std::endl;
この場合、istream::operator>>(istream&, T)は第一引数を参照で返すから、
(cin >> n)はcinそのものを返す、と。
で、そのあとcinを出力する為にistream::operator void*()を呼び出す為、
一見不可解な値が表示されるというわけ。
こまったもんだ
>>280 くっ,全然わからない・・・
C++勉強し始めて,7日目だけどいつ頃になったらわかるようになるかな?
最初から頭を突っ込むところじゃないと思うけど・・・
>>282 最初は誰でもわからない、特にC++はCとは違って体系的な学習が
不可欠だ。
取り敢えず入門書1冊読破せよ。
>>285 はるひこさんのビギナー編ファイル入出力意外全部読みました
C++やると,C言語に戻りたくないですね
>>286 読むだけではなく、手間を厭わず打ち込んで試してみた?
そういう一見無駄な努力が、実はとても役に立つのだ。
>>287 すごくうちまくったよ
とはいわないけど,50回くらいは,
cout << "a=" << a << '\n';
進化
cout << "a=" << a << endl;
とか打ちましたよ
まーもっと打てよぼけとか言われそうですけど
C++覚えると,就職有利になりますかね?
c/c++募集ってとこにいきたいんですけど,C言語だけしか覚えていないんですよね
>>288 晴彦はどうかと思うが…。
まあ次は何かアプリ作ってみなさいってこった
>>288 あとは using namespace std; を外して、std::を識別子の前に付ける
ようにすればよい。
就職は、ほとんど会社に入ってから覚えさせられる事が多いので、
まずは自分でバグ取りできるだけの力をつけるようにする。そうすれ
ば進歩が速い。
>>290 クラス内でusing namespace std;とかする分には
問題ないんじゃ?
あと関数内で。
C#やるようになって、C++のヘッダと実装を分ける書き方がなんと美しかったことかと気づかされた。 かといってC++の#includeはいやだ・・・う〜〜む・・・
>>288 > C++覚えると,就職有利になりますかね?
C++ 使う職場なら、もちろん有利になる。
295 :
デフォルトの名無しさん :02/09/29 08:13
VC++.NETで std::ios::noreplace がないんだけど。 他に変わる物もみたらないのですが、どうすればよいのでしょうか?
>>296 ありがとうございます。
古いバージョン使うのあまり気が進まないです。(将来使えなくなりそうなので)
先にファイルOPENして確認するとかしかないか...。
>>297 分けないとネストが深くなりすぎてみにくくなる。
まぁ、オレもC/C++の#includeはちょっと好きじゃないけど。
C++なんてnamespaceがあるんだからヘッダのネストとかで悩ませられるのはどうかと思う。
ヘッダは無駄と思う。設計ミスって引数変えたり名前変えたりしたときにヘッダもいじらにゃならんし。 そもそも2度同じこと(プロトタイプ宣言とか)を書かないといけないのがスマートじゃない…。Cは仕方無いとして、 C++はなんでヘッダがあるんだろう…?
>300 テンプレートライブラリのため
302 :
デフォルトの名無しさん :02/09/30 00:43
Cというなの言語は今はありません。死に耐えました。 ただC++によってそのコードは今生かされているだけなのです。
>>301 いや、分かってるよ。
分かってるんだけど、もっと別の(ヘッダファイルを使う以外の)スマートなアプローチは無かったんかい、と。
C++で 比較の結果が0/1であることは保証されてますか?
306 :
デフォルトの名無しさん :02/09/30 16:48
age
307 :
デバックの名無しさん :02/09/30 16:57
乱数はどうやって、発生できるんですか?
309 :
デフォルトの名無しさん :02/09/30 17:18
発生器を使って。
311 :
デバックの名無しさん :02/09/30 17:23
>308 C++でやりたいんです。
>>305 ある意味、保証されているが、そういう認識の仕方は少し問題だと思う。
>>314 どういう事ですか?
Cで比較演算の真偽値が0/非0と言うのは理解してますが、
C++だと0/1が保証されているという記事を読んだので、どうなのだろうと。
>>315 厳密にはC++で比較演算の結果はbool型のtrue/falseを返す。
これを整数に変換すると1/0になるという認識が正しい。
組み込みの比較演算子は保証されてるけど演算子がオーバーロード されてる場合もあるからなあ。。
std::fstreamの質問です std::ofstream TestFile("./test.txt"); として TestFile << "test message..."; とやった場合、メッセージの部分は fstreamの内部にあるバッファへ溜め込まれているだけ という認識でいいんでしょうか? TestFile.flush()するまでファイルアクセスは無いですよね? fstreamのソースみてもわけわからないです・・・
やってみてファイルを見てみましょう
>>319 そんなもん実装依存だよ
flushすれば確実に吐き出されることが保証されているだけ
>>319 バッファが一杯になると自動的にフラッシュされる。
逆に、flushしないで溜め込んでおいたバッファの内容を 参照できるような関数ってあるんでしょうか? 例えばTestFile.c_str()みたいな・・・
>323 検索したらゾロゾロ出てきました ありがとう
>324のミス・・・
rdbuf()の面白い使い方。ファイルの内容をたった一行で 全表示する。 #include <iostream> #include <fstream> int main() { std::fstream ifs("rdbuf.cpp"); std::cout << ifs.rdbuf(); }
>>328 327です。
ソースきぼん。
俺のソースはC++標準ライブラリ、P603、§13.9。
おっとっと間違いハケーン。std::fstream→std::ifstreamにしてください
標準ストリームに関する質問です std::endl std::ends std::flush の実体ってどこで宣言(定義)されてるんでしょうか? ヘッダファイル群にGREPしたところ、ヤツらの型が basic_ostream& (*pf)(basic_ostream&)で受け取れるとこまではわかったんですけど 受け取ってからどうやって振り分けたものか悩んでおります ストリームのラッパークラスなんて初心者が手を出すような領域じゃ無いのかな・・・
>>331 basic_ostreamのような気がする。継承を見ていくと。
>>331 実装によるのでコンパイラと使ってるiostreamライブラリぐらいは書いた方が。
今俺の手元にあるSTLPort for DegitalMarsC++ だと stl/_ostream.h にあったが。
つーか、振り分けって具体的に振り分けて何をするつもりだ?
endl をトラップして自前の改行文字を書くフィルタを作るとかか?
やりたい事は、ファイルオープンと同時に現在時刻の文字列をファイルの先頭に書き込んで ファイルクローズの際に、またその時の時刻の文字列をファイルの終端に書き足すクラスで 標準ストリームのように、<<演算子で次々挿入できるようにして endlとflushを受け取ったときに標準ストリームと同じ様な挙動にしたいなぁと とりあえず<<演算子のオーバーロード(&受け取った型毎オーバーライド)と endlを捕まえてバッファの内容を吐き出すところまでは実装できたんですが そういやflush受け取ったときはどうしよう・・・と悩んでいる最中です
あ、えーと、そんなもんostreamのポインタなりを返す パブリックなメンバ作ればいいじゃねぇかと言う話かもしれませんが mystream.lpfstream << "なんたらかんたら" << endl; とかやると ↑の部分が見苦しいナァと思いまして・・・ 贅沢言うな!ってとこなんでしょうか
>>334 それだったら、basic_fstreamをpublic継承して、endl, ends, flushだけを
オーバライドすればいいのでは。
あとなんでこんなややこしい事しとるのかといいますと fstreamってバッファがいっぱいになると勝手にファイルに書き込んじゃうらしいので 明示的に「書き込め!」って指示するまでひたすらバッファへ溜め込むようにしたいんです >336氏の方法だと、ファイルオープン/クローズ時の 現在時刻の書き込みはどう実装すれば良いんでしょうか?
basic_filebufを自分好みにカスタマイズ
う〜んopen/close時までカスタマイズするとなると、basic_fstreamの コンストラクタ/デストラクタまでオーバライドする必要があるなあ。 しかもbasic_ostreamのヘッダを覗いていたら、endl, ends, flushなど のマニピュレータは、basic_ostreamのメンバ関数ではない様子。 そうなるとオーバライドできないですね。 やはりここは myendl, myends, myflushなど名前を変えた方がよいかも。 rdbuf(pointer)で、大きなストリームバッファは設定できるけど、 出力に合わせて拡張するストリームバッファなんてどうやって実現 していいものやらさっぱりわかりません。
現在の実装では、バッファにstd::stringを使っているので 可変長バッファの問題はクリアだと思います flushをendlと同義に扱うか、もっと研究してflushの正体を暴くか どちらかかと思うのですが・・・ ちなみに以前myendlなどで実装しようと目論んだ事がありましたが マニピュレータのやり方がわからず、グローバルなmyendlクラスを定義して お茶を濁すという、なんとも恥ずかしい過去がありまして 今度こそスマートに実装しようとがんばってみましたが、ちょっとお手上げ状態です・・・
>>340 それだったら何とかなるかも。ユーザー定義のマニピュレータですよね。
template <class charT, class traits>
inline
std::basic_ostream<charT, traits>&
myendl(std::basic_ostream<charT, traits>& strm)
{
strm << std::endl;
// ここにさせたい処理を書く
}
のような感じでどうでしょう。
flushは内部でストリームバッファクラスのpubsync()メンバーを呼んでるなり。
符号付き32bit整数をリトルエンディアンで負数は2の補数表現で出力する関数を作りたいのですが 移植性を考えたときによく分からなくなってきたので質問させていただきます。 最初は以下のようにしました。 void writeInt32(std::ostream &o, long v) { o.write((char*)&v, sizeof(v)); } これだと以下のようなことが気になりました。 ・long*をchar*にした結果は実装依存? ・sizeof(long)が4とは限らない ・longが負の時のビットパターンが2の補数表現とは限らない というわけでとりあえず次に以下のようにしました。 o.put(v & 0xff); o.put((v >> 8) & 0xff); o.put((v >> 16) & 0xff); o.put((v >> 24) & 0xff); ところが、putの引数はcharなんです。 プログラミング言語C++第三版の付録C.3.4(p.942)の下の方には > void f(char c, signed char sc, unsigned char uc) > { > c = 255; // 限定無しのcharがsignedで8ビットなら未定義 とあります。 つまり、(v & 0xff)の結果が255の場合、o.put(v & 0xff)は未定義なのではないでしょうか? あと、負数が2の補数表現でない場合も考えないといけなそうです。 結局標準C++の範囲内でなんとかするのは不可能なのでしょうか?
あ、最後に return strm; つけて下さい。
数値表現の可能性を論じてたら先に進まない。 符号付き整数の右シフトも怪しいから、 unsigned long l = (unsigned)v; としてからo.put(l & 0xff)として書き込むのが良いかと。
>>343 charに127を超えるintを代入した時だけが未定義なのであって、
(v >> 8) & 0xffをputするのは別に代入ではなくて関数の引数
だから大丈夫では?
>>345 >数値表現の可能性を論じてたら先に進まない。
全くその通りですね。2の補数ではない時を考えて負だったらビット反転させて1足して……とかアホなことをやろうかと思ったところで目が覚めました。
>unsigned long l = (unsigned)v;
>としてからo.put(l & 0xff)として書き込むのが良いかと。
実用上これで問題ないと思うのですが、C++標準でsigned charの範囲以上の値を使用した場合の動作が未定義となっているならちょっと怖いなと思ったもので。
どなたかこのコードでうまくいかない環境をご存じの方いらっしゃいますか?
>>346 私もその可能性はあるかなとは思いましたが、一応値渡しですし、代入していることになるのかなと。うーん……
>>347 ビットパターンでの表現を絶対に保つ必要があるキャストということなら、
o.put( reinterpret_cast<char>( l & 0xff ) );
で一応定義された範囲の動作にならんかなぁ。自信ない。
>>343 普通の数学的処理(比較、商、剰余)をすればよい
charが8ビットである保証はないYO
351 :
デフォルトの名無しさん :02/10/01 09:56
c++でJavaにあるfinal( == 継承できない )と同じような事を実装できないでしょうか? Javaにできてc++にできないのはものすごく悔しいんですが... Singletonを応用すれば動的確保限定で継承できないclassが作れますが、 静的なインスタンスが作れないのと、カッコワイルので誰かエレガントな実装を教えてください。
>>351 ヘッダに「継承したら頃す」とか書いとけ
いや継承したら頃せ
354 :
Java厨 :02/10/01 11:12
>>351 悔しいかぁ
>^_^<ぎゃははははは−(爆w
char *hoge; のときは、 hoge = new char[10]; とやればいいと思っているのですが、 char hoge[]; と宣言されている変数を初期化するには、 hoge[10] とかやればいいの?
>char hoge[]; これはコンパイル通らないのではない?
>>351 コンストラクタをprivateにする。
extern char hoge[]; void f(char hoge[]){ // ... } ...って、どっちも初期化の必要は無いな。正直俺の手には負えません
次のコードが "max(long double): 1.#INF" と出力するのはなぜでしょうか。 std::cout << "max(long double): " << std::numeric_limits<long double>::max() << std::endl; gcc3.2(MinGW)です。
const char* hoge() って関数で return NULL; するのはマズいですか? const char* const hoge() の方がいいかな・・・
>>361 あのー、できるだけC++ではNULLの代わりに0を使った方がいいです。
>>364 C++の時は、NULLは0になるのでしょうか。
>>364 C++ thirdを読みましょう。
# ドッチデモイイキガスルケド
ガイシュツだけど、STLPortは次のようになってるね。
#ifndef NULL
# if defined(__cplusplus)
# define NULL 0
# else
# define NULL ((void *)0)
# endif
#endif
ほとんどの場合 (void *)0で問題ないけど、
>>57-62 のような
環境もあるから、0を使った方が無難かと。
>>367 62 は環境の問題じゃなくて自分で勝手に
#define NULL ((void*)0)
したせいでうまくいかなくなったって話じゃないの?
NULL は所詮マクロだから処理系依存だけど、
ほとんどの環境で 0 になってるし、なってなけりゃ自分で#defineすればいいだけの話。
むしろ
p = 0; //( p は int* )
とかなってて、この近辺でバグってるっぽい時に、
本当は *p = 0 なのか p = 0 なのかいちいち見直さなきゃいけないのは時間の無駄。
NULL はソースの可読性を上げるためのもんなんだから使ったもん勝ちでしょ、
と漏れは思います。
1年ぐらい前にそういうスレがあったきがする
gcc3.2(MinGW)では /* A null pointer constant. */ #if defined (_STDDEF_H) || defined (__need_NULL) #undef NULL/* in case <stdio.h> has defined it. */ #ifdef __GNUG__ #define NULL __null #else /* G++ */ #ifndef __cplusplus #define NULL ((void *)0) #else /* C++ */ #define NULL 0 #endif /* C++ */ #endif /* G++ */ #endif/* NULL not defined and <stddef.h> or need NULL. */ #undef__need_NULL となっているから、やはり 0 になるようですね。NULLを使っても現時点の コンパイラでは問題が出ないようになっているのかなあ。
371 :
デフォルトの名無しさん :02/10/01 20:18
文法に member-declaration: decl-specifier-seqopt member-declarator-listopt ; function-definition ;opt ::opt nested-name-specifier templateopt unqualified-id ; using-declaration template-declaration という部分がありますが上から三番目ってなんですか? class c { std::vector<int> ; }; とかやっても結局一番上のやつが適用されているように見えます。 (まぁコンパイルエラーですが) あと、unqualified_id に template_id が含まれているのもようわかりません。 unqualified-id: identifier operator-function-id conversion-function-id ~ class-name template-id 誰か教えて♥
0はポインタとして扱うときは常にnull pointerになるのは保証されてる。 マシンによるnull pointerの実際の表現がどんな形であろうと, ソースの方が0であれば何の問題もない。 で,NULLはnull pointerであることを明示するためのものだから, #define NULL 0 が正解 (C++では)
またNULLの話か(*´∀`)
NULLの次は何? malloc/free?
null ってキーワードを作ってくれよ!
Effective C++にある。nullの実装例。
NULLスレの余寒
null 1 無価値の,効果のない,重要でない. 2 ない,存在しない,ゼロの,ゼロに等しい. 3 〔数〕(集合で)空(くう)の a 〜 set 空集合. 4 特徴[表情]のない,無表情な. NULLスレの余寒
でも、CのNULLとC++のNULLではカナーリ意味合いが違うよね。
俺の会社では 0 を使っているが。(C++ 3rdに従っている)
>>368 氏の意見にも一理あるが、処理系が異なっても NULLの
意味合いを維持できるかちょっと心配がある。
というか今時のC++コンパイラで(void*)0なんてやってる処理系無いよ
>>380 そりゃ char* p; if ( p == NULL ) ...
が通らなくなるからねえ
NULLスレの余寒
ごめんなさい ごめんなさい・・・ ぼくが聞きたかったのは、constポインタを返す関数なのに NULLつーどこに実体があるのか知れないモノを返して良いものかという疑問なワケでして・・・ const char& hoge() だとコンパイルエラーだし、ホンマにえぇのんかっちゅー・・・
NULLと聞いて思い出した素朴な疑問。 C++標準ライブラリでは全ての識別子はstd名前空間内で定義されることに なっていると思いますが、NULLはどうしてstd::つけなくていいんでしょうか? NULLは<cstddef>で定義されるとありますが、同じcstddef内で定義される size_tはよくstd::size_tと書いてあるのを見ます。 でもstd::NULLというのは見たことが無いのですが…… (というか、コンパイル通りませんでした。いや、書きたくもないですが(笑)) #define NULL 0じゃstdに入れられないのは分かるけど C++3rd 5.1.1のようにconst int NULL = 0;とかにすればできなくはないでしょうし。 このあたりのtypedefやマクロの頭につけるstd::の有無はコンパイラによって かなりばらつきがあるみたいです。ホントのところどうなってるんでしょう?
>>383 いいつってんだろヴォケ
NULLの実体?アフォですか?
値返しだから関数から戻るときにコピーが作られるんだよ
>>384 const int NULL = 0; ってポインタに変換できるの?
コードに直接書かれた 0 だけだと思ってたんだけども
NULLスレの悪寒
>385 そんなもんスレ読んどりゃわかるわカス スレがメチャクチャなりだしたから なんであんな阿呆な質問したんか説明しに来ただけじゃドアホ
ここも荒れ出したな・・・・NULLとmalloc&freeは禁句なのだろうか。
NULLスレになってんのは361とは関係ないような・・・
NULL NULL…(*´Д`)ハァハァ…
僕のティムポが NULL NULL してきたのですが...
>>386 C++3rdの5.1.1「ゼロ」の最初によると
「ゼロ(0)は、int型である。しかし、標準変換(C.6.2.3)があるので、
0はすべての整数系データ型、浮動小数点数型、ポインタ型、
メンバへのポインタ型の定数解いて使うことが出きる。……」
ってなってます。で、C.6.2.3「ポインタとリファレンスの変換」を見ると、その中に
「0と評価される定数式は、暗黙のうちに任意のポインタまたはメンバ型への
ポインタに変換できる。」
とあるので、0になる定数式ならなんでもNULLとして使うことができるのでは
ないかと思います。たぶん。
寝てる妹のパンツの中に手を入れていじってたら NULL NULL してきたのですがこれって病気でしょうか?
>>393 サンクス
定数式なら桶なのねん。
・
・・
・・・・・・・・
char* p = ( 50+20*4 )/5 - 26 も null ポインタになるのかしらん?
逆に定数じゃなきゃダメなのかしら。 int a = 1; a--; char *p = a; あ、コンパイル時に無効なアドレスに変換できないからダメなのかな。
398 :
デフォルトの名無しさん :02/10/02 00:56
>>371 class Foo
{
template<typename T> class Bar;
};
::Foo::template Bar<int>; // 三行目
ってことじゃないの?
見てのとおり、メンバークラステンプレートのスペシャライゼーションの
宣言だけれど。
template_id はテンプレートのスペシャライゼーションを表すものなんだから
unqualified_id に入るのも当たり前な気もするけど。
詳しく知りたいなら、一度 ISO/IEC 14882 に目を通すことを進める。
メンバ関数の戻り値が下記のものはどう使い分けるのですか? class CTest { : public: CTest mFuncA(); CTest& mFuncB(); : } Ctest Ctest::mFuncA(){ return *this; } Ctest& Ctest::mFuncB(){ return *this; }
例が分かりにくかったのでもう少し具体的に、、、 下記のコードをコンパイルしてステップ実行したのですが、 戻り値が CTest と CTest& の違いがよく分かりませんでした。 どのように使い分けるのでしょうか? class CTest{ public: int a; CTest mFuncA() {return *this;} CTest& mFuncB() {return *this;} }; int main() { CTest ct1,ct2; ct1.a = 10; ct2.a = 100; ct2 = ct1.mFuncA(); ct1.a = 20; ct2.a = 200; ct2 = ct1.mFuncB(); ct1.a = 30; ct2.a = 300; return 0; }
mFuncAはCTestのcopyを返す。mFuncBはCTestのreferenceを返す。 前者はイヤンな一時オブジェクトを生成する。 後者が返すのはthisそのもの。 # (゚Д゚;)
>398 specialization というか、qualification だよね。 C++ 3rd, C.13.6 に書いてある。
仕様書持ってないからちょっと待って。 違うかも。
>>403 合ってるよ。
referenceを返す方は当然
ct1.mFuncA().a = 20;
ct2.mFuncA().a = 30;
のような書き方ができて、元のオブジェクトのメンバを変えられる。
ct1.mFuncB().a = 20;
ct2.mFuncB().a = 30;
はエラーではないが、一時変数を変更するだけで、その値は捨て
られるので何の効果もない。
スマソ。mFuncAとmFuncBは逆ですた。
抽象基底クラスAがあり、class B,CをAから継承するとします。 関数funcの引数としてB,Cをとりたいとき、 1. template <typename hoge> func (hoge tmp) 2. func (A tmp) 実行速度を含めてどっちがいいんでしょうか?
>>406 顔を洗って出直して来ること。
func ([const] A* tmp);が正解。
func (const A& tmp);もまあOK。
>>398 ありがとうございます、が意味がよくわかりません。
>::Foo::template Bar<int>; // 三行目
のとこはクラスの外側だから「三行目」にはならないと思うんですが。
(templateもいらない(あってはならない?)ような?)
>見てのとおり、メンバークラステンプレートのスペシャライゼーションの
>宣言だけれど。
ということですが、これはなんか意味を持っているのですか?
int;
ってするのと構文的には同じ(block-declaration -> simple-declaration)
ように見えます。
実際、gcc2.95では
> declaration does not declare anything
っていわれます(templateは削って)。
>詳しく知りたいなら、一度 ISO/IEC 14882 に目を通すことを進める。
そこから文法を引用しました。本文は長いので眺めただけですが。
だから C++ 3rd, C.13.6 をよめって。
C++3rd持ち出して偉そうに語るヤシっているけど、 C++3rd買うくらいならIS買う人もいるんだから 持ってるのが当然って言い方はどうかと :P
>>409 読んだけどそれとはぜんぜん違う話だと思うな
ああ、そうか、たしかに状況は違うね。 でも、後続する unqualified-id が template であることを明示する、 という機能では同じものかと思う。ところで、今、 template<class T> class Foo { T::template hoge<int>; }; とか試したけど、g++ 3.2 じゃ、エラーになるね。 ISO C++ forbids declaration of `hoge' with no type `::hoge<int>' is not a valid declarator とか言われる。書き方が間違ってる?
>>412 typename T::template hoge<int>; とすればよい。
>>412 えーとつまりキーワード「template」について
nested-neme-specifier や qualified-id や上述の member-declaration で
同じ意味(次の'<'は演算子ではない)で使われているということ
を言ってるのですか?
それならその通りだと思いますが、
>>371 の質問の意図は「上から三番目」
がどの場面で適用されるのか?ということなので。
>>412 で挙げてある例(?)に
>>413 の修正をしたものも明らかに
>>371 の
「一番上」が適用されると思うし(typenameがあるから三番目にはならない)。
勘違いがあれば突っ込んでね♥
あ、あと
>>371 でunqualified-idにtemplate-idがなぜ含まれるのかわからん
って書いてるのはusing-declarationで使うからっていうことで自分では
納得できたので、この理解で問題なければ触れていただかなくて結構です。
415 :
デフォルトの名無しさん :02/10/02 19:47
スレ立てるまでもない質問にも出してしまったのですが, こっちの方が適切と思うのでこちらにだけ繰り返し 張らせていただきます.ごめんなさい <困ってること> 継承を介してメンバ関数のオーバーロード ではなく多重定義を狙ったのですがうまくいきません. <詳細> 親クラスから継承して子クラスを作りました.そのとき, 親クラスで定義したSet(int)というpublicな メンバ関数があるのですが,これと同じ関数名で 引数の違うSet(int,int)という関数を定義しました. これで,子クラスにSet(int)とSet(int,int)という 多重定義されたメンバ関数が定義されたと思い まして,喜び勇んで子クラスで宣言した変数a からa.Set(int)を呼び出したらgccに 「そんなメンバ関数無いよ」と起こられました. 誰か,こんな現象について知っている方 解説お願いします.
子供が親と同じ名前のメソドを宣言した瞬間、 親の関数は引数にかかわらず全て隠されてしまいます。
a.親クラス::Set(int)
C++の仕様で最もハマりやすいアレですな。 Exceptional C++という本にも説明があったと思う。 今実験したんだけど、virtualでも隠されるとは思わなかった・・・
解決策としては子クラスに using 親::Set; って書けばよいです。 なぜこんなことになるかというと オーバーロード解決はその識別子が見つかった時点で親にさかのぼるのを やめてしまうからです。 つまり 子::Set があるので 親::Setは候補に入らないのです。 で、using-declarationによって 親::Set が 子::Set と同じレベルに置かれるので OKになるっていうことだと。
420 :
デフォルトの名無しさん :02/10/02 20:05
>>416 ,417
どうもありがとうございます.
なるほど,そうでしたか!!このように隠れてしまわない
ためにできる方法はないでしょうかね?ちなみに技術評論社
「決定版 はじめてのC++(塚越一雄)」では
これができるとし っかり書いてありました
が,騙されたということですね.それにしても
分かってよかったです.大変お世話になりました!!
g++では__nullを使うようにしてるんだけど、VC++ではそういう 適当な拡張はあるの?
>>408 C++標準はメンバークラステンプレートの任意のスペシャライゼーションを、
クラス定義の外部で宣言することを許している(クラス内部に存在しなければ
定義もOK)。
だから、クラス定義の外で問題ない。
>これはなんか意味を持っているのですか?
宣言だけしといて、定義しなけりゃその型のスペシャライゼーションを
抑止できるような気もするが……気のせいかもしれない。
#手元にVC7しかないので……
>そこから文法を引用しました。本文は長いので眺めただけですが。
あるなら、せめて9.2とか14.2 とか、ちゃんと読んでみてほしいな
424 :
デフォルトの名無しさん :02/10/02 20:11
>> 418 Exceptional C++にはちゃんと書いてあったんですね! 購入を検討します. >> 419 かっこいいですね!ちゃんと隠蔽の回避方法があるとは! みなさん,丁寧な説明痛み入ります.ありがとう!!
彼女のパンツを見たら__nullっとしたものがついてましたが病気でしょうか
>>401 >>403 >>404 >>405 おっしゃるような現象が確認できました。
(ct2.mFuncA().a = 30; の方はコンパイルエラーになりましたが、)
なんとなく違いが分かりました。どうもありがとう。
428 :
デフォルトの名無しさん :02/10/02 20:28
>>425 あなたがback_inserterだからです
429 :
421=428 :02/10/02 20:29
C++2nd r.13.1「宣言の一致」を要約すると、派生クラスのメンバと 基底クラスのメンバは異なるスコープに属しているので、両方に 同じ名前のメンバ関数があるときは多重定義されるのではなくて 派生クラスのものが基底クラスのものを「隠す」ということに なるようです。
鬱死
>>422 もしかして自分は大前提を知らないのかもしれないので
まずひとつだけ教えてください。
スペシャライゼーションってどういう意味で使ってますか?
自分が知ってるのはクラステンプレートでは
template</* ... */> class templ_name<int> { /* ... */ };
っていうのだけなんですが、これのほかに
最初に「template」が置かれない「スペシャライゼーション」と呼ばれるもの
があるのですか?
(
>>398 では ::Foo::template Bar<int>; を
「スペシャライゼーション」といってるのですよね?)
すみません、VC++で、DOS窓でよいのですが、 S-JISのコードを指定して出力っていうのが、どうしても半角になってしまうんです。 どうしたら全角で出すことが出来るでしょうか?
main() { puts("これでも半角になるのかYO!"); }
>>434 ありがとうございます。
でも、変数にs-jisの文字コードをいれて、
それをs-jisだと指定して、全角で出力するにはどうするといいでしょうか?
よろしくお願いします。
436 :
デフォルトの名無しさん :02/10/02 21:34
いみがわからんのう・・
そのおかしくなるプログラムを見せてみてYO!
main() { std::string s = "これでも半角になるのかYO!"; std::cout << s << std::endl; }
>>435 もしかしてint型の変数に全角のコードを入れてらっしゃるとか?
まさか…… putchar(0x82a0);//←「あ」 とかやってるとか?
はい。
cout.put('え').put('あ'); //er...uguxu
putchar(0x82); putchar(0xa0);
↑ ヲ■
std::cout.put(0x82).put(0xa0);
エンディアーン
447 :
デフォルトの名無しさん :02/10/02 23:21
カラの class Foo {}; があるとき、既存のclass Bar { ... }; を class Bar : public Foo { ... }; に書き換えても、 sizeof(Bar) が変化しないことって保障されていますっけ? VC++の6では無変化かなと思うのですが。
// 環境: VC++7 + STLport 4.5.3 #include <cstdio> int main() { std::puts("hogehoge"); // error C2039: 'puts' : '_STL' のメンバではありません。 }
449 :
デフォルトの名無しさん :02/10/02 23:28
あの、MIDI音っていうんですかね。midiOutShortMsg。 ピアノ音みたいなのが出るじゃないですか。 で、MIDIででる、ギターとか好きな音を大体のですがどうすればいいでしょうか? また、ピアノ音は自然に消えますよね?で、鳴らしつづけるにはどうすればいいでしょうか?
>>447 Barに一つでも新しいデータメンバ or 仮想関数が付け加わったら、
サイズは大きくなるよ。sizeof()という事になるとパディングの問題も
あるけど、おおむね大きくなると見て良い。
>>448 cstdio.hで全体をstdのネームスペースで包んでいない。つまり、STLPortが
適用されていない可能性あり。
452 :
デフォルトの名無しさん :02/10/02 23:31
>>450 Barの変化でサイズが変わるのはOKです。Fooを継承したことで
サイズが変わり得るかどうかだけ知りたい感じでしょうか。
Fooは常にカラです。
>>452 基底クラスに仮想関数があったら、変わるんじゃない?
おもいっきり実装依存な予感 便乗だけどメンバ変数の無いクラスのsizeofの値って決まってたっけ?
456 :
デフォルトの名無しさん :02/10/02 23:34
すごくスレ違いでスマソ。 只今、モナー版にて、「☆☆モナー海を渡る☆☆」 というスレで、その手のプロ(海外版windows等に詳しい方、 AA、モナー職人様、英語のプロ(パソコン用語詳しい方)、 などを臨時必要としています。手の空いている方、 腕に覚えのある方,興味のある方はぜひご参加くださいませ。
ちなみに、Cからのポーティングをやってます。 似たような構造体が大量にありまして、それ一つ一つにメソッド 書いてられません。 コーディング規約の縛りで、Cプログラマが見る可能性のある部分に templateを使ってはだめなので、そういう構造体を一様にFooから派生 させちまえ、という作戦です。void* よりいくらかマシかなと。 Fooで受けたあと、僕の好きになる部分では、templateで各構造体への 処理を共通化する予定と。
それは無理にC++化するとハマるんでない? 仮想関数は使う予定?
>>458 FooにもBar(群)にも仮想関数は使わない予定。というか
両方ともメソッドなしのホントのstruct。
>>459 メソッド無しのstructなら、なぜ継承しなければならないのかと小一時間。
461 :
デフォルトの名無しさん :02/10/02 23:44
せっかくスゲェ波
>>449 が来たってのに、みんな無視かよ!
乗ろうぜ!乗ろうぜ!?
struct Foo {};
struct Bar1 : public Foo { ... };
struct Bar2 : public Foo { ... };
class Hoge {
public: void SetBar( const Foo& foo );
};
SetBarを複数書きたくないから。
>>460
うーん、うーん(;´Д`) あとはnewとmallocが混在しなければ大丈夫・・・かなあ
Hoge::SetBarの中でどうやってBar1とBar2を見分けるのさ?
>>449 は質問っぽい文章をランダムに生成するスクリプトだろ。
(゚听) ツマンネ
#define SetBar( s ) templateSetBar( s ) /* ここだけ C プログラマに見せる */ template< typename type > void templateSetBar( type& s ) { }
>>465 ダウンキャストすりゃわからないはずもないけど?
というか、前に書いたように、別のメソッド
private: template <typename T> void ProcessBar( const T& bar ) { ... }
に渡して、bar.member_name に直接アクセスする予定。
Bar1とBar2で、少なくとも俺が触らなければいけない部分は、
メンバ名、型ともに同一なんでね。
で、Bar1とBar2は、sizeofの値が変わるとまずいらしいのね。
多分構造体の直書きとかしてるんでしょう。Cじゃシリアライズ
も糞もないだろうから。
# なんのために説明してるんだろう。。。
>>468 そうしようかな・・・・・・・
文句きそうだけど。。
>>469 ごめん。469は俺の失言。
どうしよ・・
やっぱりテンプレートだけにします。 メンバ変数だけの構造体の扱いなんて すっかり忘れていた罠。 ど失礼しましたー。
474 :
デフォルトの名無しさん :02/10/03 01:53
ビビッた・・・・ 窓の辺にドスンドスン体当たりしてくる音が聞こえて開けたら 物凄いデカイ蛾だった・・・ 一瞬ツバメかと重多よ
3分格闘して2本の帚で挟んで外に出してやったよ。
STLスレが熱い。
STLスレが臭い。
478 :
デフォルトの名無しさん :02/10/03 02:57
●●●●●●●●「オセロさえ納期内に作れない=OO役立たず 」祭り●●●●●●● /| | |_____ΦΦΦΦΦΦΦΦΦΦΦ||ΦΦΦ | | | ̄ ̄ ̄ /| || | | | / /|TTTTTT TTTTTTTTTT||TTTTT | /\ | /|/|/|^^^^^^ |三三| ^^^^^^^^^^^||^^^^^^^ | / / |// / /| | / / |_|/|/|/|/| | / / |文|/ // / |/ /. _.| ̄|/|/|/ Λ_Λ /|\/ / / |/ / (___) /| / / /ヽ /〔 非OO 〕〕つ | | ̄| | |ヽ/l `/二二ヽ | | |/| |__|/ Λ_Λ / /(_) | |/| |/ ( ´∀`) (_) Λ_Λ | | |/ // / ^ ̄]゚ (` ) | |/ ゚/ ̄ ̄_ヽ ⊂〔〔 非OO 〕
荒らさんと何かネタくれ。
480 :
名無しさん@Emacs :02/10/03 06:12
がいしゅつな質問だとは思うのですが、 コピーコンストラクタと operator= のオーバーロードって どんなときに使い分けるんですか? どっちも同じでいいじゃん、と思うのですけど。
>>480 コピーコンストラクタ:
代入以外でも使える(引数とか戻り値)
const なメンバが初期化できる
operator=:
右辺が同じクラスじゃなくても使える
とか
>>480 初期化と同時に複製するか、
初期化の跡に代入するか、の違い。
483 :
デフォルトの名無しさん :02/10/03 10:26
ポインタに関する質問2点です。 ポインタが( )で囲まれている場合の 通常のポインタとの違いを教えてください。 例 (*Labels)[key]=Value や (*P).first など。 また,* が後ろについている場合の 前につく場合との違いをおしえてください。 例 関数の戻り値が,クラス名*
>>483 そんな簡単なこともわからないのかよ。だっせー。
>>484 要するに答えられないわけですね(^^)
>>485 そう、答えられないの。要するにお前は俺と同レベル、もしくはそれ以下(藁
>>486 ×要するにお前は俺と同レベル、もしくはそれ以下(藁
○要するに俺はお前と同レベル、もしくはそれ以下(藁
488 :
デフォルトの名無しさん :02/10/03 11:06
C++というより、Cの質問だと思うけど たしか a[] は *a よりも「くっつきやすい」ので、 カッコをつけないと *(Labels[key])=Value *(P.first) のように解釈されてしまうんだと思う。 これは全然意味がちがっちゃうよね。 あと、char* など、 * が後ろについている場合は それは「char*」という型名の一部、前についている場合は 演算子。 こんなとこでいいかな?
>>483 1・
括弧は演算の優先順位を変えるだけ
2.
変数に付いてるなら * は常に前にある、
型なら常に後ろにある
int * p;
変数の後ろに * が来たらそりゃ積演算子だ
>488 初プログラムがC++の初心者なので, Cとの差異がわからず申し訳ありませんでした。 にもかかわらずレスいただいて感激です。 まず,1つめについては +激しく理解+ です。 2つめについては…もちょっとよろしいですか? つまり,* が後ろにあってもやはりポインタ型を表す ということでよろしいでしょうか。 今読んでいる本から抜粋しますと Vertex* Edge::souce() となっており,Vertexは自作のクラスです。
>489 あ,返事を書いているうちに新たな回答が ありがとうございます。 つまり,変数とクラスを判別するために, 前と後ろに書き分けるということでしょか。
>>491 ここはちょっと難しいねぇ。
* には3種類の意味があるんだ
型の後ろに付いてポインタ型を表すもの
変数の前に付いて間接参照するもの(typedef含む)
変数の後ろに付いて積演算するもの
変数とクラスを判別するために前と後ろに分けるんじゃなくて
それぞれ意味が違うから書き分けるの
すまん (typedef含む)は脳内消去してくれ、ちょっと意味が違う
>>489 ()は関数呼び出し演算子の可能性もあるYO!
はい,難しいです(´Д`*) ここは,ポインタ型なんだ!と割り切った方がいいのでしょうか。 今,初心者本1冊目の最終章なのですが 例題のプログラムが急に難しい応用や 既出じゃないことが出てきたような気がして 辟易しています。 性格上,全部きっちり理解するまで次に進めないのですが そもそも,このような勉強方法が間違っているのでしょうか(藁 もっとポインタやクラスについて詳しい本を,次々読んだ方がいいのかな。
>>495 ん〜〜漏れがぴきぴきドカーンと来た説明に
変数や関数の宣言は型の右っかわに書いた式がそのまま左にある型と同じくなるように作られたってやつ。
int * p は int* 型の p というより、むしろ *p の型が int と理解すると早いです。
Vertex * Edge::source() は、Edge::source() の戻り値が Vertex* という意味なんだけれど、
むしろ *Edge::source() の型が Vertex と思ったほうがいいです。
そう理解しておくと複雑なポインタ宣言
int (*(*pfunc)(int, int))(void) = func;
みたいなのも理解しやすい
>>496 念力集チューしてみましたがだめぽ…。
ますますこんぐらがってきた!!
Vertex *p_souce がVertexクラスのオブジェクト(ポインタ)
P_souceを宣言しているということは
わかるのですが,
戻り値が Vertex* という意味がどうしてもわかりません。
>int (*(*pfunc)(int, int))(void) = func;
括弧がいっぱいですね。泣きたくなってきました。
>>497 Vertex *v[];
が (array of) (pointer to) (Vertex)
って読めるのはわかるかな?
これがわかってるんなら、関数と変数を分けて考えずに、
Vertex *f();
ていうのは上の「〜の配列(array of 〜)」 が
「〜を返す関数(function retunring 〜)」に変わっただけだと考えるのはどうかな?
つまり、 * も [] も 引数を示す() も変数名(あるいは識別子)に付く「飾り」
っていうような・・。
>498 バカでごめんね。・゚・(ノД`)・゚・。。つきあってくれてありがとね。 Vertex *f(); Vertexクラスにポインタを返す関数fということでしょうか…。 そこはかとなくわかってきたような気も…。 ただ,例題のプログラムの中で *の位置を Vertex* Edge::source(); Labels *getlabels( ); というようにわざわざ書き分けてあるので 何か意味があるのかと思っていたのですが…。 ※Labels というのは,map<string string>をtypedefしたものです。
>Vertexクラスにポインタを返す関数f:に=>の クラスに返すってどこにポインタが入るのよ >Vertex* Edge::source(); >Labels *getlabels( ); 書き分けは意味なし気分次第でしょう
>map<string string>をtypedef あ、これならスペースが無いとコンパイル通らないかも
>500 重ね重ね申し訳ないです。 >書き分けは意味なし気分次第でしょう ま,マジですか…これで一週間悩んでますた。 だって,ポインタの説明の章で int *p ,int* p のどちらの書き方でもかまわないが 本書では,int *pで統一します ってわざわざ断り書きしてあったの。 で,Vertex* これは何だ?と。 小○俊夫タンめ〜ヽ(`Д´)ノ でもおかげでいろいろ勉強になりました。 コレ以上厨質問すると怒られそうなので,また自習に戻ります。 またどうしようもなくなったら来ますのでよろしくお願いします。
503 :
デフォルトの名無しさん :02/10/03 21:53
声を録音するにはどうすればいいのでしょうか
504 :
デフォルトの名無しさん :02/10/03 21:57
ラブホテルにコンクリートマイクを持ち込むといいんじゃないでしょうか
505 :
デフォルトの名無しさん :02/10/03 23:15
506 :
デフォルトの名無しさん :02/10/04 00:11
ヘッダファイルの基本的な書き方を教えてください。 実装とインタフェイスを分けて、実装が変わっても大丈夫なようにする ハンドルを使うのが一般的なんでしょうか?
>>503 スタート→プログラム→アクセサリ→エンターテイメント→サウンドレコーダ
もっと気の利いた回答を期待したのだがな。 洒落のわからんやつばかりだ。 もてねーだろ、おめーら。
市ね508
>>506 >実装とインタフェイスを分けて、実装が変わっても大丈夫なようにする
と
>ハンドルを使うのが一般的なんでしょうか?
の繋がりがよーわからん。
ヘッダファイルの書き方とクラス・インターフェースの設計は別問題だとオモワレ
あーMFCもままにならないままC#は出るしよお DirectXはquaternionだしよ、わからねえっつうの 寝転がったままオナーニしたら精子飛び散るしよお P4ねえからSSE2命令使えねえしデザパタも全然まだだし かなりやることがあるのに全然消化できてない 鬱だよぉ(=;ω;)
stlport\config\stl_msvc.hの中の
#define _STLP_NO_USING_FOR_GLOBAL_FUNCTIONS
をコメントアウトしたら、
>>448 のコードがコンパイルできるようになった。ほっほっほ。
516 :
デフォルトの名無しさん :02/10/04 19:40
テンプレートの引数に応じて、コンストラクタの引数の数を変えることは可能ですか? template<int N> struct A { template<int M> A(); template<> A<1>(int x){} template<> A<2>(int x, int y){} A<N>; }; A<2> a(1,2); 見たいなことなんですが。
>>516 コンストラクタの多重定義、もしくはデフォルト引数では不足なのか?
518 :
デフォルトの名無しさん :02/10/04 19:51
>>517 ベクトルを扱うクラスを自作してるんですが、
内部に持ってる変数をv[N]と定義してるため、
v[1]に対しA(int x, int y)が呼ばれてしまうのは都合が悪いです。
519 :
デフォルトの名無しさん :02/10/04 20:51
WAVEファイルで取り込んだファイルの各瞬間の音の高さを知りたいのですが なにか方法をご存知ですか?
知らん
俺も知らん
フーリエ変換しる!
>>517 +継承でそれっぽいのができました。
ありがとうございました。
524 :
デフォルトの名無しさん :02/10/05 00:12
「C言語なら俺に聞け」スレで聞いたのですがC++じゃないか?と言われたので ここで質問させてもらいます。 人から貰った関数の引数に double *&a というのがあるのですが、これって どういう意味なんでしょうか?
doubleポインタの参照
>>527 還元できるほどの大した事はやってないです。
派生先にB(int x) : base(x)、B(int x, int y) : base(x,y)…を用意して
基本クラスにN個とるコンストラクタが無ければエラーが出るようにしただけです。
>>528 結果の重要性はともかく、
質問した時と同じくらいの情報が、そんなふうに結論として出ると、
なんとなく収まりがいいもんですな。
解決した時に,たとえ自分のくだらないミスであったとしても きちんと報告するのが良い質問者の姿勢です
531 :
デフォルトの名無しさん :02/10/05 13:49
Linux で C++ を使い始めたのですが、シグナル処理のことで判らない ことがあるのでお訊きします。 class foo { ... void A(); void B(int signum); ... }; void foo::B(int signum) { (シグナル処理) } void foo::A() { ... signal(SIGTERM, B); ... } というような構成ですと、コンパイル時に no matches converting function `B' to type `void (*)(int)' という文句を言われてしまいます。B を class foo の外の 関数にすると何も言われずにコンパイルが通ります。 foo 内だと何故駄目なのかよく判らないのですが...
int n; cin >> n; cout << n << endl; aを入力したら,変な数値が出てきたんだけど・・・ なぜに?
>>532 単にnの初期化されて無い値がそのままでたんでは?
int n=893;とするとどうよ。
不正な入力があったら,値が代入されないんですね
マニピュレータって覚えています? あんまり必要なさそうなんで,やりたくないんですが
>>535 大抵のマニピュレータは単なるシンタクスシュガーだ。
必要無さそうだと思うならやらなくて良し。
俺は使うけどな。
537 :
デフォルトの名無しさん :02/10/05 14:34
>510 えーと、ハンドルクラスを使うと依存関係が少なくなると いうのを本を読んだのですが、クラスの数が増えるのと ややこしくなるため、ほんとにこんなことするのかなって おもたのです。 >512 どうもありがとうです。
>>531 一旦staticメンバ関数あるいは単なる関数で受けないとダメ
539 :
デフォルトの名無しさん :02/10/05 15:29
540 :
デフォルトの名無しさん :02/10/05 16:27
ファイル exception.h (ここには例外処理が書いてある)。 ファイル classA.h #include "exception.h" ファイル main.cpp #include <iostream.h> #include "classA.h" #include "exception.h" みたいな事をしていいのでしょうか? この場合、exception.hファイルがmain.cppに2回インクルードされていることに なり、おかしなことになりますか? 何かいい方法があれば教えてください。 また、include等を詳しく説明したサイトがあれば、教えてくれると助かります。
>>540 ちなみに、
#include <iostream.h>
#include <iostream.h>
とかやってみな。おかしくなんないだろ ?
<iostream.h> の最初の方に、
#ifndef _INC_IOSTREAM
#define _INC_IOSTREAM
と書いてあるので、上みたいに2回呼ばれた時にこれがどういう動作するのかよく考えましょう。
インクルードガードでぐぐる。
>>541 てことは、exception.hは
iostream.hみたいにうまいこと書かなければ、なにかおかしいってことですか?
>>542 インクルードガードとは?
インクルードガード。初めて聞きました。 ありがとうございます。 検索して調べて、理解できました。
>>543 > インクルードガードとは?
>>542 は、親切にもインクルードガードで「ぐぐる。」って書いてあるんだから、まずはその通りにしたら ?
じさ
>545 すいませんした。 ついでに、またまたくだらない質問でもうしわけないですが・・・ class Samp { private: int m; double *p; public: Samp(){ m = 0; p = new double; } Samp(int i) { m = i ; p = new double [i] } ~Samp() { delete [] p } }; とやった場合、引数なしコンストラクタでのpを開放しようとしたら、 delete p; となるが、上記のデストラクタでは、なっていない。 これは合法ですか?
>>548 デストラクタでmで判定してdelete演算子を使い分ける。
もしくはSTLを使う。
>549 おお!使い分けですか! 単純なことなのに全然気づきませんでした。 ありがとうございます。 STLでうまいことできるんですか。調べてみます。
>>548 double なら多分大丈夫だけど、クラスだったりしたらまずいと思う。
まあ、
Samp::~Samp()
{
if(0 < m){
delete [] p;
} else {
delete p;
}
}
とするか、引数無しの時も m = 1 にして配列を確保してしまうのがいいかと思う。
mがnew[]したかnewしたかを記録するためのものとは限らない。 そうしたいならせめてconst bool m;とかにしといてよ。 別にnew[]で統一すればいいのでは?
あ、mは配列の数なのね。const bool mは無し。
mが確保したオブジェクトの数ならこうすべきでは? Samp(){ m = 0; p = null; } mが1で初期化されるときとmが0で初期化されるときで オブジェクトの個数が同じく一つであることに問題が生じる 可能性があるかも。
または、 Samp(){ m = 1; p = new double[1]; }
>551 >552 ご意見ありがとうございます。 クラスならまずいということですが、次の場合はどうなんでしょう。 class Array{ private: int m; double *p; public: Array(){ m = 0; p = NULL } Array( int i ) { m = i; p = new double [i] } ~Array(){ if( p != NULL) { delete [] p } } } class ArrayDX{ private: int m; Array *p; public: ArrayDX( int i ){ m = i; p = new Array [i] } ~ArrayDX(){delete [] p} } 何かいろいろし、ArrayDXのインスタンスを作成し、 メンバのArrayの配列もきちっと作成する。 の場合。ArrayDXでインスタンスを作成し、破棄したら、メンバのArray *pの デストラクタはきちっと行われるのでしょうか。
>>556 > ArrayDXでインスタンスを作成し、破棄したら、メンバのArray *pの
> デストラクタはきちっと行われるのでしょうか。
delete [] p; なら行われる。
つーか、new [] で確保したら delete [] するのが基本。
double で多分大丈夫と言ってるのは、大方の実装が大丈夫そうだからと言うだけのこと。
規格上はまずいよ。
>>556 ありがとうございます。
それは、オブジェクトポインタがスコープからはずれたら、
デストラクタが呼ばれて、そのなかにあるオブジェクトポインタ
のデストラクタもよばれて・・・・でいいのでしょうか?
>>558 >
>>556 > ありがとうございます。
自分に礼かよ !! と言う突っ込みは置いといて...
> それは、オブジェクトポインタがスコープからはずれたら、
> デストラクタが呼ばれて、そのなかにあるオブジェクトポインタ
> のデストラクタもよばれて・・・・でいいのでしょうか?
オブジェクトとポインタ って ? よくわかんないけど、
void foo()
{
ArrayDX X(100);
...
}
で、foo() の終了時のこと言ってるなら、その通り。
>>558 スコープから出れば「オブジェクト(を指している)ポインタ」のデストラクタは呼ばれるが、
「オブジェクトポインタの指すオブジェクト」のデストラクタは呼ばれない。
>>538-539 どうも有り難うございます。FAQ なんですね。適当な C++ の本を買って
きて手許に置いたほうがいいのでしょうかね。
>>559 あ・・・。ほんとだ、自分に・・・
>>559 >>560 ってことは
void foo()
{
ArrayDX *X = new ArrayDX(100);
...
delete [] X;
}
の場合は正確でしょうか?
すんません。おなじようなことばっかで
>>562 X は配列を指していない。
この場合は
delete X;
が正しい。
いい加減STLの使用をデフォルトにしようぜ。 必要なところだけ自分でメモリ管理すればいいじゃん。 Cでいちいち標準関数再実装してるようなバカがいないのを見習おう。
double* p = new double [0]; NULLじゃないけどアクセスできないポインタ・・・鬱だ
>>565 しかも、使えないのに delete[] p; としないとメモリリークになる。
なお鬱だ・・・・
スマソ。pに何か別のポインタを代入しない限りメモリリークとは 言わないんですた。 解放し忘れとでも言うのかな。
解放し忘れとメモリリークの違いを小一時間ほど講義していただきたい
参加希望者ですが、 講義の場所と日時と費用を教えてください。
>>568 小一時間も解説するほどではないが。Effective C++にしつこいほど
繰り返し書いてある。
簡単に説明するとすれば、ある領域を指しているポインタがあり、いつ
でも解放できる状態であればメモリリークとは言わないらしい。
有効なポインタが他の値を代入することによって、その元のポインタ
が指していた領域を解放する手段が永久的に失われてしまった時、
初めてメモリリークと言うそうだ。
配列の添字にマイナスが使えるようにする方法ってありませんか?
>>573 解放し忘れであれば、deleteを書いてやればよい。しかし、メモリリークが
起きたポインタをdeleteすると、何が起きるかわからない。
>>572 operator[] をオーバーロード。配列はクラスにする。
>>574 自己レスです。「メモリリークが起きたポインタをdeleteしても、解放できない。」
でした。
>>578 deleteできないならもう開放済みなんじゃ?
>>579 例えばの例。
char* p = new char[100];
p = 0;
pが指していたchar[100]の領域は、p = 0; とすることによって恒久的に
解放できなくなった。
ああ、「解放し忘れ」は行為で「メモリリーク」は状態か
char* p = new char[100]; // ここは(ある意味)開放し忘れ … … p = 0; // この瞬間からメモリリーク ということなのだと思われ。
こう書けばいいかな? char* p; { p = new char[100]; } // 開放し忘れ --------------------------- { char* p = new char[100]; } // メモリリーク
インスタンスとオブジェクトの違いって何ですか?
何度もすまん。 開放→解放
>>586 インスタンスはクラスから生成されるもの
オブジェクトはクラスやインスタンスの総称
589 :
デフォルトの名無しさん :02/10/06 10:56
>オブジェクトはクラスやインスタンスの総称 ほんと?
objectとinstanceを英和辞典で引けば自ずとわかるかと。
違ってたら恥ずかしいんだけど クラスは「クラスというオブジェクト」という意味でしょうか? お馬鹿な俺に教えてちょ。
>>591 お!そこまで想像できるなら問題ないのでは。
JavaとかC#とかを触るとクラスもオブジェクトだなーというのが
実感できまっせ。
インスタンスはメモリ上に確保されたオブジェクトの実態。 これであってる?
>>593 誤解を恐れずに言うと、クラスはインスタンスの工場で、
生成されたインスタンスがどんなものかを全部しってる。
メモリに確保されるかどうかは言語や処理系次第ッス
>>592 あ,合ってるんですか。嬉しいです。
C++だけの時はオブジェクト=インスタンスだったんですけど
Reflection触ってから
>>591 と思うようになったのです。
>>594 メモリ上に確保されないインスタンスとは具体的に
どんなやつ?
ある本でこんな説明を見たことがある 生地からドーナツを切り抜くところを連想してください。 この場合、生地がメモリ。 ドーナツを切り抜く型がクラス。 切り抜かれた部分そのものがインスタンス。 切り抜かれた部分にドーナツと名前を付けました、名前であるドーナツが オブジェクト。
598 :
デフォルトの名無しさん :02/10/06 12:46
ポリフォーリズムについて これって何?
>>596 (;´Д`)いやその・・・この手の話って
クラスにしろインスタンスにしろ、操作にたいする振る舞い、あるいは
それらどうしの関係についての話でしかないですヨ。
どのように実装するかについては各言語あるいはフレームワークで決めていただくと。
lisp系ならクラス定義もcell内の情報だろうし(違うかも)、
C++だとクラスそのものは実体が確保されないこともあるわけで。
ポリフォーリズムに萎え
C++でデザパタのファクトリーメソッドってどうやるのですか? デザパタ本はJavaばっかりなので、わかりません。 既出だったらごめん。
603 :
デフォルトの名無しさん :02/10/06 16:00
ポリフォーリズムage
int data(int a,int b); int data(int a, int b,int c=100); data(100,200); どうなりますか?
605 :
デフォルトの名無しさん :02/10/06 16:15
[]演算子はオーバーロードできますが double ClassA::operator[][](int i, int j) ってできますか? もしくはそれに類するクラスを2次元配列のように あつかう方法とかありますか?
>>604 どっちを呼び出せばいいかわからないから、コンパイルエラーになる。
失敗するとゼロ、成功するとゼロ以外が返ってくる事がわかっている関数の返値で (例えば文字列中にある文字が存在するか調べる関数) 失敗したかどうか条件判断を行いたい場合、比較とビット反転とどちらがスマートなんでしょうか? int result = hoge(arg); if (!result) cout << "ERROR" << endl; //ビット反転と if (result == 0) cout << "ERROR" << endl; //比較
>>607 ==0 のほうがスマート
失敗すると偽、成功すると真が返ってくる関数なら ! のほうがスマート
>>607 ビット反転演算子は、'!' じゃないよ、'~' だ。'!' は、論理否定演算子。
[A] > if (!result) cout << "ERROR" << endl; //ビット反転と
[B] > if (result == 0) cout << "ERROR" << endl; //比較
俺なら、成功した時の戻り値が数値的な意味をもっている (例えば文字列中にある文字が存在するか調べる関数で、成功した時は何文字目かを返すとか) なら、[B]
そうでない (単純に成功/失敗しか返さない) なら [A] でコーディングする。
まあ、好みの範疇だと思うよ。
>605 二次元までで良いなら、今既にある配列クラスを その配列クラスを返す[]演算子を持ったクラスで包む class node //既にある配列クラス { 詳細略 double operator[](int index); }; class MyArray //既にある配列クラスを包括する二次元配列クラス { 詳細略 node& operator[](int index); node m_node; }; >605でやりたかったであろうアクセスを行うと、以下のように解釈される MyArray[1][5] → (node)[5]
>>610 なるほど。ありがとうございます。
自己解決ですが、こんなんありました。
()演算子をオーバーロードする。
operator()(int i, int j)
こんな感じ
612 :
デフォルトの名無しさん :02/10/06 17:22
「かならず継承してから使って欲しいクラス」ってC++的に書けますか? デフォルトの振る舞いとかは全部あるんですけど、 絶対に包括じゃなくて継承して使って欲しいんです もちろん基底クラスのメソッドを直コールするのもNGな雰囲気で・・・ 無理なら無理でOKです
>>612 コンストラクタをprotectedにする
614 :
デフォルトの名無しさん :02/10/06 17:29
615 :
デフォルトの名無しさん :02/10/06 17:29
>>612 class ダミー派生クラス : public 直接使われたくない既定クラス {};
ダミー派生クラス obj;
obj.結局直接呼ばれる既定クラスのメソッド();
とかされてもOKですか?
617 :
デフォルトの名無しさん :02/10/06 17:31
>>613 それだと
class Test :public base
としたとき
Test->base::hoge()
とかで基底クラスのメソッドを呼べちゃいませんか?
どうしてもTest->hoge()とさせたいんです
かといって、virtual base::hoge() = 0; では困るんです
618 :
デフォルトの名無しさん :02/10/06 17:32
>616 そうですそうです 結局基底クラスが呼ばれていようと、派生クラスのメソッドにアクセスしてるように見えたいのです
619 :
デフォルトの名無しさん :02/10/06 17:33
インターフェースと実装を分離すればいいんじゃない?
>>617 Test->hoge();は桶で
Test->base::hoge();は駄目か・・・
全部のメソッドをprotectedで継承して
派生クラスでpublicなラッパを提供するしか漏れには考え付きませんが。
class Base { public: int hoge() {return 1}; }; class Test :public Base { }; int main (){ Base A; //これはコンパイルエラーにしたい Test B; cout << B.Base::hoge(); //これもコンパイルエラーにしたい cout << B.hoge(); //これはSTDOUTに1を流したい } ということです
やっぱりかなり強引なことをしないと無理っぽいですか・・・ まだ設計段階なので無理なら無理でOKなんです
624 :
デフォルトの名無しさん :02/10/06 17:45
クラスで、標準ライブラリの iterator(反復子)のように *演算子関数を定義したとき、その演算子関数の戻り値のメンバに -> を使ってアクセスすることは、可能ですか? class X { public: int m_x; }; class Y { public: X m_y; X& operator*() { return m_y; }; }; Y y; (X&) *y; //普通にアクセス ○ (*y).m_x; // X のメンバ にアクセス。○ y->m_x; //こういう書き方は可能 ?
>>612 そういう設計にせにゃならない理由を是非お伺いしたいであります。
>>624 無理じゃないかな・・・operator ->()が別にあるし
>>623 > やっぱりかなり強引なことをしないと無理っぽいですか・・・
> まだ設計段階なので無理なら無理でOKなんです
何でそんなことが必要なん ?
>>625 ,
>>627 自由度を狭める事で、逆にインターフェースを簡潔にできないかという目論みです
カスタマイズされることが大前提のクラスなので、なんでもできてしまうのはちょっと困るのです
629 :
デフォルトの名無しさん :02/10/06 17:56
>>628 > カスタマイズされることが大前提のクラスなので、なんでもできてしまうのはちょっと困るのです
そのわりには、「結局基底クラスが呼ばれていようとも...」なの ?
一体誰から何を守りたいのかよく考えた方がいいと思うよ。
class TestImpl{ public: int hoge(){ return 1;} virtual void LONGLONG_MEANLESS_FUNCTION() = 0; } class Test : protected TestImpl{ public: virtual void LONGLONG_MEANLESS_FUNCTION() {}; }; で、Testを継承させるのはどうだ。
カオスヘッダーから地球を守るにきまっとるだろうがヴォケが!
>>630 多分
class Test : public Base
が、後々の変更で
class Test : public CustomizedBase
になる可能性もあるから、
直接
pTest->Base::hoge();
とかやられると、
基底クラスを変更したときに困る、とかじゃないかな
あ、純粋仮想メソドの名前は、 THIS_CLASS_CANT_BE_INHERITED_DIRECTLY() とかの方がいいかな。
> 基底クラスを変更 ガクガクブルブル
>>630 誰からかは不明瞭ですが、守りたいのは「簡潔さ」です
「利用者の大半がカスタマイズするだろうし、もしかしたら自分もそのうちカスタマイズするかもしれんから
とりあえず継承しておけ」というクラスなんですが
かといって、「とりあえず継承はしたけど、どうせここは基底クラスを使ってるんだからTest->Base::hoge();でいいや」
とやられないようにしたい
後で結局カスタマイズした場合に、その部分を直し忘れてエラーになったりしないように
もちろん
>>633 みたいな怖ろしい事は考えていません
>>631 そっちの話 (かならず継承してから使って欲しいクラス) は、
>>613 で OK だと思う。
問題は、「基底クラスのメソッドを直コールするのもNG」の方だろ。
>>632 話の内容についてこれないなら書き込むな、ヴォケ。
>>633 クラスの仕様書に、「直コールは止めてくれっ。」と書いておけば、規定クラス名が変更された時に困るのは変なことしてる奴なんだから別にいいと思う。
どっちにしても、基底クラス名を変更したら継承している所は修正しないといけないしね。
そもそも、基底クラス名なんてそんな簡単に変更しないと思う。
まぁ、普通のクラスで基底クラスを変更するのはまれだろうけど、 Modernなtemplateプログラムしてると当たり前のように基底クラスは変わるよ。 あんまり怖がりなさるな、おのおの方。
>637 「基底クラスのメソッド直コール」ってのは > cout << B.Base::hoge(); //これもコンパイルエラーにしたい ってことだろ。 なら、 class Test : protected TestImpl{
あ、BaseとTestを間違えてたな。 class BaseImpl{...}; class Base : proteced BaseImpl{...}; class Test : public Base {...} ; ってことで。
>>638 > Modernなtemplateプログラムしてると当たり前のように基底クラスは変わるよ。
だから ? template 使ってるって自慢 (にもなってないけど) したいだけなのか ?
すみません、雲行きが怪しくなってきたので「多重継承とかしないと無理」って事で諦めます 何か修飾子付けるだけとか簡単な解決方法はあるのかなーと思っただけですので・・・
>>641 635と636が怯えてるから、よくあることだと書いたまでですが
644 :
デフォルトの名無しさん :02/10/06 20:36
おまいら、CppUnitとか使ったりしてますか。
CppUnit+cocuppaこれ最強。
646 :
デフォルトの名無しさん :02/10/06 22:59
3次元配列の領域を動的に確保する方法を 知っている方教えて下さい。お願いします。
>>646 double*** p;
p = new double**[10];
for (int i = 0; i < 10; i++) {
p[i] = new double*[20];
for (int j = 0; j < 20; j++)
p[i][j] = new double[30];
}
double[10][20][30] が使える。
>>646 もう少し簡単な方法。
double (*d)[20][30];
d = new double[10][20][30];
>>647 有難うございます。
2次元配列と同じ感じなんですね。
やはりポインタの理解が足りないな…
すまん…ネタだと思ってた(鬱
ここはC++スレですので、C++らしい解決をお願いします
vector< vector< vector< double > > >か? template< int N > class Nd_vector;を自作する話か?
653 :
デフォルトの名無しさん :02/10/07 00:12
std::string の操作についてお聞きしたいのですが、 char hoge[10] = { ... }; string s( 10, '\0' ); memcpy( &s[0], hoge, 10 ); というのは有効な操作ですか? 有効である場合、これは s.assign( hoge, 10 ); と同じ効果が得られるでしょうか。
>>653 なんか2ちゃんでもcppllでもそんな話題ばかり見かけるなぁ。
なんでmemcpyなんてしたいんです?
> char hoge[10] = { ... };
なぜに { } なんだと小一時間…
>>653 memcpyした場合の結果は保証されません。
push_backもしくはback_inserterを使うようにしましょう。
やはりstd::vector使った方が楽でいいや。operator[]をオーバーロード して多次元配列のクラス作ろうとしたけど、よくわからん。 std::vector<std::vector<std::vector<double> > > v; v.resize(10); for (int i = 0; i < 10; i++) { v[i].resize(20); for (int j = 0; j < 20; j++) v[i][j].resize(30); } for (int i = 0; i < 10; i++) for (int j = 0; j < 20; j++) for (int k = 0; k < 30; k++) v[i][j][k] = i * 600 + j * 30 + k; for (int i = 0; i < 10; i++) for (int j = 0; j < 20; j++) for (int k = 0; k < 30; k++) std::cout << v[i][j][k] << ' ';
せっかくsize()メンバ関数があるのだから、このように書いた方がいいな。 v.resize(10); for (int i = 0; i < 10; i++) { v[i].resize(20); for (int j = 0; j < 20; j++) v[i][j].resize(30); } for (int i = 0; i < v.size(); i++) for (int j = 0; j < v[i].size(); j++) for (int k = 0; k < v[i][j].size(); k++) v[i][j][k] = i * 600 + j * 30 + k; for (int i = 0; i < v.size(); i++) for (int j = 0; j < v[i].size(); j++) for (int k = 0; k < v[i][j].size(); k++) std::cout << v[i][j][k] << ' ';
>>653 memcpyじゃなくてstd::copy
非コンストにも使えるfor_eachって欲しくねぇ? resize一気にかますときとか
>>657 vector<vector<vector<double> > > v(10 ,vector<vector<double> >(20, vector<double>(30)));
>>659 こんなのはダメなのか?
void square(int& elem)
{
elem *= elem;
}
std::for_each(coll.begin(), coll.end(), square);
標準C++ライブラリp317〜318より
>>660 へえ〜、コンストラクタの結果をクラスの型として返せるのか。初めて知った。
boost::multi_array<double, 3> array3d;
>>660 んー勘違いしていました。コンストラクタの結果をコンストラクタに
引き渡しているんですね。
>>654 つまり、memcpy と同じインタフェースを持つ関数があって、
それを使って string の内容を更新したいということなんです。
いったん、配列なり vector なりで受けてから、それを
string にコピーすればいいんでしょうが、2回コピーすることに
なるのがちょっといやかな、と思ったので。
>>655 s.resize(10) しておいてから memcpy でもだめなんでしょうか。
vector みたいに、&s[0] が配列を指す、という保証はないのかな。
>>662 ん?
単に要素の初期化をしてるだけだけど。
>>655 ,
>>658 ああ、そうか、std::copy なら begin() とか back_inserter() が
返すイテレータを使えるんですね。
やっぱり古くさいインタフェースを持つ関数は捨てて、ちゃんとした
ライブラリを作り直そうかな。
669 :
デフォルトの名無しさん :02/10/07 01:58
コンストラクタにテンプレート使う↓のってOKですか? class X { publuic: template<class T> X(T t){ ... } };
あり
void int_return(const int &rf); とかいう風にconstつけたりします? っていうかconstついているようなものか 書いていてそう思いました
>>672 一時オブジェクトを渡す可能性があるならconst必須
void hoge(const std::string& str);
...
hoge("this generates temporary obj.");
とかいう話ではなくて?
>>673 そうか。
参照は,値を書き換えてもいいんでしたね。
constは,必要か
ポインタで渡すのは,文字列か構造体ですしね
>>672 リファレンス渡しは値渡しよりも効率が良いが、呼び出し先で引数に
代入してしまうと呼び出し元の変数まで変更されてしまうので、
constをつけて、値が変わる危険性を避けつつ効率を維持できる。
関数の引数ならconstポインタでもいいと思うがなぁ。
>>676 呼び出し元で引数に&を付ける必要があるけどな。
NULLを渡せないから参照なんて嫌だー! ってそれがメリットか?
>>677 それを言ったら、newしたオブジェクトを参照渡しするときは
*をつけなきゃいけないじゃん。
680 :
デフォルトの名無しさん :02/10/07 03:35
漏れは値渡しの最適化とみなせる場合と例外のcatchの場合、それに 構文上必要な場合(コピーコンストラクタや演算子定義)はconst 参照にして、ポリモーフィズムを使う場合やオブジェクトの同一性 が問題になる時はポインタ渡しにしている。 このくらいが妥当じゃないかなあ。
>>678 またヌルヌル論争になるから null pointer って書いてくれ
>>676-679 演算子のオーバーロードするときに、いちいち
&つけるのかっこ悪いじゃん。
漏れも680とおんなじ感じかな。 構造体の場合はほとんど全部"値渡しの最適化"とみなせるのでたいていは参照、 std::stringとかみたいな値重視のクラスも参照、 ポリモーフィックなクラスの場合ポインタ使ってるっぽい。
例えば template<typename value_type> value_type TypeAdjast(const (void*)& value) { return boost::lexical_cast<value_type>(value); } int a = 100; string s; s = TypeAdjast(a); みたいにして、関数の返値が格納される先(左辺値)の型に応じて 返す型を変える関数って作れるものなんでしょうか?
そもそもC++は int foo();と string foo();は同時に存在できなかったはずだけど、、
>>685 s = TypeAdjast<string>(a) のように呼べば作れるけど、
そういうことじゃないよね?
>>687 やっぱりそうなりますか・・・
テキストで保存してあるデータを
型に合わせてロードする関数を考えているんですが
std::string LoadDataAsStr();
int LoadDataAsInt();
unsigned int LoadDataAsUInt();
:
:
みたく型毎に関数用意したり、とか
やたら型キャスト使ったり、とかが鬱陶しいので
できるだけスマートに書けるようにしたいのであります
やっぱり左辺値の型情報を渡して
それに合わせてロードするようにするのが一般的ですか
>>688 TypeAdjast(s, a) とすればいいんじゃ?
adjastってのもかなりかっこ悪いが。
>>688 IOStream風でいいじゃん。
class mystream;
template <typename Target>
mystreamr& operator >>(mystream& s, Target& target)
{
// ...
return s;
}
void f(mystream& s)
{
int i;
std::string str;
s >> i >> str;
}
1| 10 2| test string 3| 5.003 というデータに対して string s1 = GetData(1行目); string s2 = GetData(2行目); int a = GetData(1行目); float f = GetData(3行目); としたときに s1 = "10" s2 = "test string" a = 10 f = 5.003f とできるようなGetData()の実装は「無理」って事ですか? もちろん int b = GetData(2行目); は「危険なキャスト」として例外投げてかまわないんですが・・・
692 :
デフォルトの名無しさん :02/10/07 22:34
>>691 危険なキャストっていうか、「不可能なキャスト」と決めつけてしまってもOKなわけですが
GetDataの戻り値をVariantな型にして、 そのVariantな型から各型へのキャストを 書けば、実現できるかも。 つまり、 class Variant { string data; public: operator int(){ ...} operator double(){ ...} }; で、Variant GetData(int line);とか。
なぜNULLを「ぬる」と読むのかさっぱりわからない。 ずっと「なる」だと思っていたし、周りに聞いてもみんなそう言う。 「ぬる」はここへ来て初めて知った・・・ドイツ系の人が広めたのでしょうか?
695 :
デフォルトの名無しさん :02/10/07 22:48
↑ネタですぅ
>>693 ごめんなさいわかりません・・・
最終的な利用方法は
string s = (int)GetData(1行目)
ということですか?
この関数の目的の大部分は、キャストしないで利用できるようにすることなので
もし上記のようなら無理に1つの関数にまとめる必要は無いのです・・・
>>694 NULLの所へback_inserterと読みます。
「ぬるぬるの所へバックから差し込む」
694の想像力 = NULL;
おれはNumberをヌムバーと読んでいる。
>696 せめてこれくらいのテストはしてから、そういうことを言ってほしい。 #include <stdio.h> struct Variant{ operator int() { return 1;} operator double() { return 2.0;} }; int main(){ Variant v; int i = v; double d = v; printf("%d, %f", i, d ); }
一生懸命考えて必死に質問してるのに クソどうでもいいレスに流されるとホント腹が立つ はっ・・・漏れの質問も同じくらいどうでもいいのか・・・
>>702 申し訳ない。ところで君の質問はどれよ。
>>701 おお・・・すみません・・・
ということは、それくらい明らかな実装だと
既に標準ライブラリや準標準ライブラリに
同じ様な汎用型に関する取り扱いがあったりはしないのですか?
「自分のコードが一番信用できない」ってのがポリシーなので
既にあるならそっちを使いたいです
>>706 ちゃんと流されずに詳しい人にレスもらえてるじゃん。
おれはパスだが、、
>>693 つーことは、
class GetData {
const char *s;
public:
GetData(const char *s_) : s(s_) {}
operator int() const {return boost::lexical_cast<int>(s);}
operator float() const {return boost::lexical_cast<float>(s);}
operator double() const {return boost::lexical_cast<double>(s);}
operator const char*() const {return s;}
//operator std::string() const {return boost::lexical_cast<std::string>(s);}
// 以下省略
};
とかやっておけば、
int i (GetData("123"));
double j (GetData("234"));
std::string k (GetData("345"));
てな感じで呼べるわけやね。
ややこしくなってまいりました・・・ じっくり理解して実装してみます ありがとう
なぜそこでテンプレートを思いつかないかなぁ。 template<class T> operator T() const { return boost::lexical_cast< T > ( s ); }
>>711 通らないタコなコンパイラがあるんだからしょうがないだろ。
>712 boostは通るのに、711のテンプレートは通らないと?
>>713 なんといってもVC++だからな。VC6だと全く動かないコードになら
コンパイルできるが、VC7はコンパイルさえ通らん。
>>705 >「自分のコードが一番信用できない」ってのがポリシーなので
>既にあるならそっちを使いたいです
ワラタ
EXEからDLLに関数をエクスポートする場合 双方のライブラリをリンクしなきゃいけないと思うんですが どうやってライブラリを作るんでしょうか?
717 :
デフォルトの名無しさん :02/10/08 00:54
BCB なら、コマンド・ラインから、 implib hoge.dll
718 :
デフォルトの名無しさん :02/10/08 00:54
>>716 C++では名前のマングリングが起こるので、序数で呼び出す方がいいかも
しれない。
どうしても名前で呼び出すには、一度アセンブル出力して、そのラベル名
を書く。
>>716 最初はリンクでエラーになるが、.libは出来ているという罠。
そういう時は素直にGetProcAddressつかおうよ
722 :
デフォルトの名無しさん :02/10/08 01:27
class variant { public: variant(const std::string& in_value) :value(in_value) {} ~variant() {} operator const char*() const { return value.c_str(); } template <typename value_type> operator value_type() const { return boost::lexical_cast<value_type>(value); } private: const std::string value; }; variant GetData(データ格納先) { return variant(データ); } という実装を試してみたんですが int a = GetData(データ格納先); // safe string s = GetData(データ格納先); // abnormal termination const char* lpstr = GetData(データ格納先); // lexical_cast内部でコンパイルエラー となってしまいした・・・ 引数の場合はテンプレートに対して型を明示してやればオーバーロードできたのですが キャストオペレータ(て言うのかな)の場合はうまく特殊化できないようなのです なにか解決策はありますか? 環境はBCC5.5.1+BCC添付のSTL+BOOST1.28
ソースを見れば分かるけど、lexical_castでポインタ型には変換できないよ。 //少しだけ簡略化してます template<typename Target, typename Source> Target lexical_cast(Source arg) { std::stringstream interpreter; Target result; if(!(interpreter << arg) || !(interpreter >> result) || !(interpreter >> std::ws).eof()) throw bad_lexical_cast(); return result; } メモリを確保していないchar*型の変数resultには代入できないからね。 解決策はoperator char*()を定義して中でnew[]すればいいんだけど、 operator char*()を(暗黙的でも)呼び出した場合に必ずdelete[]しなきゃいけないのは大変だから、 std::stringだけ使っておくってのが正解かもね。
724 :
デフォルトの名無しさん :02/10/08 01:55
>>723 それは理解しています(というか身を以て体感しました・・・)
なので、
>>722 の5行目で
operator const char*() const { return value.c_str(); }
として、ポインタを要求された場合はvalueの直データを渡すようにさせたいのですが
const char* lpstr = GetData(データ格納先);
と明示的にconst char*型を要求しても、テンプレートが適用されてエラーになってしまう
という問題です
さらに具合が悪いことに、
operator std::string() const { return value; }
としても、やはりテンプレートが適用されてしまいます
どうしたらいいんでしょうか・・・
ちなみに今boost::anyで実装できないか試していて更に混乱中・・・
>>724 template<> char const* operator char const*() const{ return value.c_str(); }
とかでできない?想像だけれども
>>726 エラー E2036: 変換演算子には戻り型を指定できない
コンパイラがおっしゃる意味を理解できないのがツライ・・・
>>727 わぉ
すまんすまん
template<> operator char const*() const{ return value.c_str(); }
>>721 たとえばEXE の中で
void Func(int,int);
と宣言されてたら、
void (*PFunc)(int,int);
と宣言して
PFunc = (void (*)(int,int))GetProcAddress( naninani , "Func");
とする。
こんなんですか?
いいえちがいます
>>728 ダメです・・・template<typename value_type>が適用されまする・・・
そういうテンプレートの使い方をしてはいけないコンパイラだったと 諦めて、 operator long() ... operator char()... operator double()...と 列挙するとか。コンパイラ代えてみるとか。
>>729 どうするかは場合によりけりだと。
俺はDLLをプラグインとして使うことが多いから、
DLL内の関数はEXE側がGetProcAddressを使って自力で取得、
その関数を経由してEXE側の関数をEXEに渡す、てのをよく使う。
個々の関数をいちいちGetProcAddressすんのは面倒だから、
エクスポートすんのは、DLLの全機能を提供するクラスのインスタンスを返す関数ひとつだけにして、
あとはそのインスタンス経由でいろいろするのが楽。
>>732 了解しました・・・
型列挙で対応します
(BCCタダで使わせてもらってるから文句は言えない・・・)
736 :
デフォルトの名無しさん :02/10/08 02:38
VCなんで試せませないのと、boostわからんのでLokiですが、 template<typename T> operator T() { return Loki::TypeTraits<T>::isPointer ? spec_ptr<T>() : boost::lexical_cast<T>(value); } template<typename T> T spec_ptr() { return 云々; } のようにエラー起きるのだけ特化させるのはどうですか?
× VCなんで試せませないのと ○ VCなんで試せないのと boostだと、 template<typename T> operator T() { return boost::is_pointer<T>::value ? spec_ptr<T>() : boost::lexical_cast<T>(value); } ですかね。
あら・・・タイプトレイツって実行時に判断できるんですか・・・ コンパイル時チェックだと思いこんでた
>>738 コンパイル時チェックですが、関数もテンプレートなので・・・
なので、コンパイル後条件式は消えます
740 :
デフォルトの名無しさん :02/10/08 03:23
おまいら、C++でなにつくってるんだ?
>>739 三項演算はマクロじゃないので実行時に判断されませんか?
三項演算は定数扱う限りはOKだと思うけど。
>740 自己を満足させる心
744 :
デフォルトの名無しさん :02/10/08 12:47
デストラクタで delete 処理するのはいいのですが、割り込み等などで 終了させられた場合、メモリはちゃんと解放されるのでしょうか
>>744 SIGKILLのことですか?
だとしたらOSがメモリを強制的に開放するんじゃなくて?
>>745 すみません、環境を書いていませんでしたね。おっしゃるとおり UNIX 系での
シグナルを想定していました。
やはり OS が解放してくれるのでしょうか。そうでないと安心できない気がしますが。
C で書いていた頃はそうでもなかったのですが、C++ で書くようになって気になり
始めました。自動的にデストラクタを呼んでいるわけでもなさそうですし。
あるクラスのインスタンスを一つ生成し、それがイベントループを廻し続けるような
プログラムを書いているのですが、この場合デストラクタが呼ばれることがあるので
しょうか。
メモリリークなんてなぁプロセスが終了しちまえば一発で解決なんだぁよ 制限がキツイとか常駐ソフトとかでもないかぎりあんま気にすんなぁ
むしろ個別にFreeすると終了処理が長引くので、 Freeしないで終わるようにする定石もあるらしい。 Windowsだとちょっと心配だけど、UNIXなら問題 ないのではないでしょうか?
ま た m a l l o c & f r e e で す か。 deleteは忘れるなよ。
750 :
デフォルトの名無しさん :02/10/08 14:59
borland c++ から c++builderへ.rcファイルごと移行したいのですが、どうすれば良い ですか?
学生時代以来のC/C++プログラミングなので、ちょっと混乱していました(w たしかにプログラムが終了すれば、OS が面倒みてくれますね。常駐型の プログラムを書いているので、別の問題とごっちゃになっておりました。 > あるクラスのインスタンスを一つ生成し、それがイベントループを廻し続けるような > プログラムを書いているのですが、この場合デストラクタが呼ばれることがあるので > しょうか。 結局のところ、興味があるのはこの点でして、このタイプのプログラムの場合、その クラスのデストラクタを書いても意味はないかどうかということです。
752 :
デフォルトの名無しさん :02/10/08 15:56
顔が汚くてもいいから、胸の大きい女性を望むあなた・・・。
>>751 プログラムの終了処理はOSが面倒見てくれることばっかじゃなしなぁ。
>>747 まあそういうVB厨プログラマが大勢いるから
NT系サーバの連続運用は難しいとかよく落ちるとか
1日一回リセットとかの話になるわけだな。
>>747 100%pure VB房と認定されますた。
VB房ロゴの使用を許可します。
757 :
デフォルトの名無しさん :02/10/08 19:31
ClassX a; ClassX b; ClassX c; a = b; a = c ←の時点で、aのデストラクタって呼ばれるのでしょうか? ClassXの内部で動的にメモリを確保しているような場合、上のような 状況で開放する術はありますか?
>>757 デストラクタじゃなくてoperator=が呼ばれる。
>>758 おお!即レスありがとうございます。
ちょっと悩んでいたんで、かなりうれしいです。
しかしEffective C++ にのってる a = a のチェックって誰かしてる奴いるんか?
自己代入のチエックってやっぱりthisとrhsのアドレス比較するんかなあ。
>>760 メンバがスマートポインタなら a = a でもデータ消失はないから大丈夫。
さらに operator = やコピーコンストラクタも定義する必要なし。夢のハッピーライフ。
でも、スマートポインタ使いまくりって奴もあまりいないが。
>>760 Exceptional C++ の項目38に従って必要ならする…
と言いたいところだが、自己代入がボトルネックになる
場面なんて出会ったことないので結局やってないなぁ。
>>762 それじゃあ、デフォルトのoperator=とかコピーコンストラクタが
コピーじゃなくて実装の共有になってしまわんか?それで幸せなら
特に止めるつもりはないが。
764 :
デフォルトの名無しさん :02/10/08 20:29
>>747 ねぇ、それはネタなの? 本気なの? 正しいの? 間違ってるの?
>>764 UNIXで仕事してたときに終了時に free をずらずらと書いて開放処理をしていたら
先輩にCPUに無駄な仕事してんじゃないと怒られました。
766 :
デフォルトの名無しさん :02/10/08 21:15
>>760 a = a のチェックは必要なら普通するけど・・・ってのはウソで、
a = a でも問題ないようなコードで済ますことの方が多いか。
a = a でも問題ないようなコードって、たとえばポインタなら自己チェックと スマートポインタ以外の方法あるの?
freeは未使用マークをつける プログラム終了時には確保したメモリ領域はOSに返却される どちらも「解放」という言葉を使ってるのが誤解を生む元になっているのではないだろうか。 #freeがOSに返却しないのは「多くの処理系では」という条件付らしいが,詳しくは知らん
やってることは一緒だけど、ディープコピー・開放・ポインタ代入、とか。
771 :
デフォルトの名無しさん :02/10/08 23:38
クラス内のフィールドに外部から値を取得することはできるが、 設定することはできず、クラス内部の関数からは設定することが できることってできますか? ClassA { private: int m; public: ClassA(int m); } だと、mを取得することができない。Getなどのアクセサをつかわずに、 mをpulicにしても、なおかつ、設定はできないみたいなのはできますか?
C++の仕様ではできない。素直にgetアクセサをつけるべし。 つかpublicなメンバ変数は、レコードのような扱いでないかぎり あんまりお勧めできない・・・ <Del厨モード> ちなみにC#ではgetのみのプロパティにて実現可能。 Javaにはないよね(藁 </Del厨モード>
template<class T> struct id{ typedef T type; }; // dummy template<typename Type, class Owner> class read_only_field { public: operator const Type& () const { return t; } private: friend typename id<Owner>::type; read_only_field& operator=(const Type& ot) {t=ot; return *this;} Type t; }; class A { public: read_only_field<int, A> m; ... }; …99.5%くらいネタだけどな。
void f(std::vector<int> (&vr)); void f(std::vector<int> &vr); void f(std::vector<int> (&)); void f(std::vector<int> &); 全て同じ宣言ですか?
>>774 同じだろう。プロトタイプ宣言の仮引数は型しかチェックされないから。
>>775 レスサンクス。
やっぱりか(;´Д`)
ウワァーイ777!!
ウワーイ778!!
780 :
デフォルトの名無しさん :02/10/09 15:19
宿題スレに書いたんですが、レスが無いのでこちらにも書かせてください。 コールバックって、メンバー関数をじかに呼べないんですが、 class Aとclass Bがあって Bは、コールバックされる関数(SetTimerとか)を使っていて、 さらにそのコールバックされる関数の中でBのメンバー関数を呼び出したい。 BにAのインスタンスのポインターを持たせればできますが、 1. Bの実装でAに依存しない(class Aのクラス定義を読み込まない) 2. Aをコールバックされる関数を含んだ中傷クラスのサブクラスとしない という条件で、うまい方法ってないですか? 現状はtemplateを使って(public,private等は省略) class base { virtual void operaot()() = 0; }; template<class T> class callback : public base { typedef void (T::*F)(); callback(T* obj, F func) : o(obj), f(func) {} void operator()() { return o->*f(); T* o; F f; }; とやって、AはBにcallbackのインスタンスを渡すようにしてますが、今市…
781 :
デフォルトの名無しさん :02/10/09 15:43
>>780 普通に多重継承で interface (風のもの) 使えば?
782 :
デフォルトの名無しさん :02/10/09 16:51
そりは、条件2にひっかっかって… 実は、class AはCOMのクラスなので、何か仮想関数持ったクラスを継承する のは問題が起きるのではないかと思うのですが。 そんな事は無いのでしょうか?
784 :
デフォルトの名無しさん :02/10/09 17:45
デリケートですか?デリケートですか?
艦載陣さんですか?
デリケートゾーンのかゆみに…
はっきり ま ん こ と書けやゴルア!
股間の痒みにメディナース
変態ばっかだな
まかいあんこやまらさきむんこは嫌いです
791 :
デフォルトの名無しさん :02/10/09 21:45
クラス内ローカルクラス宣言てできますか? class A { class B { operator int() { return 1; } } B getB() { return B(); } }MyA; int a = MyA.getB(); みたいな もちろんint b = B();はコンパイルエラーで
クラスB定義のあとに「;」忘れました・・・
793 :
デフォルトの名無しさん :02/10/09 21:47
Java厨か? できるよ。
関数内にもできる。 実はつかったことないけど・・・汗
関数内に関数はできないんだよなー。 なんでだろう。
High-Cはできたなあ...
関数オブジェクトならできるだろう。
関数内クラス内に関数を作れば良いのだ!
>>797 だがテンプレート引数として渡せないという罠。(なんとなく理由は想像がつく)
>>780 AからBの関数を呼んで、BはAの(コールバックされる)関数を呼んで、
さらにそこからBの関数を呼ぶ、ということ?
で、AはBの定義やインスタンスを知っていて、しかもCOMのクラスなのね?
だとすると、多分Aはプラグインか何かだと思うけど、継承を避けるなら
780に類する方法しか無いと思う。ただ、Aを含むオブジェクトの中には
callback<A>もいて、それは仮想関数を持ったクラスを継承している。
WinもCOMも知らないから、何とも言えないけど、780で動いているなら、
継承は出来るんじゃあないかなあ。
構造上理由があって、継承を避けたいということならいいんだけど。
Java厨というか、無知なだけです・・・ クラス内クラス宣言が利用に先立ってされなければならない(らしい)という所にひっかかってました class A { B getB(); class B; }; // コンパイルエラー「Bの重複定義」 というやつ・・・ class A { int hoo() { return bar(); } int bar() { return 1; } } はOKなのに・・・
>>782 A が COM オブジェクトなら、ITimerHandler とかのカスタム
インターフェイス(を定義して)持たせておけばよいのでは?
多重継承とCOMについては、一度 ATL のサンプルソース読んでみて。
インタフェイス継承も実装の継承も多用しているから、大分参考に
なるはず。
>>801 class A
{
int hoo(){ B b; }
class B{};
};
これはOK
違いわかる?
804 :
デフォルトの名無しさん :02/10/10 18:04
Visual C++ 6.0 で以下のようなコードを試しています。 ofstream out; out.open("nowhere\\test.dat"); ところが、open に失敗します。 つまり、ファイルをオープンするとき、書き込み用の場合などは、 ファイルが存在しなくても、自動的に作成してくれるようですが、 ディレクトリも同時に作ってくれたりはしないみたいです。 ディレクトリを作成しつつファイルも作る方法はありますか? あるいは、単独でディレクトリを作成する標準関数はあるのでしょうか? (Windows 用の _mkdir などを使うしかないのでしょうか?)
>>804 ファイルとディレクトリはWindowsでは全く別々のものなので、
ディレクトリを作ってからopenして下さい。
806 :
デフォルトの名無しさん :02/10/10 19:36
STLのコンテナに自作したクラスhogeへのポインタを追加していって、それをソートするのに namespace std { struct less<Particle*>: public binary_function<hoge const *, hoge const*, bool> { bool operator()(hoge* const a, hoge* const b) { return a->val < b->val; } }; }; std::list<hoge*> hogelist; ・・・//hogelistにnewしたhoge*を追加 hogelist.sort(std::less<hoge*>()); のようにしています。 ・stdに手を入れていること ・hoge*に特化したstd::less<hoge*>を使っていること の2点でよくないような気がするのですが、他の方法はありますか?
>>805 うーむ、そうですか。
ディレクトリを作りつつ……というプログラムを C++ でやろうとしたら、
OS に依存したコードを書かなければならない、ということですね。
どうもありがとうございました。
>>808 > ディレクトリを作りつつ...
> OS に依存したコードを書かなければならない、
当たり前だと思うけど...、全ての OS に階層ディレクトリがあると思っているのか ?
>>804 の言うOSとはWindowsとLinuxの2種類だと思う。
>>810 >
>>804 の言うOSとはWindowsとLinuxの2種類だと思う。
>>804 だったら、Windows だけだろ ?
> Visual C++ 6.0 で...
>>806 std以外の名前空間で定義すればよい。
namespace hehehe
{
template <typename T>
struct less<T*>: public binary_function<const T*, const T* , bool>
{
bool operator() (const T* a, const T* b) const
{
return a->val < b->val;
}
};
};
若干修正 namespace hehehe { template <typename T> struct less<T> : public binary_function<const T*, const T* , bool> { bool operator() (const T* a, const T* b) const { return a->val < b->val; } }; };
815 :
デフォルトの名無しさん :02/10/10 22:39
別にlessに手を入れる必要無いじゃん。 直接テンプレート引数にファンクタ渡せば?
>>809 > 全ての OS に階層ディレクトリがあると思っているのか ?
すみません、かなり勉強不足でした。
少なくとも C++ が走るようなものではそうだと思っていました。
ちなみに、どんな OS だと階層ディレクトリがないのですか?
(検索しても Windows/Unix/MacOS 以外については余り情報が得られないので。)
なお、
> ディレクトリを作成しつつファイルも作る方法はありますか?
に関連して、無効なパスを渡された場合、
1・階層ディレクトリのある環境ではディレクトリの作成を試みる
2・そうでないときは、やはりエラーを返す
というような機能を考えてみたのですが、
やはり無理、またはやらない方がよい、ということですか?
817 :
デフォルトの名無しさん :02/10/10 23:12
>816 プリンタや自販機のROMの中にもOS入ってたりする。
>809 全てのOSにファイルはあるの?
>819 list::sortには、Predを引数とする版があるだろ。
>>821 ああなるほど、std::lessではなくて、適当な名前の比較関数オブジェクトを
渡してやればいいのですね。
824 :
デフォルトの名無しさん :02/10/11 06:54
ファンクタライクな物をVC.NETで作ってるんですが、 部分特殊化できないと LokiのTypeListみたいなのはつくれないんでしょうか? //_Tはクラス. _R は戻り値の型. _Lは引数の型 template <typename _T,typename _R,typename _L>class FunctorX {protected: _R(_T::*mem_f1)(_L); _R (*g_f1)(_L); _T* obj_ptr_f1; _T* func_obj_ptr_n1; enum Mode{other,mem_ptr,ptr,func_obj}m_mode; void Ini(){ g_f1= NULL;mem_f1 = NULL; obj_ptr_f1 = NULL;func_obj_ptr_n1 = NULL; m_mode = Mode::other; } public: FunctorX(_T& ob,_R (_T::*f1)(_L)){ Ini();mem_f1= f1; obj_ptr_f1 = ptr;m_mode = Mode::mem_ptr; } explicit FunctorX(_R (*f1)(_L)){ Ini();g_f1 = f1; m_mode = Mode::ptr; } explicit FunctorX(_T& ob){ Ini();func_obj_ptr_n1 = &ob; m_mode = Mode::func_obj; } FunctorX(){ Ini()} ~FunctorX(){}
825 :
正男 ◆GVV43x.nK. :02/10/11 06:56
途中まで読んで頭が痛くなってまいりますた
_R call(_T& ob,_L a){ if( obj_ptr_f1 != NULL && mem_f1 != NULL && m_mode == Mode::mem_ptr){ return (ob.*mem_f1)(a);} throw "Functor error"; } _R call(_L a){ switch(m_mode){ case Mode::mem_ptr : if( obj_ptr_f1 != NULL && mem_f1 != NULL ) return (*obj_ptr_f1.*mem_f1)(a); break; case Mode::ptr : if( g_f1 != NULL ) return (*g_f1)(a); break; case Mode::func_obj : if( func_obj_ptr_n1 !=NULL ) return (*func_obj_ptr_n1)(a); break; default: break; } throw "Functor error"; } _R operator()(_L a){return call(a);} };
struct Test { template<typename R,typename L> R f(L a){ return a*2;} Test(){} ~Test(){} }; int main() { Test c5,c5a; Functor<Test,int,int> t5(c5,&Test::f<int,int>); cout << t5.call(c5,100); cout << t5.call(100); cout << t5.call(c5a,100);//c5 の関数ポインタ経由で c5aを呼び出す??? cout << t5(100); FunctorX< Functor<Test,int,int> ,int,int> t6(t5); t6(100); }
>>824 その規模のコードはcppにしてどこかにアップしろ
コメントされてない(しかもインデントすらされていない)コードなんて
ただのゴミ
>>828 template苦手だからってキレんなよw
Lokiスレのほうに書きゃいいのに、とはオモウ。
TC++PL3rdや
>>3 のFinal Draftにある文法に
member-declaration
:decl-specifier-seqopt member-declarator-listopt ;
|function-definition ;opt
|::opt nested-name-specifier templateopt unqualified-id ;
|using-declaration
|template-declaration
;
という部分がありますが上から三番目は何に使われてますか?
833 :
デフォルトの名無しさん :02/10/11 20:05
ClassA{ private: int *a; public: ClassA(){a = NULL} ClassA(int i){ a = new int [i] } } みたいなクラスがあって、 ClassA ain = new ClassA[100]; で呼ばれるコンストラクタは引数なしのコンストラクタしか無理ですか?
ClassA* ain = new ClassA[100](10);
835 :
デフォルトの名無しさん :02/10/11 22:11
無理でせう。
>>874 は逝けそうだけど逝けなさそうな微妙なことを書かねばならなくなりました。
なんだこの低能なシーケンスは!
ともっちに手取り足取りC++教えたい
840 :
デフォルトの名無しさん :02/10/12 01:18
次のプログラムをコンパイルするとエラーが出てしまいます。 Aがシンタックスエラーを起こしていますとか。 どういうことなんでしょう? 本に書いてある通りにやっているのに・・・。 何がいけないのでしょう? #include <stdio.h> #include <stdlib.h> class A { public: int id; }; int main() { int i; A c; c.id = 100; for( i = 0; i < 7; i++) printf( "id = %d", c.id); return 0; }
初心者が質問するなら、エラーをそのまま貼らないと。それから > #include <stdio.h> > #include <stdlib.h> こんな低脳なコードを乗せている入門本は古すぎるか腐っているので 捨てた方が吉かと。
842 :
デフォルトの名無しさん :02/10/12 01:22
コンパイラはなに? bcc32では動いたよ。 拡張子は.cppとかにした?
.cから.cppになおしたらできました。 ありがとうございました。 一体2つはどう違うのでしょう?
ところで、stdlibをインクルードしてる理由は何なのさ?
ループを7回まわしている理由モナー
クラス内関数のテンプレート化で質問です class A { template<class T> T foo() { なんたらかんたら } }myA; int a = myA.foo<int>(); でコンパイル通ってしまうんですが、 これはどう解釈されてるんでしょうか? 「返値の型だけ異なる」オーバーロードってNGでしたよね?
848 :
デフォルトの名無しさん :02/10/12 02:07
age忘れ...
突然ですが純粋仮想関数のデストラクタは必ず実装しなければならない、 とは知りませんでした。首吊ってきます。
最近なかなか寝付けません。どうしたら良いのでしょうか?
くだらなすぎ
>>847 テンプレートはオーバーロードではないからだろ
854 :
デフォルトの名無しさん :02/10/12 10:11
C++で、2次元(以上の)配列に対して、 辞書式順序でsortできるようにするためには、 bool operatorとsortを使えばよいらしいというのは、 分かったのですが、具体的なコーディングが分かりません。 教えてください。
>>854 何がしたいのか読み取れん。いったい何がわかっているというのだ。
ソートっつー概念はそもそも直線的なものにしか成り立たないんじゃないか? 2次元以上の要素をいったいどう並び替えろと?
もしかして組み込みの配列?
辞書式順序です。 例えば、(1,2),(5,6),(5,4),(2,4)というデータがあったら、 第一番目のデータを見て、(1,2),(2,4),(5,6),(5,4) と並び替え、 一番目のデータが同じ時は、 (1,2),(2,4),(5,4),(5,6) のように並び替えたいのです。 数学的に書くと (i,j)<(k,l)←→i<k i=kのときは、j<l としたいということです。
>>858 文字列のソートがどうやっているかわかってるなら、それと同じようにすれば
いい。
>>858 > 辞書式順序です。
頼むから、用語はちゃんと覚えてくれ。あやふやだったらはじめから使うな。
> 一番目のデータが同じ時は、
> (1,2),(2,4),(5,4),(5,6)
> のように並び替えたいのです。
というのは、単に複数キーでソートすると言う。
(ちなみに、辞書式というのは概ね文字コード順にソートすることを指す。)
> 数学的に書くと
> (i,j)<(k,l)←→i<k
> i=kのときは、j<l
と言うのがわかっているなら、qsort() の比較関数をそのように書けば良いだけだよ。
でも、そう言うデータなら二次元配列より構造体の一次元配列の方がわかりやすいと思う。
>>860 >
>>858 > > 辞書式順序です。
>
> 頼むから、用語はちゃんと覚えてくれ。あやふやだったらはじめから使うな。
固定長の文字列とみなせば辞書式と言っても間違いではない。
> (ちなみに、辞書式というのは概ね文字コード順にソートすることを指す。)
別に文字コードじゃなくたっていいんだよ、順序さえあれば。
862 :
デフォルトの名無しさん :02/10/12 14:32
テンプレート型のクラスのコンストラクタを 宣言と実体を別ファイルで書くことは出来なんでしょうか? ファイル:a.h template<class T> struct A { A(); }; ファイル:a.cpp template<class T> A<T>::A() { } このクラスを別のファイル(main.cpp)で使おうとすると、 外部シンボルが未解決ですと言われます。 何か書き方が間違っているのでしょうか? 一応a.hに実体もまとめて書けばエラーにはならないのですが・・・
過去ログを参照願います。
>>861 > 固定長の文字列とみなせば辞書式と言っても間違いではない。
ハイハイ、人の指摘に手一杯で、
>>858 の
> 数学的に書くと
> (i,j)<(k,l)←→i<k
> i=kのときは、j<l
は見てないのね。
> 別に文字コードじゃなくたっていいんだよ、順序さえあれば。
ハイハイ、「概ね」と言う言葉も理解できなかったのね。
ったく、話の流れぐらい読めよ。
>>864 何が言いたいのかわからんが「辞書式比較」の定義って、二要素なら
> 数学的に書くと
> (i,j)<(k,l)←→i<k
> i=kのときは、j<l
普通まさしくこれのことだぞ。先頭要素を先に比較して、同じなら残りの要素で比較。
std::lexicographical_compare でも見れ。
( ´_ゝ`)マターリ シヨウヨ
867 :
デフォルトの名無しさん :02/10/12 16:36
>>849 VCやgccでは無理なんですか・・・
>>853 >>847 のコードはfooが呼ばれる度に
class A
{
int foo() {}
char foo() {}
:
:
};
みたいに展開されると思ってたんですが
違うのですか・・・?
>>859 文字列のソートがどうやっているかわかってるなら、それと同じようにすれば
いい。
それはそうですが、それをsortとbool operatorでできますか、ということです。
一から自分でプログラムしてもいいですが、面倒なので。
あまり自信もないし。
>>860 >頼むから、用語はちゃんと覚えてくれ。あやふやだったらはじめから使うな。
別にあやふやでないです。
辞書式順序というのは、正式な言葉のはず。
ただプログラミングの世界ではないのかも。
> 一番目のデータが同じ時は、
> (1,2),(2,4),(5,4),(5,6)
> のように並び替えたいのです。
>というのは、単に複数キーでソートすると言う。
では複数キーでソートするやり方を教えてください。
できればsortのような組み込みのアルゴリズムを使ってもらえると助かります。
>>867 class A
{
template< class T > T foo(){}
};
は
class A
{
template<> int foo<int>(){}
template<> char foo<char>(){}
};
って展開されると思う。
>>868 できるでしょ
bool operrator < で lexicographical_compare つかって sort に突っ込めば?
自分でコーディングする部分なんてほとんど無いよ
探し方があまいのか結局分かりませんでした。 誰かヒントだけでも…
>>871 テンプレートはそういうものだと思ってあきらめましょう。。。
>>871 exportキーワードをまともにサポートしている処理系でないと、
テンプレートの宣言と実体を分けて書くことはできない。
template<class T> < ん? T はintかよしよし分かった。。。ん?A()はどこ行った? struct A { A(); }; 一方その頃 cpp では。。。 ファイル:a.cpp template<class T> < おーい、俺はどうしたら良いんだよ〜、なんか不安になってきたよ。。 A<T>::A() { }
>>868 コンテナの比較は辞書式だから固定長ならboost::arrayでも使えば?
>>872-874 どうもありがとうございます。
いままでコンストラクタのところでしかエラーが出てなかったんで、
コンストラクタさえどうにかなれば可能だろうと考えていましたが、
今テストしてみた結果、実体作るとやっぱりメンバー関数も無理だと
言うことが分かりました。
確かにa.cppの型を解決する方法が無いですもんね…。
(いままでコンパイラが勝手に解釈してくれてるのとばかり…)
素直にあきらめることにします。
exportをサポートしてる処理系ってComeau以外にある? そういえば…Comeauのネット上の試用コンパイラ(?)は template <template <class> class Container> class HogeにSTLのコンテナを渡せなかったなぁ。 (→試してないけど、template <template <class, class> class Container>になら渡せそうだった。) これって普通?VC,BCC,gcc,+STLPortだと文句言わずにコンパイルしてくれるんだけど。
>>862 もし、テンプレート引数 T に渡す型とかがいくつかに限定されているなら、
それらを a.cpp で明示的にインスタンス化するという手は使えるけど。
template A<int>;
template A<char*>;
とか。
880 :
デフォルトの名無しさん :02/10/13 02:46
STLのイタレータの継承の一般的な仕方がわかりません. コンテナのbegin,endの代入も苦しいし, algorithmライブラリを使えるようにするのも苦しい. _Rb_tree_iterator<...>とか書かないとうまい事いかない もんなんでしょーか? _Rb_...とか書くと移植性0になりそうなので, 幸せになれる方法を教えてください.
>>880 C++標準ライブラリP285〜、§7.5.2「ユーザー定義の反復子」に詳しいです。
class MyIterator
: public std::iterator<std::bidirectional_iterator_tag, type> {
...
};
>>879 その方法
>>877 書いた直後に思いついたんですけど、
明示的に宣言出来るところがないんですよ。
テンプレート使ってるコードは全部ヘッダに詰め込むのが基本なんですかね??
>>881 その本持ってますが,そこではコンストラクタで
コンテナを受け取るという事をやっていて,
コンテナのbeginメンバ関数からの代入は扱ってません.
>>883 boost::iterator_adapter
>>882 template A<int>; って書き方は、どこででもできると思うけど。
別にオブジェクトとか関数とかを定義しているわけでもないし。
886 :
デフォルトの名無しさん :02/10/13 16:32
CかC++かどっちか判断できなかったので こちらで質問させていただきます。 VBから呼び出し可能なDLLを作成しています。 調べていく上でエクスポートの方法は __declspecでのエクスポートではなく Defファイルへの記述でのエクスポートが必要ということが分かりました。 それで質問というのはDefファイルっていうのは Func @1 というような記述をしますよね? そこでClass CTestのメンバ関数GetFileNameを記述するには どう記述したらいいでしょうか? 適当に書いてみても駄目でした。 文法的にどういう風に「クラスののメンバ関数」のGetFileName ということを書いたらいいのかわかりません。 教えていただけませんか? よろしくお願いします。
>>886 VC++スレってなかったかな・・・
VBからC++のクラスを直には呼べないよ。ActiveX(COM)にするしかない。
呼べるのはCの関数形式のもの。これのやりかたはFAQなので省略。
>887 え、defファイル自体VCの話しだったんですね、 スレ違いですね、失礼しました。 Comにしなきゃだめなんですね、 わかりました、ありがとうございます。 ではVBの話しは別にして、 defファイルでクラスごと、または クラスのメンバ関数のエクスポートの記述方法だけでも 教えてもらえませんでしょうか? もう半年くらいわからなくて半分以上放置になってる 悩み事なんです。 これで消えますのでよろしくお願いします。
>>888 普通はDEFファイルを書く必要はないが、
どうしてもDEFでやりたいなら・・・。
DEFファイルではクラスごとエクスポートすることはできない。
メンバごとにエクスポートする必要がある。
例えば、こういうクラスAがあったとすると、
class A {
public:
A();
int a(int, char*);
};
DEFファイルにはこのように書く。
EXPORTS
??0A@@QAE@XZ @1 NONAME
?a@A@@QAEHHPAD@Z @2 NONAME
装飾名はMAPファイルで確認すること。@ordinalとNONAMEは
なくても構わない。
890 :
デフォルトの名無しさん :02/10/13 19:16
Chain of responsibilityパターンみたいな、階層構造を表現するために 親へのイテレータをsecondに持ったマップのようなモノを使いたいのですが 既存のライブラリにそういうモノって無いでしょうか? 要求としては、 ・"文字列"と"親を指すイテレータ"を格納できる ・マップ中のある要素に"格納してある文字列"でアクセスできる ・そしてその要素から親まで順番にたどりつつ ・さらに現在の要素に格納されている文字列を参照できる イメージとしては map<string, iterator> chainmap; のような感じで、例えば A ─ B ┬ C ─ E └ D ┬ F └ G という階層構造にしたとして、 chainmap["D"].PrintUpToParent(); とかすると for (it = *chainmap["D"]; it != chainmap.end(); it = it->second) cout << it->first << endl; みたいな処理をしたいのです
あう・・・
>>890 の出力結果を
D
B
A
にしたいという事です・・・
892 :
デフォルトの名無しさん :02/10/14 16:18
自作のクラスをfor文使って配列に入れたいのですが、方法が分かりません。 要するに自作クラスのポインタをスタックに入れる処理がしたいのです。 よろしくお願いします。
class Jisaku { /*definition*/ }; Jisaku* jien[N]; for(int i=0; i<N; i++) { jien[i] = new Jisaku(); }
>>892 std::vector< boost::shared_ptr<Jisaku> > jien;
jien.assign( N, new Jisaku );
>>893 最後の()は不要
スタックに、か。忘れてくれ。
ハイパーカード?
>>894 それってjienいっぱいに同じインスタンスが敷き詰められるんじゃ・・・
899 :
衝撃の事実(漏れにとっては・・・) :02/10/15 16:01
class FileWrapper { ofstream* FileHandle; public: FileWrapper(const char* fname) { FileHandle = new ofstream(fname, ios::out | ios::trunc); } ~FileWrapper() { delete FileHandle; } FileWrapper& operator <<(ostream& (*pf)(ostream&)) { *FileHandle << pf; } template<class T> FileWrapper& operator <<(T arg) { *FileHandle << arg; } }; int main() { // 処理A ///////////////////////////////////////////////////////// FileWrapper* FileStream = new FileWrapper("testA.txt"); boost::timer t; for (int i = 1; i <= 10000; ++i) { *FileStream << i << ","; } *FileStream << "\nElapsed time " << t1.elapsed() << " sec." << endl; delete FileStream; // 処理B ///////////////////////////////////////////////////////// ofstream* FileHandle = new ofstream("testB.log", ios::out | ios::trunc); timer t2; for (int i = 1; i <= 10000; ++i) { *FileHandle << "no " << i << "," << flush; } *FileHandle << "\nelapsed time " << t2.elapsed() << " sec." << endl; delete FileHandle; }
900 :
衝撃の事実(漏れにとっては・・・) :02/10/15 16:01
環境 Win98SE PenIV1.8GHz DDR512MB コンパイル BCC5.5.1 で、なぜか処理Aにかかった時間が平均約0.05秒に対し 処理Bにかかった時間が平均約0.5秒・・・その差なんと10倍 直打ちよりテンプレート化したほうが速いって一体どういう事ですか? 処理順で(boost::timerあたりに)何か違いがあるかもと思って 上下入れ替えてみても、結果はかわりませんでした
901 :
衝撃の事実(漏れにとっては・・・) :02/10/15 16:04
処理Bのコード間違えた・・・ boost::timer t2; for (int i = 1; i <= 10000; ++i) { *FileHandle << i << ","; } *FileHandle << "\nelapsed time " << t2.elapsed() << " sec." << endl; です
> FileWrapper& operator <<(ostream& (*pf)(ostream&)) { *FileHandle << pf; } BCCは、こういうコードを通すのか、、、、return *this;を追加。 bcc: Elapsed time 0.231 sec. elapsed time 0.22 sec. vc6: Elapsed time 0.1 sec. elapsed time 0.1 sec.
何でコンパイルするとそのコードが動くの?
ああ、bccですか、失礼
flushこれの違いだけだね
そりゃflushしまくれば遅くなるだろうなあ・・・
心底つまらない事実だったな。
908 :
デフォルトの名無しさん :02/10/16 05:58
class A { operator bool() { return false; } }; int main() { if (A()) return -1; /* Do something */ return 0; } とあった場合、mainで呼び出されたAは return 0;以降でデストラクトされると保証されますか?
if文が終わった時点でデストラクトされるっしょ
多倍長整数のよかライブラリ(ソースアリ)ってないっすかね。フリーで‥
911 :
デフォルトの名無しさん :02/10/16 08:52
>>909 実は、多重起動を抑止するために
以下のような仕組みを考えてみたのですが、
なんとこれがうまく動いてしまっているんです。
環境依存の恐るべきコードですか?
class ImNotOriginal
{
public:
ImNotOriginal()
{
hMutex = CreateMutex(NULL, TRUE, "このアプリケーションの名前");
}
~ImNotOriginal()
{
ReleaseMutex(hMutex);
}
operator bool()
{
return (WaitForSingleObject(hMutex, 0) == WAIT_TIMEOUT);
}
private:
HANDLE hMutex;
};
int main()
{
if ( ImNotOriginal() ) return -1;
/* 何やらかんやら */
}
>>911 そのロジックでは、本当は重複起動を防止できない。
実際に重複起動を防止できてしまうのは、デストラクタが呼ばれないのではなく、
最初に起動したプロセスが CreateMutex() と WaitForSingleObject() で
ミューテックス所有権を 2 つ獲得してしまっている為に、ReleaseMutex() を
2 回呼ばないとミューテックスを解放できないからだ。
WaitForSingleObject() はミューテックスが誰かに所有されているかを確認する
だけでなく、誰も所有していなかったら所有権を獲得してくる。
誰かが所有している場合、その所有しているスレッドが WaitForSingleObject() を
呼んだスレッド自身であった場合は、ロックされずに所有権をもう 1 つ獲得してくる。
ロックされないのは単独スレッドによるデッドロックを防ぐため、所有権をもう 1 つ
獲得してくるのは排他処理の帳尻を合わせるため (処理 A、B で排他が必要な時、
B が終わっていないのに A で排他が終了しただけで B が突入可能になるのはまずい
だろう?)。
ミューテックス所有権の獲得と放棄は必ず 1 対 1 で対応させること、その際
WaitFor*Object() 系 API の取り扱いには十分注意すること。
ミューテックスで重複起動を防止する場合は通常、WaitForSingleObject() を呼ぶ
のではなく、CreateMutex() 直後で GetLastError() の戻り値が ERROR_ALREADY_EXISTS
であるかどうかを調べる。
913 :
デフォルトの名無しさん :02/10/16 17:15
>>912 詳しい説明ありがとうございました
では質問を変えて、operator bool()の実装を
return (GetLastError() == ERROR_ALREADY_EXISTS)
にした場合、コンストラクタ→operator bool()と呼ばれる保証はありますでしょうか?
つまりプロセス終了時にミューテックスが自動的に解法されることを利用して class ImNotOriginal { public: ImNotOriginal() { HANDLE hMutex = CreateMutex(NULL, FALSE, "このアプリケーションの名前"); } ~ImNotOriginal(){} operator bool() { return (GetLastError() == ERROR_ALREADY_EXISTS); } }; というコーディングは可能でしょうか?ということです あ・・・これだとミューテックス生成そのものに失敗してもfalseになっちゃうのかな・・・
我ながら阿呆だ・・・ 1度しか呼ばれない事を前提にすれば class ImNotOriginal { public: operator bool() { HANDLE hMutex = CreateMutex(NULL, FALSE, gc_AppName); DWORD result = GetLastError(); return (hMutex == NULL || result == ERROR_ALREADY_EXISTS); } }; これでいいのですね
>>913 if(ImNotOriginal()) はまず ImNotOriginal() が評価され、コンストラクタが
呼ばれる。
次に、if は評価式に bool を要求するので、bool に型キャストされて operator bool()
が呼ばれる。
つまり、望み通りコンストラクタに続けて operator bool() が呼ばれるし、必ずそう動く
ものと見なして良いが、結果そうなるだけで言語レベルで保証しているという訳ではない。
>>915 そこまでひらめいたなら、関数化するべきだ。
クラスである意味は全く無い。
どーでもいーけど CreateMutex() って、lpName が "(゚Д゚)ハァ?" でも "\\" でも
"\r\n" でも "" でも成功するんだよなー。
C++ってjavaとかperlに比べて標準/準標準ライブラリが貧弱すぎると思うんですが 私が知らないだけでしょうか。 libwwwとboostはつかってますがほかになんかいいのないですか?
>>917 loki、common c++ libraryかなぁ…メジャーなのだと(cc++がメジャーかどうかはアレだが)。
欲しい機能に++とかCC付けて検索すると結構APIにヒットしたりするよ。socket++、socketCCとか、
pthreadCCとか。
CやC++は、基本的に「最低限は用意してるから、後は自分で用意しろや」ってスタンスが強いから、
自作するか他人様が作ったライブラリを求めてネットをさまようしかないだろうな。
>>917 ACE, Blitz++, FC++ …などなど。
ライブラリじゃないけどflex/bisonとか。
TRACEってなに? 文字を表示するもの?
>>620 VCのデバッグ窓に文字列を表示・・ジャネーノ?
#二重起動云々はVCスレでやってほしいのう
922 :
男子高校生 :02/10/18 14:44
クラスとその周辺の設計ムズイんだけどー 実用的に汎用にすんのが辛いね。
>>922 激しく汎用化してしまえ。
マジレスするとそういのうは経験が必要だから、とりあえず適当に組むべし。
そのうち慣れるよ。
激しくgenerativeに書け 自分さえも読めない罠にはまって射精するのが漢
925 :
デフォルトの名無しさん :02/10/18 20:28
UNIXで、socketのselectだけできりゃいいんですけど、BSD系のライセンスで シンプルなwrapper libraryないですかねえ。MT不要、fork不要、realtime signal なぞぜんぜんいらない。 自分で書けってか。
(・∀・) オナーニ!! ∧_∧____ エッ Σ (*゚−゚) ./\ /| ̄〇〇 ̄|\/ |__しぃ++.__|/ .  ̄ ̄ ̄ ̄
これってどう? inline string &operator<<(string &Str, char AddStr) { return Str += AddStr; } inline string &operator<<(string &Str, const char *AddStr) { return Str += AddStr; } inline string &operator<<(string &Str, string &AddStr) { return Str += AddStr; }
>>929 いらん
TC++PL3rdや
>>3 のFinal Draftにある文法に
member-declaration
:decl-specifier-seqopt member-declarator-listopt ;
|function-definition ;opt
|::opt nested-name-specifier templateopt unqualified-id ;
|using-declaration
|template-declaration
;
という部分がありますが上から三番目は何に使われてますか?
>>930 文法を示されて、一瞬何の事かわからなかった。
すまん、stringは独自クラスではなくてstd::stringなのだが…。k94i
ostreamのように
str1 << str2 << '(' << str3 << ")";
とかできればいいなと思ったの。
ちなみに上から三番目の第二引数はconst忘れ。
ごめん勘違い。
わしの娘であるstringstreamでは不満ということかね?
>>930 住人が同じであるいじょう何度聞いても答えは得られないと思われ
所詮2ちゃんはこの程度かと思いながら他のもっとましなところに行くことをおすすめする
>>935 じつはすでに2chはこの程度かと思っているが、
comp.lang.c++などで聞く気にもなれず自分はこの程度かとも思っている。
>>937 所詮、平民出のプログラマには、stringのような田舎娘がお似合いということね!
E-mail 設定し直すの忘れたよ・・・938 スマソ。 「Cから見ればstringも充分アレだし」 と書きたかった。
comp.lang.c++も void main() で盛り上がってた。
voidタンは?
943 :
スーパー初心者 :02/10/19 12:10
ムーテックスってなに?
(´ゞ)←これ
945 :
デフォルトの名無しさん :02/10/19 13:22
#if abc #error (・∀・) #endif abcと同名のシンボルは無いはずだけど全ての処理系で通る(falseで)! 大ハケーン?
946 :
デフォルトの名無しさん :02/10/19 13:24
つかmankoでもchinkoでも何でもOKっぽよ!?(奇跡)
947 :
デフォルトの名無しさん :02/10/19 13:27
ぽよ→ぽいよ
948 :
デフォルトの名無しさん :02/10/19 13:31
#ifdef と勘違いしているだけだ とマジレスしてみるテスト
ポインタ型に対する const 指定の説明なのだが、 例えばポインタ演算 **p の結合規則は右から左なので、(*(*p)) と同じだ。 それと同様に考えればいい。 つまり、char const * p; は char (const (* p)); で、p そのものは変更できるが *p が指すものは変更できない。 逆に、char * const p; は char (* (const p)); で、p そのものは変更できないが *p が指すものは変更できる。 そして、char const * const p; は char (const (* (const p))); であり、これは p そのものも *p が指すものも変更できない。 なお、const char * p; は char const * p; と全く同一である。 でよろしいか?
次スレの予感
まもなくここは 乂千取り合戦場乂 となります。 \∧_ヘ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ,,、,、,,, / \〇ノゝ∩ < 0x03E8 取り合戦、いくぞゴルァ!! ,,、,、,,, /三√ ゚Д゚) / \____________ ,,、,、,,, /三/| ゚U゚|\ ,,、,、,,, ,,、,、,,, ,,、,、,,, U (:::::::::::) ,,、,、,,, \オーーーーーーーッ!!/ //三/|三|\ ∧_∧∧_∧ ∧_∧∧_∧∧_∧∧_∧ ∪ ∪ ( ) ( ) ( ) ) ,,、,、,,, ,,、,、,,, ∧_∧∧_∧∧_∧ ∧_∧∧_∧∧_∧∧_∧ ,,、,、,,, ( ) ( ) ( ) ( )
(;゚Д゚)∩ < なら俺は01747を取りに逝くぞモルァ!
957 :
デフォルトの名無しさん :02/10/20 14:56
957!!
957+1!
++ 957 ++;
960
957+4!
957+1+1+1+1+1!
BOOST_PP_INC(962);
long *p = (long *)0x03C0; p++; printf("%d", (char *)p + 1);
char _[967]; get = sizeof(_);
2*22*22
#include <iostream> for (int i = 0 ; i < 969 ; ++i) { std::cout << "(・∀・)マンコ!!" << std::endl; }
971 :
デフォルトの名無しさん :02/10/23 01:07
>>970 プログラムというよりただのシークエンスという気がする。
間違いなくコンパイル通らないだろうし。
throw itteyoshiException(util::make_container<vector, int>() << 969 << 972);
make_containerって何だよ。Java厨の出張?
#include <iostream> int main(int argc, char** argv) { for (int i = 0 ; i < 975 ; ++i) { std::cout << "(・∀・)ティンポ!!" << std::endl; } return 0; }
_____ |\ \ | | ̄ ̄ ̄ ̄| | | ´∀` | ヒキコもこもこ引き篭もり〜♪ | | 鬱 | \|____| 人 Y し (_)
cout<<"CountDown! : "<<1000 - __LINE__<<endl;
スマートポインタっていっても下のようにいろいろあるわけだけど、 std::auto_ptr ( Standerd C++ Library ) boost::sheard_ptr ( Boost ) Loki::SmartPtr ( Loki ) YTL::smart_ptr ( Yaneura Game SDK 3rd ) みんなは、どれを一番使ってるよ? ほかにも、イイのがあったら教えてくれ。
普通はboost::shared_ptr<>, boost::weak_ptr<>, boost::scoped_ptr<> およびその配列版だと思うが。
std::auto_ptrはスマートポインタじゃなかったような気が
>>980 Loki のスマートポインタは、いろいろいじれるから、
趣味や勉強にはいいかも。
個人的には期待大
やねうらお の smart_ptr は、面白いけど、どれだけ使う場面があるかは微妙。
やっぱ Boost か。
CComPtrとか書いたらしばかれますか?
fifteen response
YTL::oreno_nikubouwo_sakuratanni_buchikomu_haxahaxa_ptr
the rest: thirteen
早期梅。
今日も梅。
990 :
デフォルトの名無しさん :02/10/28 12:22
ten
´-`).。oO(激しく上げちゃった…やばい)
記念パピコV(^o^)V
梅v(^・^)v梅
埋め立て中
記念カキコ
996 :
デフォルトの名無しさん :02/10/28 20:37
ageちゃったりなんかして
997 :
ぉながいします :02/10/28 20:39
0〜99の数字を1秒間隔で表示。1〜9で改行、表示する こんな感じです 1 2 3 4 5 6 7 8 9 10 11 12〜〜〜〜〜〜〜〜〜〜〜〜 〜〜〜〜〜〜〜省略〜〜〜〜〜〜〜〜 〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜99 これのプログラムを教えてください よろしくお願いします
998 :
デフォルトの名無しさん :02/10/28 20:41
ってもうスレねーーーー
999 :
デフォルトの名無しさん :02/10/28 20:43
おれ
999ゲットズザー
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。