1 :
v(^・^)v :
04/05/09 00:39 C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
テンプレートライブラリ(STL含む)に関する質問は
専用の別スレにお願いッス。
過去スレ、関連スレ、関連リンクなどは
>>2-9 あたり
はじめてすれ建てしたよ。 関連スレは増えてたんで適当にわけたよ。 足りない分は補充よろしくです。 テンプレは以上です。
10 :
デフォルトの名無しさん :04/05/09 00:52
乙!
それでは地鎮祭を始めてください。
12 :
デフォルトの名無しさん :04/05/09 00:59
D言語でいこう
春ですね〜 呑まれねばなるまい 呑まれねばなるまい
>>前スレ990 > 恥ずかしながら関数型という言葉を知らないんだが具体例をきぼん。 typedef int filter( int ); filter identity; int identity( int x ){ return x; } boost::function< filter > f = identity; とか。
filter* p = identity; とか。
それにしても、前スレ
>>988 の必死さと頭の悪さは笑えた。
↑自作自演か?
そんなにかまってもらいたいのか?
19 :
デフォルトの名無しさん :04/05/09 01:23
>>16-17 つまらん自演で「場がその話題で盛り上がってるフリ」して楽しいか?
自演乙
976 :デフォルトの名無しさん :04/05/08 23:09
>>972 それはお前がバカだから、
Effective C++
読んでから言え。もっとも積極的に勧めてるわけじゃなく、
両方読める必要があると言っている。
お前はそれを知らなかったんだから、知る必要があったわけだ。
無知をひけらかして恥さらすな。
988 :デフォルトの名無しさん :04/05/08 23:28
>>983 お前が何にも知らんことは文面から用意に察することができたのでバカでも知ってる教科書名を挙げてやったのよ。
一通りよんでりゃ、const の前置、後置ぐらいでスレ汚すバカは居ないだろうからな。勉強になったことを感謝しろ。
日 本 海 溝 よ り 教 育 レ ベ ル の 低 い 糞 ガ キ よ 。
999 :デフォルトの名無しさん :04/05/08 23:45
>バカはおまえだ。俺は両方の表現知ってたし、
バーカ。こんなこと知ってるぐらいのことを何宣言してんだ。アホの活造りかおまえ。
22 :
デフォルトの名無しさん :04/05/09 01:27
オーバーロードとオーバーライド それぞれの機能は認識してるんだけど、名前が時々どっちだったっけって 迷う。何か良い憶え方無い? ゴロ合わせでもいいんだけど…
Expression Template はテンプレートスレがいいのかな?
>>22 「オペレータ・オーバーロード」はきいたことあるっしょ?
これを覚えておけばどっちがどっちかすぐにわかるでしょ。
25 :
デフォルトの名無しさん :04/05/09 01:29
>>22 C++はオーバーロード。
Javaはオーバーライド。
D言語は?
オーバードース
「ロリコンは多人数」と覚えておけ。
>>22 オーバーライドという単語の"ride = 乗っかる"の部分に注目すれば、
認識するのは容易だと思うけどなぁ。
ずっとカタカナで考えてると混乱するかもね。
オーバーロード:(道は)一つだけとは限らない、沢山ある オーバーライド:乗り移る
別に名前憶えてなくとも、組めりゃいい
Object Pascalだとキーワードになってるから覚えなきゃいけない。
エレベーターとエスカレーターがごっちゃになる どこぞの関西弁女子高生を思い出した
34 :
デフォルトの名無しさん :04/05/09 01:46
オーバーロードのロードって道(road)だったのか・・・
チガウヨ
まあアレだ、 カタカナより日本語の方が日本人にとって 覚えやすいのは確かだ。
みんなありがとう!
英語の弱いロリコンの俺は、
>>28 で逝きまつ
カタカナは日本語ではないそうです。
オーバーロードのロードはだな THE虎舞竜 ロード第一章 のロードだと覚えとけばイイ!!
>>42 THE 虎舞竜のロードは奴らにとって“道”ではなく“重荷”だったといいたいわけか?
>>45 ごめん、
>>42 のどこがどう語呂合わせになってるのかさっぱり分からないんだけど。
ロード第一章で覚えておくと、なんでオーバーライドとオーバロードの違いが覚えられるの?
オーバーロード:(同じ名前の関数を)ロードし過ぎ オーバーライド:上書き
オーバーロード:横のつながり オーバーライド:縦のつながり
STLつかうと一気に実行ファイルサイズが10倍に?!
>>50 環境によるだろ。
俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力
ランタイムを使用するようにして使っているが、例えばstd::vectorを
使っても使わない時と比べ10Kほどしか増えない。
>>51 すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。
>>51 すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。
あぁ今スレではまだだったか。
>>52 スマソ(w
C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。
とかいうエラーが出るんだけどこれってどうすればいいのですか?
糞が黙ってろ!市ね
>>55 #include "stdafx.h"
後死ね。
>>57 言葉が悪いな。それで教えているつもりか。
まぁヒントぐらいにはなったな。
うむごくろう。
あぁ自作自演
つうか、もう飽きたよ
61 :
デフォルトの名無しさん :04/05/09 18:28
class A { int a; int b; public: void Set(int i, int j) { a = i; b = j; } } などと適当に作って、printf("%d\n", sizeof(A)); してみると8バイトって 出るんですが、メンバ関数の部分ってメモリを食わないんでしょうか?
ポインタ
>>61 面罵関数へのアドレスはコンパイル時に決定されるから要らない。
ただvirtualなものがある場合VMT分の領域が要る。
>>61 クラスインスタンスごとに必要なメモリ量にメンバ関数自体は関係ない。
それでも、「メモリを食わない」とは言い切れなくって、
virtual関数の有る無しで間接的に影響することはあるし、
コード領域としてメモリを食うと言えるかもしれない。
> 面罵関数へのアドレスはコンパイル時に決定されるから要らない。
なんか胡散臭い説明だなぁ。
で、復刊C++プログラミングの筋と定石を買った奴はいるのか。
これって原書Advanced C++のこと??
クラスのメンバ変数を static にする理由って何ですか?
>>67 個々のインスタンスではなく、クラス全体で共有したいから。
>>67 同じ内容を各インスタンスの中それぞれに含むのは効率が悪いんだよ。
>>67 デザパタ本を読めばわかるかもよ。GoFなんかスタンダードな所で。
>>67 インスタンスではなく、そのクラス自体の属性を表現する場合に用いる
組み込み用に書いたCのソースの動作をGUIでテストしたいのですが、 VC++やBCBなどのC++からCを動かす方法でいいアイデアがあったら 教えてください。 とりあえず思いついたのはC++のクラス定義部分にて class hoge{ public: #include "目的のソース.c" } と書いて動かしています。
>>73 普通はCモジュールのヘッダファイルの頭に
#ifdef __cplusplus
extern "C" {
#endif
を、最後に
#ifdef __cplusplus
}
#endif
を書けばC++から普通に呼べるんだがね
namespace hoge { extern "C" { #include "目的のソースのヘッダ.h" } } クラスにすりゃGUIになるってもんでもないし、 こうして使えばいい。
>>質問アゲ 質問する態度じゃない カエレ!
環境はVCとかBCCなんだろ? 普通じゃん。
>>77 76は最近良く沸いてるage嵐じゃないの?
73の態度から76はちょっと考えづらい。
あぁ、そうかも。 だったらスマンかった。。。>73
82 :
デフォルトの名無しさん :04/05/09 22:55
>>73 その「Cのソース」をコンパイラのオプションか拡張子を変更してC++ソースとしてコンパイルしてみれ
もし問題が全く起きないか、容易に解決できる問題しか発生しなければそれがベスト。
>>83 Cとして書かれたソースでも、C++としてコンパイルできる場合があるということ。
って、あまり説明になってないが、わからんかな?
俺は82じゃないけど、意味わかったぞ。
Effective C++ にメンバ変数をpublicにすんなって書いてあったので、 class AGE { private: std::vector< double > _age; ...その他もろもろ public: AGE( size_t size ) : _age( size ) {} std::vector< double >& age( void ) { return _age; } ...その他もろもろ }; void fun( std::vector< double >& ){...} int main( void ) { AGE age( 10000 ); fun( age.age() ); ... } と書いたらメンバの参照を返すなとも書いて有りますた。 漏れはどうしたらいいでつか?
class AGE { ... public: ... void fun() { fun( _age ); } ... };
double& AGE::GetAgeData(const unsigned int nIndex) { if(nIndex < _age.size()) return _age.at(nIndex); else return -1; } みたいなもん作れってことか?
>>86 ども。
AGEは汎用にしたくて(DATAのバッファ用等)fun()とかメンバ関数持たせたくない場合はやむを得ずでしょうか?
>>88 互いに関係の無いもの同士をひとつにまとめるだけならpublicなデータメンバによるstructにすればいい。
「メンバ変数をpublicにすんな」、「メンバの参照を返すな」というのは、
クラスがただのデータの集まり以上の意味を持つとか、
データメンバの間に常に保たなければならない整合性があるとか、
そういった場合の話。
ただのデータの集まりならstructで単純にまとめればいい。
便乗です。メンバ変数のポインタは返してもいいのですか。
返すのは自由だが、どう使うつもりなんだ?
>>91 SoBigはとてもデータのサイズが大きい構造体です。
class a
{
SoBig big;
public:
SoBig* GetData(){return &big;}
};
つまり、値で返してしまうとコピーに時間がかかってしまうのでポインタを渡すということです。
>>93 そういうときはせめてconstつける。つか、参照で充分だが。
Sobigは嫌なウイルスだったな…
誤爆スマソ
このスレもC言語スレ並にネタスレ化してきたな
>>97 馬鹿が増えたからだよ(もちろん俺様を除く)。
このスレもネタスレ化してきたな
100げt
グローバル変数a,bがあります。 class A { public: int value; A() { value = 1; } }; A a; class B { public: int value; B() { value = a.value; } }; B b; こういうので、aがコンストラクトされるまえにbがコンストラクトされてしまって bは正しく初期化されない、ということってありえますか? 正しくは b.value == 1 になると思うのですが実際には0になります。 関係あるか分かりませんが、aとbは実際には別の翻訳単位で定義されています。 つかってるのはvc.net2003です。
>>101 というか、ダメな見本のようなコーディングだよな。
自己解凍しました
イニシャライズ用の関数若しくはクラスを作って 初期化の依存関係に応じてイニシャライザを呼ぶ
自家生産しました
つまんないから
>
>>104 >それぐらい考えろ。
嫌ならわざわざ書き込むな糞が。
>>110 違うよ。最初からそれぐらい考えろって言ってる訳じゃなく、
ヒントを与えてから言ってる。
別にやりたくもない宿題だったらまだしも自分でプログラムの勉強してるなら
考えないとダメになる。
>>111 C++FAQ第2版の16.14〜16.18に解決策が載ってるよ。
これはその一番最初の例。Bの静的変数はA内に保持する方法。
class B {
public:
int value;
B(int v) : value(v) {}
void f() { std::cout << "B::f(), value = " << value << std::endl; }
};
class A {
protected:
static B& bo(int x) {
static B* p = new B(x);
return *p;
}
public:
int value;
A() { value = 1; }
void f() {
std::cout << "A::f(), value = " << value << std::endl;
bo(value).f();
}
};
A a;
int main()
{
a.f();
}
Bのstatic変数はA内からbo(int)としてアクセスできる。 もしこのintが邪魔なら static B& bo(int x = 0) { static B* p = new B(x); return *p; } とでもすればいい。とにかくAがBより先に初期化されて欲しければ Aの内部にBを持つしかない。
>>113 そんなことするよりも
>>107 の方が断然いい。
ほんとに一度しか初期化されたくなければフラグ持たせればいいわけだし。
>>114 「シングルトン」でググれ。
ついでに、「僧衣」でググれ。
>>115 singletonとは別だろ?
というか
>>101 が何をしたいかによる。
インスタンスが一つしか嫌だってばあいはsingletonだし
複数持ちたい場合はsingletonじゃダメだし。
多くの場合、シングルトンで作ると可植性・拡張性が落ちるよ。
何でもかんでもすぐにデザパタっていうのは嫌い。 もちろんデザパタはいいが使いかたも知らないで使ってる奴もいるし。
理想としてはアリなんだけどね。現実が・・・。
実際はグローバルじゃなくてクラスのstatic変数なので ポインタでもつようにしました。
singletonというか、Phoenix singletonでない? たしか、生成順の制御ができたやつ。
実際にはそんな高尚なプログラムではなく、101の設計が悪いだけ、というのはありがちな話だ。
>121 phoenix singleton は破棄の順序が問題になる場合。 今回は生成順序なので >107 で十分でしょ。 singleton はしばしば >107 のように実装されるけど、唯一性を目的としたものじゃ なければ singleton じゃないわな。
再利用できる部品を作る場合、いちいち生成順序を気にしたくないな
>>124 同感。
かなり微妙だからね、生成順序って。
トレースさえ開始できないタイミングで生成されると
動作確認がお手挙げだし。
126 :
デフォルトの名無しさん :04/05/11 23:33
singleton の生成にdouble checked locking パターン? は使えないという記事をどこかで読んだけど、 どうしてダメなのか意味がわからんかった 誰かサルにもわかるように優しく教えてください
>>126 デザパタスレってなかった?そっちで聞いた方がいいと思うけど?
仕様変更に弱すぎ。>シングルトン
>>127 メモリ確保→コンストラクタ
の一連の処理がアトミックになってないって事なんですかね
なんとなく納得しました
微妙にスレ違いですんませんでした
131 :
デフォルトの名無しさん :04/05/12 01:16
メモリ確保とコンストラクトが アトミックになってないなんて… > Java 使えないインスタンスを返すなんて重大な設計ミスのような希ガス。
instance =new Singleton(); が JIT で mem = allocate(); instance = mem; ctorSingleton(instance); こんな擬似コードを出力するという主張らしいんだけど スレッドを考えると少なくともこうしないとまずいよね。 mem = allocate(); ctorSingleton(mem); instance = mem;
つまり「double checked locking パターンは使えない」というのはJavaの話で、C++では問題ないのですか?
>>135 コンテキストスイッチが発生する位置によっては
C++でも保証はされないだろうな
>>136 そりゃ、C++の言語仕様でスレッドに関する保証を得るのは無理だけど、
正しく動作するlock/unlockを前提にすれば、
double checked lockingという手法自体は問題ないんじゃないの?
>>138 だから、lock/unlockは前提と言うことで済ませた上で、
「C++では
>>134 のような問題はない」→「C++ではdouble checked lockingは問題ない」
ってことじゃないの?
>>139 生成されるコードによるってことが分からないの?
あれはJavaに限った話じゃない。
C++では生成されるコードに対する規定はまったくなされてないよ。
規格書を見てみたよ。 >5.3.4 New >The new-expression attempts to create an object of the type-id or >new-type-id to which it is applied. (中略) If the entity is a >non-array object, the new-expression returns a pointer to the object >created. パラグラフの最後に"new は「生成された」オブジェクトのポインタを返す" ってあるから、コンストラクタは通らないとまずいんじゃないかな。 コンストラクタを通らないと created にはならないんでは。 the object allocated なら別だけども。
だから、そういう問題じゃないんだって。
>C++では生成されるコードに対する規定はまったくなされてないよ。 どんなコードを生成してもいいってわけじゃあないし。 制限がなかったら規格の意味なんてない。
145 :
デフォルトの名無しさん :04/05/12 10:30
C++ソースとその出力コードの組み合わせで、
>>127 (
>>134 )の問題が発生するようなシナリオのサンプルきぼん。
出力コードは擬似でもいいです。
個人的には
>>139 が正しいと思ってます。
とりあえず、VC6の吐き出したコード。 337: EnterCriticalSection(&Singleton::cs); 004025E6 mov esi,esp 004025E8 push offset Singleton::cs (00405258) 004025ED call dword ptr [__imp__EnterCriticalSection@4 (00406228)] 004025F3 cmp esi,esp 004025F5 call _chkesp (00403004) 338: if (instance == NULL) 004025FA cmp dword ptr [Singleton::instance (00405274)],0 00402601 jne Singleton::getInstance+97h (00402647) 339: instance = new Singleton(); 00402603 push 1 00402605 call operator new (0040302c) ----- *1 0040260A add esp,4 0040260D mov dword ptr [ebp-14h],eax 00402610 mov dword ptr [ebp-4],0 00402617 cmp dword ptr [ebp-14h],0 0040261B je Singleton::getInstance+7Ah (0040262a) 0040261D mov ecx,dword ptr [ebp-14h] 00402620 call Singleton::Singleton (00402680) ----- *2
00402625 mov dword ptr [ebp-58h],eax
00402628 jmp Singleton::getInstance+81h (00402631)
0040262A mov dword ptr [ebp-58h],0
00402631 mov eax,dword ptr [ebp-58h]
00402634 mov dword ptr [ebp-10h],eax
00402637 mov dword ptr [ebp-4],0FFFFFFFFh
0040263E mov ecx,dword ptr [ebp-10h]
00402641 mov dword ptr [Singleton::instance (00405274)],ecx ----- *3
340: LeaveCriticalSection(&Singleton::cs);
00402647 mov esi,esp
00402649 push offset Singleton::cs (00405258)
0040264E call dword ptr [__imp__LeaveCriticalSection@4 (00406224)]
00402654 cmp esi,esp
00402656 call _chkesp (00403004)
*1で一時領域にメモリの確保
*2でコンストラクタの呼び出し
*3で変数instanceへの格納
と、
>>134 でいう後者のパターンで構築が行われているので、
VCの吐き出したコードには問題がない。
じゃあ、前者のパターンのコードを掃き出すコンパイラがあったらどうなる?
Javaと同じ問題を抱える事になるね。
>>148 a = new A();
と書いてるのなら、式の評価順序としては
コンストラクタの実行がaへの代入より後になるなんて考えられない気がするが
規格に規定ないの?
mem = alloc(); ctor(mem); a = mem; 上のコードが、最適化によって a = alloc(); ctor(a); にされちまうことがあるのかもしれんな。 スレッド間の干渉まで考慮してくれるような賢いコンパイラが要求されてるならvolatileなんてキーワードも必要ねーしな
>>149 評価を終了せずに代入することはないから
まともな処理系なら問題なし。
まともじゃない処理系は…捨てたほうが。(ワラ
なんか、議論がずれてない?MC++DのP157に出ているように double checked lockingが保証されるかどうかはCPU(コンパイラ)の 問題なんじゃないの? 仮にdouble checked lockingが有効だったとしても、 allocateとctorの順番がどうであれMC++Dの double checked lockingをつかったsingletonの 実装には関係なさそうに見えるし。
あーうそだ。 a = alloc(); ctor(a); だったら、MC++Dの実装でもまずいか。orz ただ、double checked lockingがCPU依存なのはOKだよね?
a = new A(); は、 a.operator=(new A()); だから評価が終わるまで代入される事は無い。
155 :
デフォルトの名無しさん :04/05/12 14:13
std::stringの文字列に、後から文字列を追加する場合、 メモリの再割り当ては行われているのでしょうか? appendで追加すると、文字化けがおこってしまいますし、 resizeやreserveを行うと、既存文字列自体が破壊されているようです。 どうすればいいんのでしょうか?
>>155 何やってるの? なんか変なことやってない?
appendはもちろん再割り当てが行われ得るし
reserveとかで既存の内容が破壊されるってことは普通ありえないが。
普通に代入してるのなら。
>>155 もしかしてstringをstringのままで使わずに
文字列のポインタ得てそれを使い続けようとしてたりしてる?
158 :
デフォルトの名無しさん :04/05/12 14:19
>>156 すいません。実行してみたらちゃんと出てました。
でもデバッグしてると、内容が「|r」とかわけわからんものになってるんです。
そいで、そのstringの_Mysizeとやらが16になってるんですが、
文字列の長さも16なんで、ヌル文字分が確保されていないように思うのですが。
>>158 ああ、VC7.1で少なくともマルチスレッド版だと
16文字までは自身に格納し、それを超えたら参照カウント共有とかやってるみたいだね。
で、デバッガでみると間違ったほうが表示されたりすることがあるね。
まあそういうこと。とりあえずコード側でassertionとかdebug printとかで逃げてるよ。
160 :
デフォルトの名無しさん :04/05/12 14:23
連カキすいません。
ちゃんと表示されてるのは、string tempとして、
temp.c_str()をやってるからなんでしょうか?
>>157 stringのまま使っています。
vcでデバッグして、tempの値をトレースしてると、文字化けが起こります。
具体的には、「ConsoleLog-1.txt」(16文字)という文字なんですが、
1の部分が2,3...10...20...と増えていくので、
ConsoleLogの後に「-」,「(数字)」,「.txt」を3回に分けてappendしています。
161 :
デフォルトの名無しさん :04/05/12 14:25
>>159 そうなんですか。ありがとうです。
プログラム自体はちゃんと動くんですが、デバッグしてたら不安になりました。
>>158 >ヌル文字分確保
std::stringがヌル文字分確保するなんて誰に聞いた?
.c_str() こちらは最後にヌル文字が付加されるね。
長さを知ってれば'\0'はいらないのれす
vectorで、ある要素の直前に新しい要素を挿入したい場合どうしたらいいんでしょうか? 要素は独自定義のクラスのオブジェクトのポインタなんですが。
>>165 insertでイテレータを指定しますよね?
ある要素のイテレータを取得するにはどうしたらいいんですか?
その要素のポインタは分かるんですけど。
>>166 vector.begin()はrandom access iteratorを返すので
vector[i]のイテレータは (vector.begin() + i)で得られるけどな。
教えてください。 istream_iteratorでdifference_typeってのを指定しますよね。 こんな感じ。 typedef vector<string>::difference_type deff_type; ifstream infile("XXXXX"); istream_iterator<string, diff_type> input_set(infile); このdifference_typeというのは、解説書によるとイテレータ 同士の減算を行った際の差を格納するための型だということでした。 これがどうもピンと来ないのですが、上の例だとイテレータ間の stringが全部格納されるのでしょうか?しかし、型指定しただけで そんなうまいこといくんでしょうか?それとも違うでしょうか? そもそも組み込み型の配列の場合ってポインタの減算は、その型の 要素数の差が返ってきますよね。単純に数値が・・。 vector<string>に距離を収めるとはどいうことなんでしょうか?
>>169 単純に数値と考えれば良い
「差」を表す名前を与えただけ。
レスどうもです。 ちょっとわからんのですが、数値だとしてなぜにvector<string>型を 指定するのでしょうか?そこの意味がわからんのです。 実際にイテレータ同士の減算を行った結果を格納するのが、上の例で いうとvector<string>なんですよね?数値の型としては不適当な 気がするんですが・・・。
>>171 vector<string>じゃなくてvector<string>::difference_typeだよ?
あ、そうか・・・じゃvector<string>って何なんでしょうか。 たとえば他の型を指定することも可能ですか?上の例で。 またそれによって変化がでてくるのでしょうか・・・。
differnce_typeがptrdiff_t以外なのってみたことない
ちなみに私があげた例はC++ Primerにあったコードを簡略化したものです。
スマソ、誤爆った。
>175 vector<string>::iterator って書き方したことない? vector<string> のイテレータの型が vector<string>::iterator。 で、この vector<string>::iterator の差の型が vector<string>::difference_type になる。 istream_iterator に対してテンプレート引数 Distance を指定するということは、その istream_iterator の差が Distance 型になるということだ。 istream_iterator は Input iterator なので実質 distance() が返す型が Distance 型になるってことだな。 ほとんど意味がない。 なのでわざわざ Distance を指定せずデフォルトにまかせるのが普通。 なお、istream_iterator の宣言は↓の通りなのでそのコード間違ってるよ? template <class T, class charT = char, class traits = char_traits<charT>, class Distance = ptrdiff_t> class istream_iterator:
つまり「double checked locking パターンは使えない」というのはJavaの話で、C++では問題ないのですね?
179 :
デフォルトの名無しさん :04/05/13 00:18
でも結局どうすればいいんだろ? シングルdインスタンスを取得するたびにロックするしかない?
マルチスレッドで最初に要求があったときに作成するというスタイルを止めろ ってのは?
std::stringからintに変換するにはどうしたらいいんでしょうか? stringには数字しか入ってないのは分かっています。
一番楽なのは恐らくboost::lexical_cast
std::string::c_str()の後にatoi()とか std::istringstream使うとか
vectorの要素へのアクセスって何がいいんでしょう? std::vector< double > tmp(10); tmp[1]、std::vector< double >::iterator、tmp.at(1)等などありますけど。 それから、sizeが必要な場合関数への受け渡しは何がいいですか? void func( std::vector< double >& d ){ size_t size(d.size());...} void func( std::vector< double >::iterator begin, std::vector< double >::iterator end ) void func( double *tmp, size_t size ) 幾らでも方法がありますけど。
シングルトンにせよ何にせよ排他制御できる方法があるなら boostがAPIを使ったりはしないと思うのだが。
は?
>>187 tmp.at(1)は範囲エラーの時に例外が飛ぶが、
tmp[1]は例外が飛ばない。(たぶん
template <typename RIt> void func(RIt top,RIt last);
はいかが?格納方法がvectorであることも強要しないし、
double *tmpの用にメモリ上に連続であることも強要しない。
RandamAccessIteratorである事のみ強要する。
ただ、funcの性質にもよると思う。実装ベタベタな関数なら楽なのに
すればいいし、汎用的にするなら上記方法もありだし。
>>177 詳細な説明ありがとうございました。
意味ナッシングですか・・・。
どうもPrimerの著者は、執筆してる段階ではまだ古いC++コンパイラ
使ってたようで、その辺の名残がサンプルコードにあるみたいです。
素直にデフォルトでいけばいいですね。
194 :
デフォルトの名無しさん :04/05/13 23:51
c++でgetoptよりもカッコイイオプションの取得の仕方を教えてください
>>194 boost::program_options
196 :
デフォルトの名無しさん :04/05/14 00:05
本屋へ行き、趣味と雑誌のコーナーを探す
VC++プログラマは知らないgetopt が一番だろ。
198 :
デフォルトの名無しさん :04/05/14 00:14
みなさんありがとうございます vcでも使いたいのですがboostは使わせてもらえないので 素直にboostのソースをコピペしてつかう事にします
"placement new"で日本語のページをグーグルしたら > class X { > public: > static void *operator new( size_t size, void *buf ) { return buf; } > }; と、しなければ placement new はコンパイルエラーになるって書いて あります。が、下のソースで何の問題もおきません。std::vectorの動作を 考えてみてもoperator newの定義はなくてもいいと思うんですが、どうなんですか? #include <iostream> struct S { S() { value = 555; } int value; }; int main() { char buf[sizeof(S)] = { 0 }; S* s = new (buf) S; std::cout << s->value << std::endl; return 0; }
>>198 boost使わせてもらえない = 使用禁止??
boostのソースコピペ = 使用してるじゃん。
馬鹿?
boostってすぐに部分引用できるほどシンプルな作りじゃないと思うのだが。 どうよ、お前ら。
getopt コピーするほうが簡単だよ。
>>200 開発環境に明示的に組み込めないってことだろ
外部ライブラリを使っちゃいけないとか規約があって
自作の振りしてこっそりコピペするんだろ。すぐバレそうだけど
boostをコピペねぇ・・
商用開発でboostのようなライブラリを使えない理由って例えばどんなのがあるんでしょうか? boostの場合コンパイラを選ぶって理由はあるとは思いますが 商用利用においてライセンス周りでうるさいライブラリではないと思うのですが・・・ boost使ったコードを理解できない(ドキュメント読んで理解する時間が惜しい)という理由でしょうか? 厨な質問で申し訳ないです。
ある意味、これがクラスライブラリの痛いところだよな。 部分コピペしにくいのは明らかにグローバル関数じゃなくてクラス関数。
208 :
デフォルトの名無しさん :04/05/14 01:21
boost使ったコードを理解できないっている? そんなやついっしょに仕事したくない
俺はspiritわからんよ
>>208 ・・・と同時にmplあたりをすらすら理解できてすらすら書くようなやつとも
一緒に仕事したくないわけだがw
211 :
デフォルトの名無しさん :04/05/14 01:28
やっぱ、2chってレベル低すぎw
特に「w」を使う奴は底辺に位置する
213 :
デフォルトの名無しさん :04/05/14 02:28
struct A { char a; char b; char c; char d; }; A proc(void) { return NULL; } ↑このプログラムがコンパイルできないんですけど コンパイルが通るようにキャストする方法ありませんか?
なんでAにNULL返そうとしてんだ? A*ならまだしも。
216 :
デフォルトの名無しさん :04/05/14 02:46
>>214 C++です。
>>215 A proc(void)
{
A r;
r.a = 0;
r.b = 0;
r.c = 0;
r.d = 0;
return r;
}
でもいいんですけどちょっと高速にしたくて。
>>216 戻り値最適化を期待するならコンストラクタを作っておいて、
return A(0, 0, 0, 0); でいいのでは。
単に初期化したいだけ?
>>219 実際にコンパイルして試してみた?
それではデフォルトコンストラクタが呼ばれるだけで初期化は
されない。
struct A
{
char a;
char b;
char c;
char d;
A() : a(0), b(0), c(0), d(0) {}
};
とか。もっとスマートな方法があると思うのだが・・・・・
あ、正確にいうと、デフォルトコンストラクタが呼ばれてAの一時 オブジェクトが作られ、それでもって r を初期化する、ですね。 で、一時オブジェクトはメンバが初期化されてないから各メンバ にどんな値が入ってるかわかったもんじゃない、と。
A r; r.c=10; r=A(); return r.c; の場合「0」になったけど? VC.Net2003 Releseで。
>>223 108 16 64 0
になった。各メンバ。BCC5.6.4だけど。
まっとうなOSならプロセスがOSから確保したメモリは0で初期化される。 これはセキュリティ上の問題。 しかし、スタックにせよヒープにせよ、OSが確保して以降全く使用されていないという 保証がなければ当然期待値は「不定」だ。
>>225 それが、VC7.1のコードではDebugでもReleaseでもXOR EAX,EAX
というコードに展開されててゼロクリアしているんだよね。rを。
gcc3.4.0(MinGW)でも同様だった。BCCだけ違う。
どっちが仕様上正しいのかは知らないが VC,GCCなら問題ないと。 まあ、仕様に定義されてないんだろうけど。
>>227 もっと大きなクラスか構造体で試してみたいね。
俺の考えではA()はAのデフォルトコンストラクタを呼び出して
(何もしないですぐリターンする)、一時オブジェクトを作るだけで、
0クリアするなんて掟は規格書にはなかったような記憶が。
規格書12.6.2.4 (暗黙のコンストラクタの規定は12.1.7) 言語規格上は不定値であることが定義されている. (勝手に0クリアするのは規格違反じゃないだけで保証はされない) というか素直に221で良いと思うんですが・・・
struct T { T() {} T(const T&) {} ~T() {} private: const T& operator=(const T&);//禁止したい }; -------------- T t1, t2; t1.~T() new (&t1) T(t2); これって実行時間をのぞけば t1 = t2 を実行できたのと同じことだよね? (operator=がごく普通にコピーをあらわすとして。)
>>230 違う。
T t1, t2;
T(t2)のコンストラクタで例外が発生した場合、
後者ならt1は有効だけど、前者ではそうではない。
というかコピー禁止したい場合は ふつう両方を private において実装なしにするだろ。 ついでに operator= の戻り値は非 const な。実際に使うことは稀だと思うが。
>>232 生成時以外には値をかえられたくない、と思ってこうすることも
ひょっとしたらあるかと思って。
>>229 12.6.2は"Initializing bases and members"なので、そこで「初期化されない」と定義されているのは、
メンバ(または基底クラス)のうち、初期化リストに現れず、且つPOD型である場合。
8.5 -7- により初期化子が空の括弧 () の場合、「デフォルト初期化」されると決まっている。
そして 8.5 -5- により、POD型の「デフォルト初期化」は「ゼロ初期化」であるとされている。
つまりVCとGCCは準拠しているが、BCCは違反。
>>191 レスありがとです。
template <typename RIt> void func(RIt top,RIt last);
を使ってみます。
>>234 一連の話、VCは .NET2003 からね。2002までは初期化してくれない。
>>234 暗黙のデフォルトコンストラクタがメンバに対して空の括弧の初期化子を
適用することは明示されているのでしょうか?
12.1.7 (ISO/IEC 14882/2003)
The implicitly-defined default constructor performs the set of initializations of the
class that would be performed by a user-written default constructor for that class
with an empty mem-initializer-list (12.6.2) and an empty function body.
これの"empty mem-initializer-list"の解釈の問題だと思うのですが,
私は,mem-initializer-listが全く指定されていないコンストラクタと理解したのですが・・・
(よって初期化子リストに現れず,12.6.2.4により初期化は保証されない,という主張です.)
旧式のヘッダファイル名と 標準C++のヘッダファイル名(拡張子無し) をソースファイルに両方記述できますか?例えば #include <windows.h> #include <string> のように
コンパイルが通らなかったんです。
>>239 なんとなく、統一した方が無難かなと思いました
>>234 >>237 struct B
{
int m[1000];
};
int main()
{
B b = B();
std::cout << b.m[0] << std::endl;
}
結果
2621440
何回試してもダメだ。BCCは糞。
c++でフォルダを作成したいんですが、どうしたらいいんでしょうか?
boostはプロジェクトの命名規則に違反してるから使えんな
「も」とか「表」かな
>>248 なるほど。良く分からないんで自分で調べてみます。ありがとうです。
>237 >暗黙のデフォルトコンストラクタがメンバに対して空の括弧の初期化子を >適用することは明示されているのでしょうか? そうではなくて、>234 は POD 型 (ここでは struct A) の () による初期化 自体が zero-initialize になる(からデフォルトコンストラクタは呼ばれない)ので、 0 に初期化されるという主張だと思う。 なお、14882:2003 だと zero-initialize じゃなくて value-initialize となってる。 この例では、結局 zero-initialize と同じ結果になると思われ。
未定義と0は違う(スレの流れ読めてないかも)
>>251 値が不定ってのなら分かるが、未定義となると、デフォルトコンストラクタ
を呼んだ途端にコンピュータがフォーマットされても文句言えんぞ。
253 :
デフォルトの名無しさん :04/05/14 23:54
>>252 コンピュータがフォーマットされるってのが
よくわからんがFORTRANみたいになるのか?
それとも紫外線あてるとか・・・
>>254 かわいい!オシッコ飲みたい!!(;´Д`)ハァハァハァハァ
257 :
デフォルトの名無しさん :04/05/15 08:11
stlって標準で使えるものなんですか?
まぁ、STLのSはスタンダードのSだし・・・
>>257 ・・・
現在はSTLは標準C++の中のテンプレートライブラリ部分の名前。
STLはStamp Trader List
261 :
デフォルトの名無しさん :04/05/15 13:44
三角形の面積を求めるc++プログラム希望。 大学の課題なんで詳しい人助けてー。
三角形の面積って 底辺かける高さわる2 ぢゃないのか?
しかもC++って・・・ Classで三角形だけじゃなくいろいろな面積に繋げるため inheritanceしろってか?
265 :
デフォルトの名無しさん :04/05/15 14:12
>>263 伝統的な章立てで進行する授業なら
データと型あたりか? そこだと、まだclassが登場してないよな
これが授業中だったら笑えるな。
cinとcoutを使うだけで後はCと同じでもよいとか?
vc++を使ってるんですが、グローバル変数を定義すると 「既に定義されています」 というリンクエラーが出ます。 どこで定義すればいいんでしょうか? 今はsfdafxという全てのファイルから参照されるヘッダに宣言しています。
stdafxが多重インクルードされるから。 VCの場合は #pragma once 一般的には #ifndef __STDAFX__ #define __STDAFX__ 中身 #endif とする。 __・・・ __ をヘッダーごとに変える。
>>270 > stdafxが多重インクルードされるから。
ちがうよ。
>>271 いろんなところから呼び出されるんだから多重インクルードだろ。
別にインクルードがループしてるって意味で言ったんじゃないぞ?
みなさんありがとうございます。
>>270 の方法でやりましたが、同様のエラーが出ました。
#pragma onceを消して#ifdefを書くんですよね?
>>269 複数のクラスから参照される変数なんですが、
使用するすべてのコードで書くんでしょうか?
>>274 ヘッダには定義ではなく宣言を書く。
extern int a; // 宣言
int a; // 定義
>>274 エラー内容(表示される物)書いてくれるのが一番助かるんだが。
>>250 ようやく納得しました.確かに
A r = A();
の書き方は,8.5.7によりvalue-initializedになり,Aにユーザ定義のコンストラクタが
ないので,8.5.5によりvalue-initializeによってメンバ全てに対するvalue-initializeが保証されて,
結果PODメンバに対してzero-initializeが保証されるわけですね.
ありがとうございました.
>>274 ちなみに#ifdefじゃなくて#ifndef
つまり
__STDAFX__が定義されてなかったら
{
__STDAFX__を定義する
中身
}(#endif)
というので多重インクルードを防げる。
#pragmaはVCオンリーなのであんまり使わない方がいい。
で,補足として
#include <iostream>
struct A{ char a, b, c, d; };
struct B{
B(){}
char a, b, c, d;
};
int main(int argc, char *argv[]){
A a = A();
std::cout << int(a.a) << std::endl;
std::cout << int(a.b) << std::endl;
std::cout << int(a.c) << std::endl;
std::cout << int(a.d) << std::endl;
B b = B();
std::cout << int(b.a) << std::endl;
std::cout << int(b.b) << std::endl;
std::cout << int(b.c) << std::endl;
std::cout << int(b.d) << std::endl;
return 0;
}
上のコードのようなしょうもない違いが生じるわけですねw.
(VC++7.1では違いは出ませんが,gcc3.2.2では違いが生じます)
Aが
>>250 に対応し,Bが
>>237 に対応すると.
>>279 stdafx自体VCオンリーな感じが(笑)
>>279 つーかVC使ってるんなら
VCの拡張だって理解した上で
#pragma once使ったほうが効率的。
>>277 はじめに
A r=A();
を持ち出したのは俺だがあってるみたいでよかった。
俺も他人がこの方法で初期化してるのみて「できるの?」
って思ってたから・・・
じゃあ、A()が0初期化保証されるならBCCは違反って事?
>>279 #pragmaがVCオンリーってのはネタ?
>>281 関係ないのはわかってるが
#ifndefじゃなくちゃいけないのに#ifdefって書いてあったから。
質問はageで、と以前言われたもので。すいません。 エラー内容は、 error LNK2005: "int TARGET_DAY" (?TARGET_DAY@@3HA) は既に AnalysisManager.obj で定義されています。 というものです。 このほかにも同様のエラー、「グローバル変数XXは既にXXX.objで定義されています」と出ます。 コンソールアプリなんですが、このTARGET_DAYとかをコマンドライン引数から入力してもらって、 その値によって処理を変えようと思うので、グローバル変数にしたいんですが。 グローバル変数をコード内に書くとするなら、その変数を使用する全てのクラスのコード内に記述するんでしょうか?
>>286 #pragma once
ってVCでしかみなかったからオンリーだと思ってたよ・・・
違うんだね。
でも、VC以外では使わない方がいいってのはあってるでしょ?
>>290 あ。
すいません。
つまり宣言は複数用意すると。宣言は使用するクラスのヘッダ内全てで書いてもいいんですか?
それで定義をメインクラスのグローバルスコープの位置でするって感じですかね?
>>285 280をgccで実行してもらえれば分かりますが,A()の書き方で
0初期化保証されるのはAにユーザ定義のコンストラクタを全く定義していないときに
限られますのでご注意を.
ユーザ定義のコンストラクタを定義していない場合の話なら,
当然BCCは違反ってことになりますね.
>>292 ヘッダファイルは一個に見えてもincludeしたすべてのモジュールに
コンパイル時につなぎ合わされて解釈されるの。
宣言は使用するクラスのヘッダすべてがincludeする別のヘッダに一個かけばいい。
定義はメインクラスんとこでいいよ。
疲れた('A`)
>>294 #pragma onceって書くのめんどくさかったから・・・
>>295 あーなるほど!良くわかりました。ありがとうございます。
疲れさせてすいませんでした・・・。
>>296 いや、それは分かるけど今回は全然意味変わってんじゃん。
JavaScriptをJavaと書くようなもんだよ。
ガイセキ/2計算しろ。5分あれば誰でも書ける。
#ifndef __Hoge_H__ なんてのをなんでいちいちプログラマが考えにゃならんねん。 #pragma onceにして、プログラマの手から離れたほうがいいに決まってる。 対応してない環境で開発しなきゃいけない状況に陥らない限り、俺は絶対#pragma once使うぞ。
またインクルードガードに予約された名前だよ。 知らない奴に教えるときくらい気をつけて欲しいもんだな。
include <iostream> #include <mah.h> #define vector00 1,2,3 #define vector01 4,5,6 namespace mytriangle{ class Vect3D{ double x, y, z; public: Vect3D(){} Vect3D(double const&, double const &, double const&); friend Vect3D OuterProducts (Vect3D const &,Vect3D const &); inline double Abs3D(){ return sqrt(x * x + y * y + z * z); } Vect3D &operator=(Vect3D &V){ x = V.x; y=V.y; z=V.z; } friend double Square(Vect3D const &, Vect3D const &); }; Vect3D::Vect3D(double const & X, double const & Y , double const &Z) :x(X),y(Y),z(Z){} inlinedouble Det2(double const & a, double const &b, double const &c, double const &d){ return a * d - b * c;} inline Vect3D OuterProducts(Vect3D const &v1,Vect3D const &v2 ){ return Vect3D( Det2(v1.y, v1.z, v2.y, v2.z),-Det2(v1.x, v1.z, v2.x, v2.z),Det2(v1.x, v1.y, v2.x, v2.y));} inline double Square(Vect3D const &v1, Vect3D const &v2 ){ return OuterProducts(v1, v2).Abs3D()/2.;} } int main(){ using namespace mytriangle; Vect3D u(vector00), v(vector01); std::cerr << Square(u,v) <<'\n';}
ごめん inlinedouble -> inline double あと、main のなかで最後に 1でも返しといて。
>>300 VC.netにはマクロがついてる。
自動で#ifndef、#define、#endifしてくれる。
名前はファイル名で。
今頃インクルードガードごときで言い争いですか。アホですね。
>>305 どこが言い争いにみえたのやら・・・
誰と誰がどういう意見で争ってるのか、言ってみ(w
305と306が言い争っているかどうかに付いて争っていると見た!。
翻訳単位を意識させるC++はダサい
310 :
デフォルトの名無しさん :04/05/16 01:07
いうまでもない事だが、100%使いこなしている上で批判しているわけだが。
312 :
デフォルトの名無しさん :04/05/16 01:14
314 :
デフォルトの名無しさん :04/05/16 01:41
必死だな (プププ
315 :
デフォルトの名無しさん :04/05/16 02:43
答えてるヤシは、c++暦どれくらいなんだ?(;´Д`) さすがに1年以下は居ないだろうな・・・・・・(゚Д゚;)
>>315 コンパイル単位なんてC++に限らんが、C++始めたのはつい最近だな。10年くらいか。
よくVC++7.1のANSI準拠度は高いと言われてるけど、 VC++7.1付属のSTLの出来はどう?(6.0ではいろいろ問題があったけど。) あえてC++を使いこなしてる人のこのスレで意見を聞きたい。
次のコードがコンパイルできないんですけど、どこが悪いんでしょうか? コンパイラはMinGWのgcc 3.3.3です。 ソース> #include <iostream> using namespace std; class Test { public: template <class T> Test& operator<<(const T& rhs) { cout << rhs; return *this; } }; int main() { Test t; t << 100 << std::endl; return 0; } エラーメッセージ> t120.cpp:19: error: no match for 'operator<<' in '(&t)->Test::operator<< [with T = int]((&100)) << std::endl'
>>318 std::endlの定義を考えてみて。
320 :
デフォルトの名無しさん :04/05/16 19:10
仮想メンバ関数を定義したクラスAを継承したクラスBと、さらにクラスBを継承したクラスCがあったとします。 struct A { virtual void Foo1(void) { std::cout << "A" << std::endl; } void Foo2(void) { Foo1(); } }; struct B : public A { void Foo1(void) { std::cout << "B" << std::endl; } }; struct C : public B { void Foo1(void) { std::cout << "C" << std::endl; B::Foo2(); } }; int main( int argc, char *argv[] ) { struct C test; test.Foo1(); return 0; } これを実行したときに、「CCCCCCCC・・・」と永遠に続いてしまいます。 test.Foo1()を実行ときに「CB」と表示されて終了して欲しいのですが、何か良い手段はないでしょうか? (B::Foo2()を実行したときに B::Foo1() が呼び出されて欲しい。) ちなみに、「B::Foo2()」を「B *cls = (B *)this; cls->Foo2();」にしても結果は同じでした。
C::Foo1() のなかで呼んでいる B::Foo2() は B::Foo1() の間違いでは?
>>320 キャストしても、Foo1へのポインタは
オブジェクト自身に C のvTblへのポインタが含まれてるので
C::Foo1が呼ばれる。
あー、ごめん。Aのインタフェースを通すのか。
324 :
デフォルトの名無しさん :04/05/16 19:18
>>320 struct Bに
void Foo2(void) { std::cout << "B" << std::endl; }
を追加する。
>>320 > test.Foo1()を実行ときに「CB」と表示されて終了して欲しい
要求がそれだけなら、
void C::Foo1(void) { std::cout << "C" << std::endl; B::Foo1(); }
とか、
void C::Foo1(void) { std::cout << "CB" << std::endl; }
とか、
やりかたはいくらでもある。
実はGTKでATLのようなテンプレートライブラリを勉強がてらに作っていたんですが、 イベントを親クラスにチェーンする機能(ATLのCHAIN_MSG_MAP())を作ろうとしたときに 親クラスのイベントマップをうまく呼び出せなかったんですよね。 (CEventImpl + CWidget -> CWindowImpl -> CBaseWindow -> CFrameWindowという継承を 行った場合、CFrameWindowからCBaseWindowのイベントマップを呼びたかった) でも、なんかCEventImplの実装が間違っているような気もするので別の方法を模索してみて諦めます。
テンプレートで質問なんですが、 template<class Type, int i> void func(){...] みたいにテンプレートの引数のところにint iというような記述を する必要があるときってどんなときですかね? 普通に関数の仮引数にしないのはどういう意図なんでしょうか。
>>327 静的な定数として使うとき。
たとえばその関数内で char a[i] とか、 std::bitset<i> とか。
すいません、どうもわからんのですが、関数の仮引数に constつけるのとは違うのでしょうか? できれば例か何かあげてもらえないですかね。
あ、そういうことですか・・というか const int size = 5; char a[size]; はできますが、sizeが関数の仮引数だとだめなんですね・・・なんでだろ。
コンパイル時定数
>>322 たいていの処理系だと、自動変数はスタックにとる。
size がコンパイル時定数なら自動変数のアドレスはすべて
スタックフレームポインタの相対アドレスとして求まるが、
size が可変だと自動変数のアドレスを実行時に全部計算する
必要があって、効率悪くなる。
まぁ gcc みたいに独自拡張で size が可変でも OK っつー
処理系もあるし、alloca() 使えばスタック上に可変サイズ
のデータ領域とれるが、C++ 的には
1) コンパイル時に確定できるならテンプレート引数で
2) 実行時に決まるなら std::vector
というのが推奨。
定数とかの定義って #define 使ってますか? 何か、名前空間を汚してイヤンな感じがするんですけど、 どうするのがスマートなんですかねぇ? 現在は、 namespace IJIRUNA { const int hoge = 123; const char * const p = "ふがふが"; }; とかやってるんですが、何かマズいことはありますか? ほとんどの場合、即値に展開されると思うのですが。。。
クラスのメンバじゃダメなの?
enum fuck
欠陥コンパイラとはVisual Studio のことか?
>>335 ヘッダでポインタを初期化すると、
インクルードするソースごとに文字列リソースが作成されるのでは?
>>335 の場合、"ふがふが"がソースの数だけ実行バイナリに埋め込まれてしまうはず。
VCなどの最適化処理では対処しきれないと思う。
ソースで宣言している分には問題なし。
補足: あるソースでポインタpを使ってなければ、そのソースの分に関しては "ふがふが"文字列リソースは埋め込まれない。
いつぞやのバカか?
レスどうも。どうやら、ケース・バイ・ケースで一概に言えないようですな。
>>336 なんか、ちと大げさな気が。。。
static const なメンバならいいんですかねぇ?
>>337 enumって定数だけだったやうな(ry
>>341 ヘッダには、もちろんexternつけますよ。即値で埋め込んでくれたほうが
速度的に良さそうな気がしますが、あまりにも長い文字列は、ファイルから読み込むか
プールしとかないとだめでしょうね。
真っ当なコンパイラなら文字列リテラルは使い回すのがディフォルトで、 使い回さないオプションがついていると思うのだが。
347 :
デフォルトの名無しさん :04/05/17 22:04
>>346 真っ当なって時点からただの戯れ言に成り下がったな
授業中ではなかったですw ↓のエラー(ミス)がわからないのですが、詳しい人助けてくださいm(__)m #include <iostream,h> #include <math,h> void main(void){ doble hen-a,hen-b,hen-c,; doble t,menseki cin>> a >> b >> c ; if(a+b>c & b+c>a & c+a>b){ t=(a+b+c)/2 s=sqrt((t-a)(t-b)(t-c)); } cout>>menseki; あと、マイクロソフトビジュアルc++はどのように入手できるのですか? 手助けお願いします。
>>348 .h> -> >
void main -> int main
doble -> double
& -> &&
)( -> ) * (
店で買う
>>348 Visual Studio C++ .net でも大体同じことできるよ。
>>349 >>350 さん、ありがとうございます!
>Visual Studio C++ .net はどのように手に入れるんですか?
質問おおくてすみません。
>>346 使いまわしが可能なのは、あくまでもソース単位(中間ファイル単位)だと思われ。
>>352 いや、VCのオプションだと文字列は一カ所に追いやられる。
それを参照する。
>>351 学生ならアカデミック版がやすくていい。
いろいろとありがとうございます
>>352 文字列等のコンストラクタを伴わない定数は、
どのように最適化するかはコンパイラベンダの実装に任されている。
一つになるか複数になってしまうかはツール依存だったと思う。
const定数使った方がデバックが楽なので、個人的にはconst定数の利用を御勧めする。
359 :
デフォルトの名無しさん :04/05/18 01:17
要はバグを出さなければいいわけか。
360 :
デフォルトの名無しさん :04/05/18 01:30
>>351 winnyで出回ってるよ
買うやつはアフォ
亀レスになりますが >319 なんとかなりました。 ostreamファイルでのendlの定義が namespace std { (略) template<typename _CharT, typename _Traits> basic_ostream<_CharT, _Traits>& endl(basic_ostream<_CharT, _Traits>& __os) { return flush(__os.put(__os.widen('\n'))); } (略) } となっているので、ようするに _CharT と _Traits の型が決められなかったのが原因でした。
362 :
デフォルトの名無しさん :04/05/18 01:36
int hogehoge::hoge(foo* &bar) { // どうのこうの } ってメンバのfoo* &bar ってなんですか?
364 :
デフォルトの名無しさん :04/05/18 01:54
日本語は苦手なのねw
365 :
デフォルトの名無しさん :04/05/18 02:07
C++用のindentのようなツールはないでしょうか。 きちゃないソースをメンテすることになって泣きそうです。 OSはSolaris、linuxです。
astyleでも応援しる。
368 :
デフォルトの名無しさん :04/05/18 02:55
369 :
デフォルトの名無しさん :04/05/18 03:05
pthreadをクラスのメンバ関数から生成した場合、スコープはどこまでに なるんでしょうか?そのクラスのメンバ関数をpthreadで生成したスレッド 関数で加工できますか?それともポインタで渡してしまえば、何でも Cのように書き換えられちゃったりしますか?
>>369 >pthreadをクラスのメンバ関数から生成した場合、スコープはどこまでになるんでしょうか?
pthreadは何を入れる変数or関数なのか?
>そのクラスのメンバ関数をpthreadで生成したスレッド関数で加工できますか?
メンバ変数の誤り?加工じゃなくて呼び出し?
どっちにしてもそのスレッド関数とやらがfriendなら自由じゃない?
>それともポインタで渡してしまえば、何でもCのように書き換えられちゃったりしますか?
>>368 入れればいいじゃん。
どっちにしろなんかツールを新規導入しようとしてるんでしょ。
372 :
デフォルトの名無しさん :04/05/18 11:59
std::string の find() は、 一般的に高速と言われているBM法などに比べて パフォーマンスはどのようなもんなんでしょう? 高速を目指すなら独自実装が必要なんでしょうか?
STLは実装が違うから自分でソースみれば?
短い文字列なら単純に検索する方が早いことも多々あるが。
女子供じゃあるまいしstd/stlになんて頼るなよ。 自作の超チューニングされたコードにかなうものなし。
>>375 俺も結構自作派。String,Vector、スタックあたりは自作。
>>375 |
|
∩___∩ |
| ノ _, ,_ ヽ (( |
/ ● ● | (=)
| ( _●_) ミ _ (⌒) J ))
彡、 |∪| ノ
⊂⌒ヽ / ヽノ ヽ /⌒つ
\ ヽ / ヽ /
\_,,ノ |、_ノ
378 :
デフォルトの名無しさん :04/05/18 17:01
char chbuff[] = "ORIENT ENTER DENTOO"; この文字列の中にあるENTという文字が幾つあるか検索したいんだけど、 どうすれば良いんでしょうか。 strchrを使って上手く数えられないのかな? ポインタを動かして読み飛ばしとかってのも考えたんだけど、 上手くいかないっぽ。 何か良い手を教えてもらえませんか?
人様が書いたライブラリっていうのは、あくまでも書いた人にとって都合のよいライブラリ。 とりあえず使ってみるのはいいけど、高速化/コードサイズ/使いやすさとか追求すると結局最後 は自分で作ることになるよ。もちろん公開されてるライブラリソースは参考にするとしても。
C++っていうのは、あくまでもBjarne Stroustrupにとって都合のよい言語。 とりあえず使ってみるのはいいけど、高速化/コードサイズ/使いやすさとか追求すると結局最後 は自分で作ることになるよ。
>>378 strstr() でぐるぐるすれば簡単にできるっしょ。
C++ らしくはないけども。
382 :
デフォルトの名無しさん :04/05/18 17:14
>>380 禿同。最近はライブラリだけじゃ物足りなくて
コンパイラにも手を入れ始めるようになったよ。
先週はデフォルト最上位クラスobject、
例外の最上位クラスexceptionを追加して
すべてのインスタンスを統一的に
扱えるようになってもうウハウハ。
☆★☆★★☆ラッキーシリ☆★★☆★☆ ⊂⊃ .☆.。.:*・゚ ∧_∧. / ( ´∀`)/ このシリに出会ったあなたは超桃尻。 /, つ 近々便秘が舞い込んでくることでしょう。 (_(_, ) しし' ☆★☆★★☆ラッキーシリ☆★★☆★☆
384 :
デフォルトの名無しさん :04/05/18 17:26
>>381 ありがとうございました。
そんな関数頭になかった><
ガッツり出てきそうです。thx
>>384 大丈夫、キャリア10年以上、年齢40以上の博士号持ってる自称SEでさえ知らなかったから。
386 :
デフォルトの名無しさん :04/05/19 01:28
int i = 1; をstd::string str;に 入れたい。 str = "1"; をiをつかってやるとどうなる?
388 :
デフォルトの名無しさん :04/05/19 01:33
iが [1-9]\d* だったらどうするんだよ
>>386 boost::lexical__cast
390 :
デフォルトの名無しさん :04/05/19 01:39
あんな駄作ライブラリ入れなくない
すまそん 388さんのエクスプレッションの意味って なんでつか?
入れなくなくなくなくなくなーい
と、失敗作が申しております。
394 :
デフォルトの名無しさん :04/05/19 01:47
このスレ的には標準ライブラリで
s/入れなくない/入れなくもない/
398 :
デフォルトの名無しさん :04/05/19 02:22
C++は面倒だね perlなら sprintf("%d",$i); でいいんだけど・・・
定期的に沸いてくるね、自作厨が。
>>398 じゃあ、perlで日本語つかるってとこみせてみろよ
403 :
デフォルトの名無しさん :04/05/19 08:09
classAでclassBを作った時にclassB内でclassAへのポインタを得るにはどうしたらいいですか? classBからclassAのメンバ変数を操作したいんです
#include <sstream> #include <string> std::ostringstream oss; int i = 1; oss << i; std::string str = oss.str();
>>403 class B
{
public: B(class A* ref);
};
class A
{
B b_;
void func() { b_ = new B(this); }
};
メンバ変数をいじりたいならfriendなりも必要な気がするが。
なにくだらねーこといってやがる
408 :
デフォルトの名無しさん :04/05/19 11:16
オブジェクトを下の様な方法で解放する場合、何か問題が起こる場合はあるでしょうか? (実際にはユーザー定義のデストラクタがあります) 抽象クラスAから派生した複数の型のクラスを格納して一括して解放したいのですが‥‥ class A { public: virtual void Delete() = 0; }; class B : public A { public: virtual void Delete() { delete this; } }; main() { B *b = new B; A *a = b; a->Delete(); }
>>409 仮想デストラクタをAに定義してれば普通にAのポインタでdeleteすれば
派生もokだが
>>409 デストラクタをvirtualに、ではいかんのか?
>>410-411 そーいえばそんなものがあったなぁ‥‥
アリガトン
ミ
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄」 ノ∩
―――――――――――――‐┬┘ ⊂ ヽ
| /( 。A。 )っ あらよっと
____.____ | U ∨ ∨
| | | |
とあるソースを見ていたら、 namespace A { // ここに関数やクラスなどの宣言がずらずらと } using namespace A; というヘッダファイルがありました。 名前空間の終わりの直後にusing namespaceをしては名前空間の意味がないと思うのですが、何か意味があるのでしょうか?
>>413 たぶん、無名の名前空間ってのを知らない奴が書いたのでは?
>>413 名前空間で囲っておけば名前が衝突しても簡単に回避できるからだろう。
using指令を使ったところで名前空間の意味がなくなるわけではない。
>>415 そうなんですか。
知りませんでした。
ありがとうございました。
>>417 名前なし名前空間は普通ヘッダファイルでは使わないだろ。
翻訳単位ごとに別の名前が宣言されるからな。
>>418 あ、ヘッダファイルか。そうだな、勘違いしてたよ。
じゃあ
>>413 の答えは、「意味なし」は言い過ぎにしても、「台無し」が正解じゃないのか?
いや415でいいじゃん。何かしら意味があったわけだし、 413もそれを知ることができたわけだし。
てきとーに作ってたら名前がかち合ったのでnamespaceでくくった。 しかしすでにコード書いた部分をnamespaceを明示するように修正するのは面倒。 なのでついでにusingした。
そうですか
↓ヘッダでusing namespace std するよ派とするなよ派の喧嘩
│ │ │ ∧_∧ ↓ ( ・ω・ ) ■p⊂ と ) (_(_ろ
台無しっつうより能無しだな
∧_∧ ( ・ω・ ) ■b⊂ と ) | (_(_ろ | | | ↓
ATL や、WTL はデフォでそうなっているわけだが。
インテリセンスの為だけに、名前空間を使ったとか?
>>428 なんか誤解してないか?
名前空間の特徴のうち、
・Koenigの自動照合
・リンク時のシンボルレベルでの衝突の回避
・(名前空間内ではなくて)ユーザーコードの修正によるコンパイル時点での衝突の回避
は、using namespaceをするしないに関わらず機能するぞ。
430 :
デフォルトの名無しさん :04/05/19 21:00
今までVBを使ってきたのですが、いい加減乗り換えようと最近C++の勉強を始めました。 そこで現在、開発環境をどれにするかで悩んでいます。 条件としては、 ・ 言語: C++ (当たり前か・・・) ・ フリーソフトウェア(≒オープンソース)である。 ・ RAD環境が整っており、簡単にグラフィカルなアプリが作れる ・ 環境が日本語 ・ WindowsでもX Window Systemでも動作可能 ・ インターフェースは Winなら普通のLook&Feel Xなら(できれば)GTK+ WideStudioも検討しましたが、ランタイムが重過ぎたり、 UIが独自で扱いにくい、そして別スレでの評判(作者云々)で できれば検討から外したいと思っています。 無理な話だとは思いますが、このような環境をご存知の方居られましたら ぜひご教授願います。
そうですね。まず・・・環境うんぬんの前に、C++が本当に扱うことができるようになるのか、じっくりと検討してみるのがよろしいと思います。 あと、そんな環境ありません。あなたが本当にやる気があるのなら、フリーウェアの項は撤廃すべきです。
そんな都合のいいものがあるわけ内だろ。
>> あと、そんな環境ありません。
確かに無理難題だったかもしれません。条件を厳しくし過ぎてしまいました。
>> C++が本当に扱うことができるようになるのか、じっくりと検討してみるのがよろしいと思います。
とりあえず、
http://www.asahi-net.or.jp/~yf8k-kbys/cpp0.html には目を通し、大枠では理解できたかと感じました。
目を通しただけで、実習としてのコーディングは全てざっと読んでから、と考えていました。
そして大分(内容の6割くらいか?)理解できたと感じたので、コーディングのための環境を揃えようと思い立ちました。
しかし、他のプログラムのソースを見ると、どうやらテキストベースとグラフィックベースのプログラミングでは、
随分差があるように感じました。多分これは間違いではないと思います。
それに、私はテキストベースのソフトを作るつもりは当分無いので、できることなら初めからGUIのやり方に慣れよう、
と思ったわけです。
また私は現在、できる・できないの問題でなく、「できる所までやってみよう」という趣旨のもと、言語の学習を進めています。
どうせ趣味としてのプログラミングで、納期なんて物も無いですから、気楽に学習しています。
>> あなたが本当にやる気があるのなら、フリーウェアの項は撤廃すべきです。
意図が掴めなかったので、これについての詳しい説明をお願いします。
VBのぬるま湯に長く浸かっておりましたので、皆様には間の抜けた質問をしてしまうかもしれませんが、
頑張って慣れてゆこうと思いますので、どうか宜しくお願い致します。
Java か C# のほうがいいんじゃないの? C++ で GUI なんて、C++そのものの勉強、プラットフォームの勉強の後じゃないと理解できないと思う。 少なくとも、RADが期待できる言語ではない。
>>434 Javaは重いとか、Webアプリ向けでスタンドアロンには向かないという
印象が強いのですが、じっさいのところどうなんでしょう。
>>435 いや、そんなところでワガママ言ってるようじゃ
Windows でも X でもって所でどうしようもなくなる気が。
言語的にはスタンドアロンに向かないことはない。
誰も使ってないだけで。
C++を勉強し始めて2週間です。 ソートプログラムを書いていて疑問に思ったんですが、 バブルソートとクイックソートとバブルソートなどは 実際の現場!?ではどのように使い分けているのでしょうか? ・プログラムのしやすさ ・使用メモリの大きさ ・速さ などを考えたんですが、実際はどうなんでしょうか?
基本はstd::sortとstd::stable_sort。場合によってはstd::map系。 いちいちソートなんぞ書いてられるか。 自分で書くとしたらcomb sortぐらい。
>>438 そんなことをつらつら考えるより、ライブラリを使った方が早い。
特殊用途以外では気にすることもない。
Boostって完全に現行標準ライブラリとは別の付加機能になってる のでしょうか?それとも、もしかして将来、標準ライブラリの一部と 取って代わるようなこともありえるのですか?
将来のことは誰にも分からない。
>>431 ,432,434
要するに、C++でRADというのは実質無理なのでしょうか?
私がRADにこだわるのは、便利で手軽、保守が簡単であるという点と、なにより
ネット上に存在する多くの資料を見て嫌気が差したからでもあります。
私のC++を学習しようとする理由のひとつが、「Windows以外でも走らせたい」ということであり、
もちろんこれはJavaでもできますが、マイナーであるし、Java Start(だったっけ?) という
Sun版のJVMについていたサンプルのUIに良い印象を受けなかったこともあり、良い印象を持っていません。
それに、バイトコードを実行するので、性能も犠牲になります。
ですから、折角なら前々から考えていたC系言語をやってみよう、と考えたのです。
宜しければ、この際RADには拘らないので、C++でのGUIプログラミングを始めるにあたって
分かり易いサイト、もしくは書籍等を紹介して頂けないでしょうか。
もちろん、C++の基礎に関しては、分かり易い情報を多く見つけることが出来ましたので、
そこら辺の知識が前提となっていても構わないです。
ネット上の資料は、難しいか、VC++関係のものばかりで入門用の情報が見つかりませんでした。
何度もご迷惑をお掛けする事になってしまいましたが、どうかよろしくお願いします。
>>435 平仮名で送信してしまった・・・恥ずかしい
C++ Builderとか
445 :
デフォルトの名無しさん :04/05/19 22:48
RADって必要? っていうか、RADってmodelとviewなんかぐちゃぐちゃに書くやつが 多くていやなんですが・・・ VC++みたく、DOC/VIEWで完全に切り分けて、初心者を除外して欲しい 仕事しずらいったらありゃしない
GUIだけならあってもいいけどな。楽だし。
>>443 クロスプラットフォームのライブラリ使うにはそれなりのC++の知識が必要。
とりあえずウインドウズでGUIの基本を学ぼう。
まずMSのサイトでC++のコンパイラを落としてきて、プラットフォームSDKをインストールしましょう。
その次に「猫でもわかるプログラミング」でググって、出てきたページを1からやりましょ。リソースエディタなんかなくても手書きで十分。
あと、VisualStudioのMFCならダイアログエディタで作ったダイアログをクラスに落とすことができるから、いいRADになると思うよ。
>>443 「プログラミング言語C++ 3版」
これを書店でつらつらと眺め、全部理解できそうだと思ったら買って勉強する。
思いとどまるなら思いとどまる。
Webサイトの解説を読んで分かった気になっても、それは気持ちだけの話だからね。
>>430 >>443 俺もそう思ってwxWindowsを使ってる。RAD環境も(一応)ある。
恐らくこいつで不満は出ないと思う。
聞きたいことがあればwxWindowsスレで聞いてくれたら教えてあげるかも。
451 :
デフォルトの名無しさん :04/05/20 01:02
Qt devel + Kdevelop glade + anjuta kylix3 などと言ってみる。
なんで勉強したいのにRADよ 覚えられないだろ
453 :
デフォルトの名無しさん :04/05/20 01:58
可変長引数を処理する方法を教えてください。m(__)m
>441
>Will the Boost.org libraries become part of the next C++ Standard?
>
>Some might, someday, but that is up to the standards committee.
>Committee members who also participate in Boost will definitely be
> proposing at least some Boost libraries for standardization.
>
>Libraries which are "existing practice" are most likely to be accepted
> by the C++ committee for future standardization. Having a library
> accepted by Boost is one way to establish existing practice.
http://www.boost.org/more/faq.htm より引用してみたが、質問の意味が違うのか。
基本的に標準ライブラリに「取って代わる」ようなものではない(一部あるかも知れないが)。
ただし追加として標準ライブラリに採用される可能性はもちろんある。
>>443 やー、まー、なんつーか。
多分あんたがVBで作ったアプリよりJavaのバイトコードをJIT搭載環境で動かした方がずっと速いから。
いきなり完璧なソフトなんてつくれっこないんだし、性能なんてもっとも難易度の高い分野のひとつ
なんだから考慮するだけ無駄だっての。
だいたい、基礎を分かった気になってるようだけど、それなら何で入門サイトなんか聞きたがるの?
開発環境で日本語を要求してる当たり、英語の資料は全部難しいんだろうね。
なんか、学問に王道を要求した王様のようだな。 寧ろPerlでcgiでも作ってみたら? 制約された条件で、如何に使いやすいGUIを提供できるかいい勉強になるよ。
>>443 (゚д゚)ハァ?
あなたは、何か勘違いしてませんか?このスレの住人はガッコの先生じゃ
ありませんよ。自分で歩ける様になってから尋ねて来てくださいね。
459 :
デフォルトの名無しさん :04/05/20 07:32
.datファイルで保存した20x2のテーブルを 読み込みたいのですけど、、 #include <stdio.h> #include <math.h> #define M 21 #define N 2 void main(void) { int V, T; int i; int array[M][N]; for(i=0, i<21, i++);{ FILE *ifp; /* declare pointers for in and out */ ifp = fopen("in.dat", "r"); fscanf(ifp, "%d %d", &V, &T); printf("%d %d", array[i]); }} これで駄目だったので、どこが悪いですか?
ごめんなさい。21x2のテーブルでした。
>>459 >これで駄目だったので、どこが悪いですか?
ちゃんと勉強してないのが悪い。
質問の仕方が悪い。
つーか、そもそもCスレで聞くべきだろ
arrayにはどこで代入してるんだよ。おめでてーな。
>>461-464 お前ら糞だな。ぐちゃくちゃ書き込むぐらいなら、一言でちゃんとと教えてやれ。
それと
>>462 C++はCの仕様を包含してることを忘れるなアホ。
>>465 といいながら一言で教えてない罠
あとCを包含してるといってCの話題をC++スレでやったら
Cスレと分かれてる意義が薄れ、話題が分散してしまう。
ということで
>>462 に同意
>>465 C++にはstdio.hもmath.hもないが
つーか
>>465 が質問者だろ。教えてくれないからキレてるだけだ。
470 :
デフォルトの名無しさん :04/05/20 13:37
Cスレに相応しい質問はすべて、C++スレにおいても相応しい質問なのである。
だから答えないお前らはアホなのである。基地外なのである。ゴミ以下なのである。
ていうか俺の質問には絶対に答えなくてはならない、これは全宇宙的な戒律なのである。
って、さっき
>>465 が部屋の隅っこで呟いてたよ。
>>467 >C++にはstdio.hもmath.hもないが
アホかお前?
>>471 お前がアホ。
つうか、もうヤメレ。
はい、次。
わかった、おまえらアホだ。 しかし俺のほうがもっとアホだ アホって誉め言葉でしょ
画面にHello World!と表示するプログラム作って
DISPLAY "Hello World!"
>>471 cstdio のファイルの中身すら見たことない超初心者の
>>467 をいじめてやるなよ。
C++では stdio.h は絶対ないことは間違いない。
うすかわの表面しか理解してないことに気づきました。 首吊ってきます。
481 :
デフォルトの名無しさん :04/05/20 14:49
恥さらしあげ
>>447 cstdioの中身が
namespace std {
#include <stdio.h>
}
とかになってるって事か?
規格と実装は(略
483 :
デフォルトの名無しさん :04/05/20 14:56
<iostream>しか使わないのでのstdio.h は消してました。 通りでコンパイルできなかった理由が初めてわかりました。
operator<<=, って演算子があるけど、 こいつを文字列に対して、例えば以下のように多重定義する。 wstring & operator<<=( wstring & lhs, string const & rhs ) { vector< wchar_t > buf; buf.reserve( mbstowcs( 0, rhs.c_str(), MB_CUR_MAX ) ); mbstowcs( &b[0], rhs.c_str(), MB_CUR_MAX ); wstring( b.begin(), b.end() ).swap( lhs ); return lhs; } すると、ナロー文字列をワイド文字列に変換する際に以下のようにかける。 wide <<= narrow; とても C++ らしいと思うのだがどうだろう?
ナロー文字列なんて言葉を使うな。
なんだと、んナロー
>>488 optional
しかも、厳密にはcstdioがstdio.hを取り込むのではなく、
stdio.hで各関数をグローバルにusing std::printf;みたいな事するようになってる。
490 :
デフォルトの名無しさん :04/05/20 16:00
さらし上げ
>>487 アホの活け作り。Cの処理系なしに、pure C++だけで動く処理系あれば言ってみろ。糞が
すり替え一名様ご案内〜
>>488 オプションであってもそれが使えなければCとの互換性は保てない。
DではなくてあくまでもよりよいCがC++だから。
なんで規格の話してる奴に処理系の具体例を求めているんだろう(´・ω・`)
なんで処理系の話をしてるのに勝手に規格の話を持ち出してんの?
だから結論はこれだろ。 > Cスレに相応しい質問はすべて、C++スレにおいても相応しい質問なのである。 > だから答えないお前らはアホなのである。基地外なのである。ゴミ以下なのである。 > ていうか俺の質問には絶対に答えなくてはならない、これは全宇宙的な戒律なのである。
規格はstdio.hをインクルードするなとはなってないよ。
>>492 あくまでもよりよいCがC++だから。
それはお前の中だけだろう。
Cと矛盾する仕様もいくつか含んでいるし
C99に至っては完全に枝分かれしたような状態なのに。
C++の要件にCとの互換性があるなんて初耳だぞ。
C++ソースにおいてがstdio.hを直接includeして何か問題あるようなら、 warningなりerrorなりを出すべきだな。 簡単にできるはずだが、現実はそうなっていない。
>>499 だれもそんな事は言っていない。
C++標準以外のヘッダやライブラリは使えないとでもいうつもりか?
>それはお前の中だけだろう。 お前何言ってる? C++はよりよいCを目指して作られた処理系ってこと知らないのか?
>>500 アフォかお前。
Cの標準ライブラリをincludeしたときにwarning出すぐらい簡単だと
言ってるんだよ。自前のファイルのincludeをハネル必要なんかないだろうが。
>>501 目指して作られた事と、実際にC++がCのスーパーセットであることに相関関係はないぞ。
>>502 C++の処理系がCのヘッダファイルを「わざわざ」認識して警告する必要があるのか?
アフォとか言う前に、プリプロセッサの仕事を良く考え直してみろ。
取り込んだヘッダがC++の文法と矛盾していなければ問題なくコンパイルできて何が悪い?
>目指して作られた事と、実際にC++がCのスーパーセットであることに相関関係はないぞ。 頭悪いなお前。言ってることのロジックが成り立ってないこともわからんのか?
>取り込んだヘッダがC++の文法と矛盾していなければ問題なくコンパイルできて何が悪い? 全く問題ないよ。だから使うことに何の問題もない。 お前、考えてから書き込めや。
>>504 >C++の処理系がCのヘッダファイルを「わざわざ」認識して警告する必要があるのか?
全くないよ。
すげぇ、まだやってたんだ。 お前ら、全員馬鹿だってば。 いいかんげんにヤメレ!
基本的にC++はCとは基本的に別の言語であって、
C++の言語仕様には、Cとの多くの共通点があるだけ。
>>507 使う事に問題があるなんて誰も言ってないだろうが。
Cのstdio.hを使うのならそれはC++スレの範疇ではないと言ってるだけだ。
C++は決してCを包括しているわけではない。
511 :
デフォルトの名無しさん :04/05/20 16:39
だれか、これは何をしたいのか教えてくれ。 何でやたらキャストばかり・・・ int main(){ int y[] = {1,2,3,4,5,6,7,8,9,10}; int *ip; long L1; long L2; L1 = (long)y; cin >> L2; ip = (int*)(L1 + (L2 * sizeof(int))); printf("%d\n",*ip); return 0; }
512 :
デフォルトの名無しさん :04/05/20 16:40
あと、sizeof(int)をかける理由はいったいなに?
いや違う。 C++はCを包括している。
>>510 基本的にC++はCの完全なるスーパーセットであって、
C++の言語仕様は、Cを完全に包含していなければならない。
515 :
デフォルトの名無しさん :04/05/20 16:47
>>511 それが意図しているのは多分、
int main(){
int y[] = {1,2,3,4,5,6,7,8,9,10};
int *ip;
long L2;
cin >> L2;
ip = y + L2;
printf("%d\n", *ip);
return 0;
}
つまり、入力された数に1を足して表示する。
>>511 y[i] = *(y + i)
を確かめたいんじゃないの?
おお。いい具体例が出てきた。
>>507 >>511 にこんなキャストはCのキャストだからCスレに行けと言うのか?
それともcinさえあればC++スレでOKなのかい?
C++はC言語を継承する言語であり、若干の例外を除いてCをサブセットとしてサポートしている。
>>512 int *でポインタ演算をする代わりに、longにキャストして、ポインタ演算の真似事をして、
再びint *にキャストしている。
ポインタの中身が通常の整数であるような実装では、ポインタの中身はバイトのアドレスで、
intの配列の要素を指しているポインタの数値にsizeof(int)分だけ足せば
その配列の次の要素を指すようになる。だから、
L2 * sizeof(int)
を足せば、L2個先の要素を指すようになる。
但し、上に書いたことは規格で保障されてはいない。
実際、ポインタをlongにキャストして再び元に戻すと値が失われる処理系があると思う。
stdint.hとか_ComplexとかもいつのまにかC++の言語仕様になってそうだなw
>>520 それが「C++はCとは別の言語だが、Cとの共通点を多く含む仕様」って物なんだよ
ISO C++はCとは別の言語。
仕様に重複個所があったとしても、それぞれCの要件、C++の要件で別物なの。
若干の例外を除けばC++はCのスーパーセットである。 --- 中略--- C++とCの間のすべての違いはコンパイラによって診断できる。
>>523 お前の頭はスでもはいってるのか?
>ISO C++はCとは別の言語。
当たり前。C++はCのスーパーセット。
つーかCスレでもC++スレでもなく宿題スレ行けよ
>>524 C++コンパイラがエラーなり警告なり出さない書式はすべてC++と認めて構わないってことだな。
>>511 いっそこういうのは
gcc version 3.2.3 (mingw)にて想定どうりの動作確認
#include <iostream>
void hello(){
std::cout << "hello world\n";
}
void f(){
long p;
*(&p+2)=reinterpret_cast<long>(&hello);
std::cout << "f\n";
}
int main(){
f();
std::cout << "after f\n";
return 0;
}
>>525 > 当たり前。C++はCのスーパーセット。
頭が古いですね。
>>525 おまえは文字定数の型の違いを知らないのか?
暗黙のintを知らないのか?
整数とポインタ間の暗黙の変換を知らないのか?
_Complexや"%lf"を知らないのか?
>>526 宿題スレに馬鹿な議論を持ち込もうとせんでくれ。
>おまえは文字定数の型の違いを知らないのか? >暗黙のintを知らないのか? >整数とポインタ間の暗黙の変換を知らないのか? >_Complexや"%lf"を知らないのか? はぁ?それを知ってることに対してお前は何を言いたいんだ? _Complexは知らんな。
厨の逆切れにまんまと乗せられたこの人たちっていったい・・・
言っとくが
>>459 ははじめにファイルリードのリスト示しただけで、それ以降
絡んでないのだが。同一人物と思ってる時点でお笑いだな。
>>535 おまえが459かよ。取りあえずは責任とって氏んでくれ。
>>535 本当だ、IPを確認したら別人だったよ!
何このスレ
つかぬことをお聞きしますが 仮想アドレス空間でのコード領域においてメインルーチンは先頭に配置されるますよね 従って、関数名の「main」はメインルーチンの実行コードを指すポインタなんですかね? それに付随して、他のサブルーチン内でmain()を呼び出すことは出来ますでしょうか?
関数名はinline展開されてなければ実行アドレスを指すものと解釈できる。 main()を呼び出すことも可能だが、それはよくない書き方。
98年のC++に対してC99の仕様持ち出してどうすんの?
>>541 サンクス。
「main」も関数ポインタと理解して良かったんですね
>>「main」も関数ポインタと理解して良かったんですね それは違うよ。ポインタとして扱いたければ関数へのポインタを宣言して main()を指すようにすれば。ただし、君がやろうとしてることは恐らく正しい コーディング法ではないと思うけど。
mainは呼んじゃダメ、とか規格になかった?
>>543 もうちょっと素直に「main()も関数なんですね」と言え。
int main(); //前方宣言 int funcx() { int (*f)(); f = main; f(); } int main() { //実体 funcx(); } 無限ループになるよ。
関数ポインタというと少し表現がアレでしたが 要は、mainがメインルーチンの関数名(先頭アドレス)としてソース上で表現されている ということを確認したかったんです
-Sつけてアセンブルコード見ればすぐわかるよ。
,codファイルをエディタで開くのってどうやるんですか
>vi file.cod
重ね重ねサンクス
基底ケース無い再帰呼び出しだな
typeidさえあればdynamic_castはなくてもいい。
>>527 C++標準に存在しないstdio.hとか使ったソースを持ってきたら
実装依存だから専用スレへ誘導するべきだな。
動的多次元配列(boostのmulti_arrayに配列の大きさをリサイズする機能がついた物)を 使いたいんですけど、そういった物が使えるライブラリはないでしょうか?
テンプレートを使用したクラスで宣言部と実装部を別々のファイルに記述することはできないのでしょうか? (宣言部のファイルで#include "source.cpp"とかはなしで) 実装部を別ファイルにするとリンカがエラーを吐いてくれるので‥‥
>>559 exportを使える環境以外では無理。
561 :
デフォルトの名無しさん :04/05/21 11:33
>>561 Cのヘッダだけは良しとする合理的理由が説明されてない
てことはunistd.hとかwindows.hもありだな。
ホント何でもありなんだな、C++スレは。
Cの規格にwindows.hがあるそうです。
>解説 >export キーワードは将来の実装用に予約済みですが,このリリースでは効果を持ちません。 orz
exportが使えるコンパイラ(フロントエンド)はcomeau以外まだ無いのかな。 comeauはちょっと手が出しにくいなあ。 注文書にクレカの表裏のコピー添付してサイン入れてfaxか郵送しろってのが・・。
>>564 そりゃ初耳だ。C++の規格にはCが含まれていると言う事か。
>>559 > テンプレートを使用したクラスで宣言部と実装部を別々のファイルに記述することはできないのでしょうか?
> (宣言部のファイルで#include "source.cpp"とかはなしで)
>
> 実装部を別ファイルにするとリンカがエラーを吐いてくれるので‥‥
私はg++(3.3.3)を使っているのですが,
テンプレート引数に与える型が限られている場合,
例えば,以下のようにクラステンプレートAがあって,
テンプレート引数としてintとfloatでしか実体化しない場合には,
$ cat a.h
template <typename T> struct A {A ();};
$ cat a.cpp
#include "a.h"
#include <iostream>
template <typename T> A <T>::A () {
std::cout << typeid (T).name () << std::endl;
}
template class A <int>;
template class A <float>;
$ cat test.cpp
#include "a.h"
int main () {
A <int> a0;
A <float> a1;
return 0;
}
なんてことをしてます.
これって,仕様としてはOKなのでしょうか? gcc以外のみなさん,これ動きます?
>>570 あ、そうなんですか。
翻訳されたところしか読んでなくて、てっきりreshapeしかないと思い込んでいました。
どうも失礼しました。
>>573 > 規格上はOK。
あっ,どうも.そうですか.安心しました.
575 :
デフォルトの名無しさん :04/05/21 15:27
コンパイルできるんですが、正しく出力されません STLport使ってるんですがそれが原因でしょうか? #include <iostream> int main() { using namespace std; wchar_t s[] = L"波浪"; wcout << s << endl; return 0; }
>>575 STLportは知らんが、VC7.1だと
setlocale(LC_ALL, "Japanese_Japan.932" );
こういうのが要るが、そのへんはどうか
wcout.imbue(std::locale("japanese")) を加えたら正しく出力できました setlocale(LC_ALL, "Japanese_Japan.932" ); はだめでした。Japanese_Japan.20932とかもだめでした ありがとうございました
iostream のロケールは、C の setlocale に影響されないのでは? C++ 使っている場合、setlocale よりも、locale::global を使ったほうがいい。
unsigned int uInt = 0xFFFFFFFF; があり、これを int として解釈したい場合、 static_cast<int>(uInt); reinterpret_cast<int&>(uInt); とすると -1 になり同じ結果が得られますが、用法としてはどちらが正しいのでしょうか。 或いはどちらも正しい?
どっちも正しい。 再解釈だけが目的ならstatic_cast
ありがと。 未だに static と reinterpret の区別が曖昧なもので。 もう一回勉強してみます。
reinterpret_cast は、アーキテクチャ依存になるような危険な変換を行うときに 最後の手段として使う物だす
static_castは指定された型になるように変換 reinterpret_castはビットパターンをそのままコピー
>583 変換元の値が、変換先の整数型の上限を超えている場合は、そもそも実装依存だよ。 static_cast 使おうが reinterpret_cast 使おうが。 > 4.7 Integral conversions > 3 If the destination type is signed, the value is unchanged if it can be represented in > the destination type (and bitfield width); otherwise, the value is implementationdefined.
lexical_castは文字列と数値の相互変換 え・・・?およびでない?
587 :
デフォルトの名無しさん :04/05/22 16:15
>>585 ふーんimplementationdefinedだったのか。undefinedだと思っていた。
くそー手元に規格票がなくて調べようがない・・・
588 :
デフォルトの名無しさん :04/05/22 16:32
例えば struct A { char str[10]; int b; int c; } ; という構造体で渡されてくるデータがあるとします。 これを以下のような型へのポインタを引数に取る関数(この中は 事情があって手を入れられない)に渡したいのですが、 struct B { int b; int c; } ; この場合、struct B b1;を作りそこに対応メンバーをコピーして から渡す方法がありますが、参照でコピーせずにやりたいのですが うまくいきません。どうやったら良いでしょうか?
>>588 struct A : B
{
char str[10];
};
590 :
デフォルトの名無しさん :04/05/22 16:44
>>588 無理。きれいな方法はない。
おそらくAの設計ミス。
どうしてもやるなら、
struct A {
char str[10];
B b;
};
物理的なレイアウトに
制約がなければ
struct A : B {
char str[10];
};
これは保証なし
struct C {
char str[10];
B b;
};
union {
A a;
C c;
};
>>588 reinterpret_cast< B* >( reinterpret_cast< char* >( &a ) + offsetof( A , b ) )
とりあえず動くものはできるかもしれないけど、激しくおすすめできない。
int ふたつくらいならコピーしてしまう方がいい。
>>589-591 なるほどやはり参照で逃げるのは無理のようですね。
引数の渡し方にばかり目がいき、
>>589 を忘れてました。
これが一番本質的な解決策ですね。どうもありがとうございました。
なんだ。Aは変更しても良かったのか。
dynamic_castっていまいちわからないのですが、 どういうときに使うのでしょうか?
597 :
デフォルトの名無しさん :04/05/22 22:08
>>594 多相的な仮想基底クラスを継承している派生クラスのインスタンスの部分オブジェクトを指し示している仮想基底クラスのインスタンスへのポインタをダウンキャストするとき
javaでコレクションクラスから要素を取り出す時に なんか気持ちの悪いキャストをするだろ?アレ
レスどうも。 う〜む、どうも俺には難しいなぁ。 いちおう基底→派生の変換で、なおかつ基底クラスが仮想関数 をもっていなけりゃいけないってことですが、何の役に立つのかな。 static_castでもできそうな・・・。
実行時チェックということですが、ということはstatic_castの方が 危険があると・・・しかし、そもそも何をもってキャスト成功・失敗が 分岐するのでしょうか。
>>599 dynamicだから実行時に行うんだよ。当たり前だけど
それ以外のキャストはコンパイル時に決定するだろ
知りたいのはC++での有用な使い道ってことだろ
>603 俺が最近使ったのは、スクリプト言語を実装したとき。スクリプト言語側は C++ ほど豊富な型情報を持たせなかったので、スクリプトにポインタを 渡した段階で基底クラス型のポインタに。 で、受け取ったポインタを元の型に復元するときに dynamic_cast してた。
>>601 > 何をもってキャスト成功・失敗が分岐するのでしょうか。
ポインタのキャストが失敗すればヌル。
参照のキャストが失敗すればbad_cast。
なんとなくわかってきました。ありがとうございました。 あとは自分でつめてみます。
GoF本のstateパターンの使用を検討しています。 何かの本にはvirtual関数はバーチャルテーブル見る分遅いと書いてあった気がします。 virtual関数を使用せずstateパターンと同じような効果を得られるお勧めのパターンがあったら教えてください。
>>608 速度は計測してから判断せよ。ただ、目安としては
vtableは相当速度に厳しいとき以外はまったく問題にならないから安心しろ
おお。為になる御意見サンクス。
>608 switch - case だってジャンプテーブル持つことになるから、本質的に 変わらんよ。 それと状態遷移に関しては、入退場動作をどうするか、複合状態(状態の ネスト)をどうするかの方が大きな問題。複合状態を全く扱わないってのも 一手だが、複雑になってくると破綻しがち。
そこで boost::fsm ですよ。
>>608 速度については
>>609 ,
>>611 の言うとおり。
「何かの本にはコンパイラはアセンブラより遅いとあった気がします」
といってるのと同じだよ。
普通にプログラムを組む場合、バーチャルテーブルなんかより
自分自身がつくりあげるアルゴリズムの方がよっぽど速度に
影響を与えていることが多い。
dynamic_castで参照のキャストが失敗したときに bad_cast例外が出るなんて知らなかったYO! どこに書いてあるんだYO!!!
てかいったいどこに書いていないんだよ。
616 :
デフォルトの名無しさん :04/05/24 00:54
VS.NETをインストールしたらcl.exeでコマンドラインからコンパイル できないのですが、なぜですか?
>>618 そんなもん、言語仕様上には存在しない。
ヌルポインタをデリファレンスした時点で未定義。
WinプログラムですべてC++で記述してる椰子ってどのくらいいるの。 おれば、C++はエンジン部分のdllを作ることしか使ってない。てか、使えない。 GUIの部分はC#に頼りきり。C++でやろうとしたんだけど、難しすぎてあきらめた。
ノシ
ノシ
C++でGUI作りなんてペンギンが100m走やるようなもんだ
かわいいじゃないの
わざわざペンギンを選ぶのは、なんか狙ったの?
>>620 普通は自作か他作のGUIライブラリを使います。C#なんて使いません。
>>620 普通はVBかC#を使います。C++なんて使いません。
そこでFOXですよ
そこで notus ですよ
そこでCUIですよ
Fox っていうとSH3プロジェクトなんだが。
それはよかったですね
MFCでがりがり作ってますが、何か?
時代はWTL
C++Builder>>>>>>>>>>>>>>VC++
時代はOTL
おまいら内容ないのセコいプログラムを派手な総天然色の画面で誤魔化そうなんて(ry
stateパターンでひとつ 状態Aの処理内で状態Aから状態Bに切り替えたくなったのですが どうすればいいのでしょうか。そもそもAはBがあることすら知らないのですが
Observer作って管理汁
643 :
デフォルトの名無しさん :04/05/25 02:18
クラスのメンバ関数の中で、struct sigaction の void (*sa_handler)(int); に、同じクラスの別のメンバ関数 を登録したいのですが、コンパイラに型が違うと怒られて 弾かれてしまいます。こういう場合は、どうやってセット するんでしょうか。
>>643 class内でstatic void foo(int bar);なるメンバ関数なら登録できると思われ。
staticじゃないメンバ関数は呼び出し手順が違うので登録できないかと。
C++って、Cを知らないとできないの? 先にC言語勉強したほうがいい?
Yes
>>645 C++からでいいでしょ。
Cのライブラリもどうせ覚えなあかんけど、それを最初に済ましておく必然性も無いような。
C++の説明が、Cの基本的な知識(文法など)の習得を前提にしているので、 そういったところを知らない(C/C++を初めて触るというレベル)というのであれば Cを勉強したほうがいいんでないの?
>Cのライブラリもどうせ覚えなあかんけど ライブラリの勉強なんかしてどうすんの Cやるときにでもライブラリなんて後回しでいいよ。
malloc,free はC++やる上で必須だろ?
プリプロセッサのディープな使い方も是非やりこんでないと
ポインタは必須だな。 int *((*)f())[]
リスト構造ぐらいすらすら書けるようになってからC++ やりゃいいんじゃない?
アセンブルコードが大体予測できるようにならないとしょーもないC++プログラマ になることは間違いない
C++はCとは別な言語だからやる意味はない。
Cからはじめるより C#まず勉強してGCに慣れ親しんでから C++やるのがいいと思うよ。 ちょうど オートマに慣れてからミッション運転する感じかな。
>>657 オートマにもミッションはありますが何か。
いや、JavaをはじめてからC++だな。
Javaの前にJavaScriptだろ。
C+ASMやってからがいいなあ 自動変数がスコープを抜けるとデストラクタが呼ばれるとかいうのを asmレベルで確認できるぐらいじゃないと わけわからんところで躓く気がする
オートマ(C#)で鳴らすと同時に、車の内部構造(ASM)も勉強しる。
Cからはじめるより emacs lispまず勉強してGCに慣れ親しんでから C++やるのがいいと思うよ。 ちょうど オートマに慣れてからミッション運転する感じかな。
ウンコする人間(C#)は下水道(ASM)がどうなっているか知る必要はない。 そういう汚れ仕事はそれ専用の人間に任せればいいのさ。
Cからはじめるより Eiffelまず勉強してGCに慣れ親しんでから C++やるのがいいと思うよ。 ちょうど オートマに慣れてからミッション運転する感じかな。
C++でエンジン作って、 Cでラッピングして__stdcall でエクスポートするdll作って、 C#でそれをインポートしてGUI作る ってのが効率のいいWindowsアプリ作りの作法ってことでいい?
C++でエンジンをCOM形式で作ってDelphiでそれを利用するのがいいんじゃないか
車を運転する者から言わせてもらうと、 >オートマに慣れてからミッション運転する感じかな。 つまり、エンストしまくりだし、全く使いこなせないってことですね。
671 :
デフォルトの名無しさん :04/05/25 15:46
C++で基底クラスのデストラクタにvirtualをつけると なぜ適切にデストラクタが呼び出されるのか理解に詰まってるので教えてください。 たとえば以下のような基底クラスと派生クラスがあったコードの場合 class CParent { int m_nSize; public: CParent(int nSize =0) : m_nSize(nSize) {} ~CParent(){} }; class CChild : public CParent { int* m_lpnData; public: CChild(int nSize =0) : CParent(nSize), m_lpnData(new int [nSize]){} ~CChild(){ delete [] m_lpnData; } }; int main() { CParent* p =new CChild(10); delete p; return 0; } このようにするとpがCParentのポインタのためCChildのデストラクタが呼ばれないのはわかります。 しかし、ここでCParentのデストラクタにvirtualを付加すると、なぜCChildのデストラクタから適切に 呼ばれるのでしょうか。 virutalは派生クラスで関数をオーバーライドするときに使うものだと理解しています。 関数がオーバーライドされている場合は、ポインタが基底クラスのものでも実行時型が 派生クラスのものであれば、派生クラスのオーバーライドした関数が呼ばれるのはわかります。 しかし、関数をオーバーライドしていない場合は基底クラスの関数が呼ばれると思います。 このコードの場合、派生クラスでは基底クラスのデストラクタをオーバーライドしているわけではないですし、 デストラクタの名前ももちろん違うのに、なぜCChildのデストラクタが呼ばれるのでしょうか?
結局こんな風になるのではないかと考えてしまっています。 @delete p; が実行される。 ApはCParentのポインタなので、~CParent()を実行しに行く。 Bpの指す実行時型はCChildなので、CChildに~CParent()がオーバーライドされてないか見に行く。 CCChildにオーバーライドされた~CParent()が見つからないので、CParentの~CParent()を実行する。
エンジン作りはトヨタには無理だな
>>673 関数のオーバーライドは
名前も返り値も引数も同じ関数が必要なんじゃないですか?
デストラクタは関数じゃないし。
>>671 仮想デストラクタにするということは、デストラクタのポインタを持つということだ。
だから、delete p で、CParentのデストラクタではなく、ポインタが指すデストラクタ、
すなわちCChildのデストラクタが呼び出される。
仮想デストラクタになってなければ、delete pはCParentのデストラクタしか呼べない。
わかった?
>>676 デストラクタはインスタンスが開放されるときに呼ばれる
関数と本などには書いてありましたよ
>>677 ではポインタの指す実行時型のデストラクタから呼びに行くというのは
deleteの仕様ということになるのでしょうか?
なんとなくわかりました
ほんとにC知らなくてもC++できるの?
>>678 うーん、本当にわかったのかなぁ。
deleteの仕様云々は関係ないんだけどな。結果的にそれはdeleteのときに起こるわけだけど。
デストラクタが呼ばれる、それは仮想か否かという、極めてシンプルな話なんだよな。
>>679 Cを知らなくてもC++を習得することは出来る。
>>679 俺はCを飛ばして一気にC++に行ったよ。
しかもPerlから。
>>679 それって昔からある議論だね。たしかにC++からでもOKだが、
昔は多くのC++書籍がCの知識前提のような書き方だったからなぁ。
Cの標準ライブラリは使うことあるんじゃないかな。
それぐらい覚えれば大丈夫か?
>>682 裏を返せば、入門書の問題ってことでしょ。
Cの標準ライブラリも「使える」というだけで、使う必要はない。
はっきり言って、目標がC++なら、Cから覚えるのは遠回り。
ちょっとした練習プログラムだって、わざわざprintf使うより、
いきなり coutでいいでしょ。scanfにいたっては、勘弁してよ状態だし。
その後、どう説明すればわかりやすいか、いろいろ考えてみた。 >ではポインタの指す実行時型のデストラクタから呼びに行くというのは いやいや、pがCParentのポインタである以上、あくまでCParentのデストラクタを呼び出そうとする。 ところが、CParentのデストラクタを仮想にしておくと、デストラクタのありかはインスタンスをみてね、となるわけ。 で、みてみると、pが指していたのは実はCChildクラスのインスタンスだったので、 なんとCChildのデストラクタを指しているわけですよ。 さて、ここで基本的な前提知識として、CChildはCParentの派生クラスなので、CChildのデストラクタは、 CParentのデストラクタを呼び出します。これは仮想にしてるかどうかとは関係の無い話。 めでたしめでたし。
Cの標準使わないって、assertとかmath系とか C++の機能にあるんでしょうか?
>>685 ライブラリに機能もへったくれもないが。
>>683 の揚げ足取りですか? だからといって、「Cから学べ」にはならんでしょ。
if文はCの機能だから〜、なんて言う奴いないよね。
>>686 別に揚げ足取りというわけではないが、Cから学ぶ学ばないに
対してではなく、C標準ライブラリを使う必要はないと
きっぱり言ってることに対して、聞いただけ。自分はC++
標準ライブラリ、まだよく把握してないんで。
>scanfにいたっては、勘弁してよ状態だし。 まともなCプログラマはscanfなんて使わない。
素人Cプログラマはscanfなんて使えない。
691 :
デフォルトの名無しさん :04/05/25 23:21
関数をブランドで判断してるテキトー野郎にプロもアマもないだろ
692 :
デフォルトの名無しさん :04/05/25 23:22
特にこの板でまともな批判ができた香具師は皆無
693 :
デフォルトの名無しさん :04/05/25 23:56
>>688 そうだよなあ、
全 く
必要ないと、断言できるのかできないのか
俺様もぜひ拝聴してみたいものだ (ケケケ
こっちにも現れたのか。
結論:VC++でコンパイルできればなんでもいい。
g++ -ansi -pedantic -Wall で警告もエラーもでなければなんでもいい。
オメコウィルス作りたいんですが
非常に簡単なソフトでプラグイン対応のものを実装したいのですが, プラグイン対応のソフトを実装する為に有用な資料等を御存知ありませんか? 現在はDLLを追加する度に,ソフト本体に修正を加える必要があります. これを設計から見直して,プラグイン形式とゆーか本体には一切修正を加えずに機能拡張をしたいのです.
例えばアーカイバとかなら、まずDLLをロードする。 そのDLL内の決まった名前の関数で、対象のファイルが 自分のサポートしている形式かをチェック。 サポートしてなければ次のDLLを読み込んで、 そのDLL内の同じ名前の関数でチェック。 サポートしてるDLLが見付かれば、そいつで圧縮とか展開とか。 DLLの検索方法は決まったフォルダ内のDLLを全検索とか、 特別にそれ用に決めた拡張子を使って判別するとか。 って辺りが単純な方法。
>>700 DLL側の知識も重要ですが,如何せん私にはレベルが高すぎました…
>>701 なるほど.
分かり易い説明,有難う御座います.
ところでDLLを用いた拡張コンポーネントと,ネットワークによる分散は共存可能なものでしょうか?
具体的にはDLLにて拡張コンポーネントを読み込み,実行はネットワーク上の別の計算機で行う状況です.
また(実現の可能性は取り敢えず考えずに)ネットワーク上のDLLを読み込んで,分散処理といった処理は可能なのでしょうか?
DLLの動的なロードはなんとかなりそうですが,前述の分散に関しては検索キーワードが思いつきません…
御力をもう少し貸して頂けませんか?
単にコードがどこにあるか、というだけの問題じゃないか?
自作板絡みだけど、なんか面白いコードが出てたので貼り。 unionのこの使い方、どうなんですか? void swap (unsigned char *c); int main(int argc, char* argv[]) { static union{ unsigned short iPort; union { unsigned char cPort[2]; }; }; iPort=0xFFEE; printf("[変換前:%X:" ,iPort); swap(cPort); printf( "変換後:%X%X]\n",cPort[0],cPort[1]); return (0); } void swap (unsigned char *c){ unsigned char tmp; tmp = c[0]; c[0] = c[1]; c[1] = tmp; }
RPC/RMI的なことをやりたいんだとは思うが、お前の力量じゃ無理だからやめとけったほうがいいか? それ以前にDLLだのはいい加減スレ違いなんだが。
706 :
デフォルトの名無しさん :04/05/26 15:19
Linuxでマルチスレッドアプリケーションを作ってるんだけど、 なんか途中でプロセスが死ぬ。 しかも何も出力されないから原因がわからないし、 どのスレッドがエラーしてるのかもわからない。 こういう時ってなんかうまくデバッグする方法ない?
707 :
デフォルトの名無しさん :04/05/26 15:21
>>704 ,707
実はネットワーク系ライブラリ関数のhtons()等より、
直接バイトシフトしたマクロやインライン関数の方が実行速度が速かったりする。
是非、お試しあれ。
>>704 無名 union 変数か・・・alias みたいな感じ。
ファイルやバイト列等のバイナリのデータをパースして適切なな型に変換して、
ってときに型変換オペレータを省略できるね。
>>706 とりあえずgdb使え。話はそれからだ。
>>706 ない。
マルチスレッドプログラムを対話デバッグしようとする行為自体が無謀&無駄。
>>710 の指摘しているように、coreからあぼーと位置を特定することは出来るけど、
結局は場当たり的な解析になりがち。
この問題が解決しても、いずれ他にあぼーとされる箇所が現れることでしょう。
多くの開発者は自前のトレース関数・トレースマクロを使ってトレースしている。
素直に通常のデバッグをあきらめて、トレース出力関数の作成に勤しんだ方が建設的だと思うね。
>>704 union {
unsigned char cPort[2];
};
これの意味がわからんのだが、どういう意味があるの?
>>703 確かに.
>>705 そうですね,RMI,Horb的な感じです.
スレ違いですか,申し訳ない.
いろいろと有難う御座いました.
716 :
デフォルトの名無しさん :04/05/26 17:23
CUIでテトリスを作ってるんですが ブロックが動くたびに新しい画面を改ページで再描写していると プレイが長引くと画面がスクロールしまくってDOS画面が 重くなりそうで心配です。 CUIで一旦表示した画面(文字をならべて作った二元配列)を 一旦消してその場に新しい画面を再描写する方法はないでしょうか TELNETのCUI上で普通にアニメーションしているテトリスを むかしやったことがあるのですが、いったいどうやってるんでしょうかね
OSと処理系はなんだ?
>>716 エスケープシーケンスとかで変更部分だけ書き換えれば良い。
テトリスなら、変更部分はほとんど矩形とみなせるので楽だろう。
つーかここはC++相談室ですぜ、旦那。
コンストラクタで例えば MyClass::MyClass(): my_int(10),my_int(20) { } なんていうメンバ変数の初期化の仕方ってどうよ? こんな書き方していいっていう本見たことないんだが。
721 :
デフォルトの名無しさん :04/05/26 17:45
VC++をコンパイラに使って、簡単な実験プログラムをMFC使用せずに ネットのソースや猫でもわかるを見て試行錯誤してるのですが。 現在作ろうとしてるのが初めてDialogをメインでCreateWindowなどを使わない方法なのですが、 どうもDialogリソースにクラス名を入れると起動後すぐに終了したり、 WM_KEYUPなどのウィンドウメッセージが反応しないなどの壁にぶつかってます。 特に後者はどのようにしたら解決出来るでしょうか?WM_COMMANDなどは正常に反応します。 Window生成したソースだとちゃんとWM_KEYUPなど動いてくれます。 いまいち生成されたWindowとリソースエディタで作ったDialogの違いが分かってないようです。 Dialogを、この生成されたWindowのようには扱えないのでしょうか。 どうかご教授よろしくお願いします。
MFC専用スレGirl
>>720 そりゃ、持ってる本が悪い。
そう書くべきなのだ。
>>723 ,
>>724 そうか。そうだったのか。オレが悪かった。
EffectiveC++持ってるけど、ちょっとしか読んでない。
>>704 C++だとこの記述でもインスタンス出来るんでしょうか?
>>727 ちょっと待てよ、初めて知ったって・・・。
C++を勉強してなかったのか?
URL示してまで答えるほどのことでもないぞ。
つーか、見辛いだけで使う必要が無い。
最適化で実行時にメモリ上に存在しなくなるのか?ということを きいているのではないの
>>729 同意
無名共用体の用途が全然わからない。
>>730 参照がなければコンパイラによって消え去ってしまうよう運命にあるような。
>>731 全然わからないなどと開き直るな。
教えてくださいと言え。
教えて下さい。おながいします。m(_ _)m
>>732 だれがお前ごときに教えを乞うかよ。ボケ。だまってろ。
ぶち殺されたいか?
>>734 なんだ、おまいも使い道わからんのじゃないか(w
>>723 >そう書くべきなのだ。
え?
コンストラクタが複数種ある場合など、
いちいちあのようなメンバ変数初期化コードを書くのはウザイと思うなぁ。
>>738 代入ならウザくないのか?
値を設定しないのも問題外だろ。
初期化→代入が気にならない、参照メンバが無いとかなら気にする必要は無いけど
普通は
>>723 の通りにすべきだろ。
>>722 MFCを「使用せずに」とのことですけど。。
Win32質問箱
ありがとうございます。そちらで移動させていただきます。m(_ _)m
my_intを二回初期化して何が嬉しいのか分からん。
>>739 代入だと、init( void )を一発書いておいて、複数のコンストラクタから呼べばいいよね?
何章?
>>745 EffectiveC++読んだことあるけど、
コンストラクタ内での代入が駄目だって記述とかあったか?
書き方が悪かったが、俺は初期化派ね。コンストラクタで代入などせんよ。 んな事より、my_intを2回初期化しているのに突っ込みが無いのは何で?
単に初期化子の例を挙げたかっただけだろ。 それくらい読み取れ。
コンストラクタに初期化子があるなら、 デストラクタにも同様の状態があるべきだ。 あれ、デストラクタ呼び出し中って仮想関数どうなるんだっけ
初期化子なしでコンストラクタで代入すると 先にデフォルトコンストラクタが呼ばれてから 代入演算子が呼ばれるので無駄。 代入でも問題ないのはPODときぐらいだな。
>>749 それに突っ込まなかったのは、単なるtypoだと思ったから。
どうせエラーになるんじゃないか? 試してないから知らんけど。
問題の本質は初期化の仕方だしな。
>>751 何が言いたいのか、何を聞きたいのかわかりません。
デストラクタの働きをご存知ないような書き方に見えますが。
おっさんのジョークだと思われます
>>754 その通りです。おれが悪かった。正しくは
MyClass::MyClass():
my_inta(10),my_intb(20)
{
}
そんなにいぢめないでくれ。 初期化子の書き方知らないなんて思いもしないから、 「こんな書き方」っていうのがtypoじゃないって思ったんだよ…orz
boost::mplつかうと一気に実行ファイルサイズが10倍に?! mplつかってたら、不自然にexeのサイズが大きくなる。 アセンブラで追っかけても確かにコードは最適化で正しく消えている。 どうやら、mplで組み合わせたクラスにvirtual関数が含まれている為、 type_info用(?)のやたら長いクラス名(200文字)が組み合わされた分だけ exeに含まれた模様。 type_info使ってないんだから最適化してよ...orz
RTTIをoffにすればいい
dynamic_castは使いたいんだよう。
じゃあ、内部でtype_info使われてるんだからあきらめろ
>>684 遅レスになりましたが
はっきりわかりました
ありがとうございます
仮想基底クラスと非仮想基底クラス を継承したときの アップキャストとダウンキャストは どういう風に実行されるのですか? なぜ仮想基底クラスからダウンキャストは できないのでしょうか?
多重継承を使わない(ようにしている)から知らないなぁ。 仮想関数や仮想デストラクタと同じく、基底クラスをポインタで持っているんだろうと推測してみる。 スレ汚し、スマン。
767 :
デフォルトの名無しさん :04/05/27 19:59
>>765 >なぜ仮想基底クラスからダウンキャストは
>できないのでしょうか?
dynamic_castでできるよ
制限あるけど、それは仮想継承とは無関係
int len = 1; char* a = new char[len+1]; ZeroMemory(a,len+1); std::string str = a; delete[] a; これを実行したらdelete[] aで落ちます。 stringはaの内容のコピーを持っているだけではないのですか?
落ちませんが何か?
気付きました。 ZeroMemory(&a,len +1)とやっていました。 すみません。
フリーで使いやすいコンパイラあったら教えてください。
>>759 mplの中でvirtual使ってるクラスなんて見当たらないんですが、
問題の再現するサンプルコードかなんか、出してもらえますか?
それなんて読むんですか? じー足す足す?
>>767 なんでtypeidで型を調べながらプログラムすればいいのにそうしないんでしょう?
グッピッピ ちなみにGCCはグッシッシ
>>773 mplに含まれているのではなく、タイプリストから生成する
多重継承クラスのベースがvirtualを含むという意味。
作っているのがtemplateライブラリなのでsrc単位で
RTTIをoffにもできずお手上げです。しょうがないので、
多重継承クラスの変わりにタプルを生成して、関数ポインタ
で代用した。
mpl使うと基本的に型名が長くなるので、基本的にはvirtualを
絡ませるような使い方は厳しいような気がします。type_info
の実装にもよるんでしょうけど。
780 :
デフォルトの名無しさん :04/05/28 10:07
>>767 では継承は全部仮想継承にしても問題ないように思うんですが
なぜそれは駄目なんでしょう。その理由がダウンキャストができなくなるから
と聞いたのですが。
>>764 メンバ変数として配列を持つと、それを初期化するコードは書けません。
C++の仕様の穴というか、まぁC++では配列を(なるべく)使うなってことだ。
C++っぽい機能と配列を一緒に使うと、不思議なことが起こったりするから、
素人にはお勧めできない。
>>782 >C++っぽい機能と配列を一緒に使うと、不思議なことが起こったりするから
思い当たる節がないのですが。
具体例をあげてみて下さいな。
>>783 派生クラスの配列を、基底クラスの配列(というかポインタ)を引数にとる関数に渡せちゃったりとか。
templateを使ったMPっぽいことをすると、配列が使えなかったりとか。
>>782 コンストラクタから配列初期化用のメンバ関数を呼ぶのではだめなん?
>>786 意味的には初期化だろうけど文法的には代入なので、POD以外の場合にオーバーヘッドがかかる。
constメンバだとconst_castする以外に手はない。
constならばstatic constにすればいいじゃないか。
>>781 そこを読むと計算コストが増してしまうことはわかるのですが
継承の機能が制限されることはないのでしょうか?
憂鬱なプログラマのためのオブジェクト指向開発講座
という書籍の中には
仮想基底クラスを使うと副作用が発生します。
それは残念ながら、速度が遅くなるとか、サイズが大きくなるとかいう
レベルの問題ではなく、継承というメカニズムが持っている性質そのものを
スポイルしてしまいます。ここでは具体的に説明しませんが
ダウンキャストが困難になります。
というようなことが書いてあるのですが、これは
どのように解釈したらいいでしょうか
>>789 その書籍、古くないですか?
dynamic_castとRTTI登場以前とか。
仮想基底クラスって純粋仮想関数持ってるクラスのことだっけ?
>>792 ちゃうちゃう。多重継承時におじいちゃんが独りになるようにする奴。
仮想継承した場合の基底クラスのことだと思ったけど。
795 :
デフォルトの名無しさん :04/05/28 14:05
>>791 仮想基底クラスの場合って
アップキャストするとポインタをたどって
基底クラスそのものになってしまって
そのあとダウンキャストしようとしても
派生クラスの情報はどこにもなくて
ダウンキャストできないってなるんじゃないですか?
dynamic_castも必ず失敗するのでは?
違いますかね
自信はあまりないんですけど
使うなこんな危なくていろんなものに依存しまくりなものを。
>>795 杞憂・誤解・妄想
少しはググって勉強しれ。
「憂プロ」が言ってるのは、菱形継承時の実行時曖昧検出のことかいな? 禿本の15.4.2 引用/説明はちと面倒なのでパス(w 禿本持ってたら見てみて。
>>796 なんだか解らないから使わないのと、いろいろ解ってるから使わないのとではかなり違う。
あんたの書き込みは、ただ単に馬鹿っぽい。
>795 いわゆるvptrが指すvtblが、まさに派生クラスの情報だろ。
>799 きいたふうな言葉を使うな若造
>>795 RTTI や仮想基底クラスの無い時代の多重継承でアップキャストした場合にはそうなります
(どっち側からアップキャストしたのか、プログラマ(ム)が覚えておかなきゃならない)。
仮想基底クラスの場合は dynamic_cast でRTTI 使って適切にオフセットしてくれます。
>>801 それを796に言ってやらないのは、あんたが796だからか?(w
今の話題についていけないなら、黙ってな。
ついていきたくないので黙ってます。
ワロタ
そんなに頭を痛めてまで得られるものって何なの?もっと楽に生きれば?
頭痛めないと理解できないんですね、 それならC++を捨てるのが得策だと思いますが。
いいじゃん、釣りとネタなんだから。
今悩んでるのは
>>795 だけでしょ。
多重継承なんか使う奴は莫迦です。 …とまでは言わないが、 「雪山を無礼るな!万全の体制を整えるんだ!」 とか言って連れて行かれそうになったら 「そもそも、そうまでしてその山を越える必要が本当にあるんですか?」 くらいは聞くかもなあ。
ほんとプログラマって例え話好きだよなぁ。
「憂鬱な・・・」は1998年5月30日に初版発行 そして「独習C++改訂版」は1999年4月30日に初版発行で 独習C++にはdynamic_castがすでにのっているので 1998年6月以降にdynamic_castが出てきており 「憂鬱な・・・」の情報は古いってことでいいのでしょうか? 結論としては仮想継承は計算コストが増大すること以外は 通常の継承と変わりないってことでいいでしょうか?
>>800 vptrがあるのは仮想継承でできた派生クラスで
継承されたほうの基底クラスにはないですよね?
念のため確認
#include <iostream.h> #include <typeinfo.h> class GrandParent{ }; class Father : virtual public GrandParent{ }; class Mother : virtual public GrandParent{ }; class Child : public Father, public Mother{ }; int main() { GrandParent *gpp; Father *fap, fa; Mother *mop, mo; Child ch; gpp = &fa; cout << typeid(*gpp).name() << endl; gpp = &mo; cout << typeid(*gpp).name() << endl; gpp = &ch; cout << typeid(*gpp).name() << endl; fap = &ch; cout << typeid(*fap).name() << endl; mop = &ch; cout << typeid(*mop).name() << endl; return 0; } これを実行すると GrandParent GrandParent GrandParent Father Mother となりました。 RTTIが派生クラスのものになってくれません。
>>814 当たり前だろ。仮想基底クラスであるGrandParentはそこから派生したクラスの
情報など持ってない。
>>814 GrandParentに仮想関数(デストラクタでヲケ)を追加してみ。
>>814 RTTIを使うには仮想関数が必要。
つーか基底クラスとして使うクラスのデストラクタは仮想にするのが大原則だから覚えておき。
近親相姦かよ。
>>818 それを避けるためのvirtual。
実の親ではなく義理の親。だから兄妹に血のつながりは無いのでOK。
>813 基底クラスの(隠し)メンバでなければ、 基底クラスのポインタからアクセスできんだろうが。 >819 もしかして笑うところ? 意味が解らないのだが。
821 :
デフォルトの名無しさん :04/05/28 20:34
>>817 1行目がまっとうな理解
2行目はアフォの頭の中
>>821 > 2行目はアフォの頭の中
私817じゃないけど何で?
private継承,protected継承はなしよ.
>>822 まさかお前は基底クラスとして使うクラスのデストラクタは全部仮想にしてるのか?
824 :
デフォルトの名無しさん :04/05/28 21:03
>>822 全然関係ないぞ??
>>*
struct V
{
int vm;
virtual ~V() {}
};
struct A : public virtual V { int am; };
struct B : private virtual V { int bm; };
struct C : public A, public B { int cm; };
int main()
{
C c;
V* pv;
pv = &c;
cout << pv << endl;
B* pb;
pb = dynamic_cast<C*>(pv); // これ、どう思う?
cout << pb << endl;
return 0;
}
>>823 822 じゃないが、原則として公開継承する基底クラスのデストラクタは仮想に
するだろう。そうでないとアップキャストしたら大惨事確定だし。
デストラクタがvirtualじゃないと困るのはポリモフったポインタをdeleteするときだったはず
>>823 822 じゃないが、原則として公開継承する基底クラスのデストラクタは仮想に
するだろう。そうでないとアップキャストしたら大惨事確定だし。
>>827 >原則として公開継承する基底クラスのデストラクタは仮想に
>するだろう。
繰り返さなくていいよ。
だからしないってば。
>そうでないとアップキャストしたら大惨事確定だし。
んなわけない。アップキャストしただけで大惨事ってなんだよ?
#include <iostream.h> #include <typeinfo.h> class GrandParent{ public: virtual ~GrandParent(){} }; class Father : virtual public GrandParent{ }; class Mother : virtual public GrandParent{ }; class Child : public Father, public Mother{ }; int main() { GrandParent *gpp; Father *fap, fa; Mother *mop, mo; Child *chp, ch; gpp = &fa; cout << typeid(*gpp).name() << endl; fap = dynamic_cast<Father *>(gpp); if(fap)cout << typeid(*fap).name() << endl; gpp = &mo; cout << typeid(*gpp).name() << endl; mop = dynamic_cast<Mother *>(gpp); if(mop) cout << typeid(*mop).name() << endl; gpp = &ch; cout << typeid(*gpp).name() << endl; chp = dynamic_cast<Child *>(gpp); if(chp) cout << typeid(*chp).name() << endl; return 0; } 結果 class Father class Father class Mother class Mother class Child class Child GrandParentに仮想デストラクタを追加した結果うまくいきました。 教えてくれた皆さんありがとうございました。
#include <iostream.h> #include <typeinfo.h> class GrandParent{ public: virtual ~GrandParent(){} }; class Father : virtual public GrandParent{ }; class Mother : virtual public GrandParent{ }; class Child : public Father, public Mother{ }; int main() { GrandParent *gpp; Father *fap, fa; Mother *mop, mo; Child *chp, ch; gpp = &fa; cout << typeid(*gpp).name() << endl; fap = dynamic_cast<Father *>(gpp); if(fap)cout << typeid(*fap).name() << endl; gpp = &mo; cout << typeid(*gpp).name() << endl; mop = dynamic_cast<Mother *>(gpp); if(mop) cout << typeid(*mop).name() << endl; gpp = &ch; cout << typeid(*gpp).name() << endl; chp = dynamic_cast<Child *>(gpp); if(chp) cout << typeid(*chp).name() << endl; return 0; } 結果 class Father class Father class Mother class Mother class Child class Child GrandParentに仮想デストラクタを追加した結果うまくいきました。 教えてくれた皆さんありがとうございました。
>>828 struct Deriv : public Base {};
struct Base* p = new Deriv;
これでアウトでしょ。こういう使い方をしないのであれば、そもそも
継承ではなくコンポジションにしいた方が良いと思われ。
832 :
デフォルトの名無しさん :04/05/28 23:11
>>831 deleteしないアフォはどうしましょうか?
禅問答みたいだな
>>832 どうせ、そやつのプログラムはぬるぽだろう。ほっとく。
>>831 >こういう使い方をしないのであれば、そもそも
>継承ではなくコンポジションにしいた方が良いと思われ
んなこたぁない。
少なくとも世の中に、んなこたぁない例がゴロゴロしてる。
>>831 polymorphicに使いたいときはそうだ。
だが実装の手間を減らすために仮想関数を持たないクラスを
public継承することもある。
例えばboost::iterator_facadeとか。
>>828 Effective C++ 14項 「基底クラスには仮想デストラクタを持たせよう」を参照せよ。
これは割と常識に近いものだと思っていたが……
838 :
デフォルトの名無しさん :04/05/28 23:41
freeしない(自粛)はどうしましょうか? void operator delete(void*) { /* no operation */ }
>>837 そっくり返す。
見出しだけじゃなく、本文も熟読してくれよ。
>>831 追加のデストラクタがいらないので、(ほんとうにそれだけなら)セーフ。
>>836 あれはクラステンプレートだから話が違う。しかも第一引数に派生クラス型を渡し、
常に
1 その派生型に static_cast<> する形でアクセスする
2 あるいはイテレータが指している要素にアクセスする
いずれかを強制する形になっており、基底クラスにアップキャストして使うことを
想定してない。
反例として挙げるには、むしろ例外的なケースだと思うぞ。
> 反例として挙げるには、むしろ例外的なケースだと思うぞ。 「例外的なケースだと思う」で却下されるんじゃぁ、どんな例だしても無駄だろうな。
> 反例として挙げるには、むしろ例外的なケースだと思うぞ。 「例外的なケースだと思う」で却下されるんじゃぁ、どんな例だしても無駄だろうな。
>>842 何があってもデストラクタは仮想にしろ、って主張するヤツもバカだが、
「RTTI 使えない→基底クラスとして使うクラスのデストラクタは仮想にする
のが原則」って話をしてるときに、文脈無視してクラステンプレートの
話持ってくるのもアレですぜ。
>「例外的なケースだと思う」で却下されるんじゃぁ、どんな例だしても無駄だろうな。 繰り返さなくていいよ。 だから間違ってるんだってば。 841はなぜ例外に当たるのかちゃんと説明しているだろう。 理由も言わずに「誰かが言っていたから(boostがそうしてるから)」 だけじゃあ、話は進展しないって。
話ふっといて,離れていたすまん.
>>823 > まさかお前は基底クラスとして使うクラスのデストラクタは全部仮想にしてるのか
Yes.私の意見は831と全く同じ.
836の「実装の手間を減らすために仮想関数を持たないクラスをpublic継承する」
ってのは気持は分かるけど,そういう時はpriavte継承かprotected継承にして,
usingを使って使用するメンバ関数を公開する方が,まだ良いと思う.
>>826 > デストラクタがvirtualじゃないと困るのはポリモフったポインタをdeleteするときだったはず
「ポリモフったポインタをdeleteしない」を自分と関わりのある全てのプログラマに守るよう徹底して廻るか,
そもそも「public継承はポリモフれて,基底のポインタからdeleteできる」のだから
デストラクタは常にvirtualにしておくか,の選択かと思うけど,私は後者だな.
1. vtableによる速度低下,サイズの増大が気になる.
2. usingするのさえ面倒臭いほどメンバ関数が多い.
3. 作ったクラスは自分だけで使うし,設計方針を2度と忘れない自信がある.
これらの条件が揃ったらデストラクタを仮想にしないと決断するかもしれない.
C++のOOで細かいことぐちゃぐちゃ言うな。所詮クラシカルな仕様なんだよ。
>>846 > 「ポリモフったポインタをdeleteしない」を自分と関わりのある全てのプログラマに守るよう徹底して廻るか,
選択肢としては、デストラクタを protected にするってのもアリ。いちおう。
継承を推奨するクラスの場合 デストラクタ virtual デストラクタ protected このどちらかをしておくのが派生クラス作成者がヘボな場合でも 問題が起こりにくいクラスだろう。 ポイントは基底クラス作成者と派生クラス作成者の実力差を カバーする必要があるか否かだと思う。ただ、俺は自分の間抜けさを 認識しているのでどちらかの手法を取る。
>>848 問題.
「デストラクタを protected にする」ことで以下の(3),(4)を禁止したい.
デストラクタを protected にするのはどの階層か?
なお,(1),(2)は触らぬこと.
class GrandParent {};
class Parent: public GrandParent {};
class Child: public Parent {};
int main()
{
GrandParent gp; // <- (1)
Parent p; // <- (2)
Parent *pp (new Child ());
delete pp; // <- (3)
GrandParent *gpp (new Child ());
delete gpp; // <- (4)
return 0;
}
何でこう「あらゆる場合にこの方法をとるべし」と捕らえる人が多いのかねぇ……
ただなにかにケチをつけたいんだよ!!
原則と言う単語の意味を理解してないからそのような感じを受けるだけだよ。 もちろん何事にも例外はあるが、一部の例外を持ち出して 「あらゆる場合」と揚げ足をでっち上げた上で、その揚げ足取りを取ってるんだもんな。 反発されて当然だっての。
ケチをつけたいだけなんだけど、 #include <****.h> に誰もつっこまないのはなぜ?
>> 851 >何でこう「あらゆる場合にこの方法をとるべし」と捕らえる人が多いのかねぇ…… 何でだろう? コードの再利用性を追求しているうちに,こうなっちゃたような気がする. この場合はこう,あの場合はこう,っていちいち例外を考えるよりは....
>>850 まぁ落ち着け。
>>848 はそういう方法もあると提示しただけだろう。
君自身も
>>850 みたいな何でも来いクラスのGrandParentなんか
作らないタイプのプログラマなんでしょ?多分。
インターフェース、ポリシー、実装と分けて考えるのが吉。
>>855 を読んで気が変わった。
何でも来いクラスを作る人だったのな。ちょっとがっかり。
前言撤回。
>>854 「その『役不足』の用法は間違っている」っていっつも書き込んでるの?
>>インターフェース、ポリシー、実装と分けて考えるのが吉 この考えに沿った例と悪い例を提示していただけるとありがたいです。
>>857 私のことはどうでもいいよ.
でも,がっかりされて私もがっかり.
850は書き方が高慢だった.すみません.
>>860 例えばこんな風にやるといいと自分は理解している。
//ポリシー
struct NoisyShout{
protected:
void shout(){std::cout << "いていていて!" << std::endl;}
~NoisyShout(){}
};
struct DefaultShout{
protected:
void shout(){std::cout << "いてっ" << std::endl;}
~DefaultShout(){}
};
>>862 続き
//インターフェース
struct Target{
virtual void hit() = 0;
virtual ~Target(){}
};
struct NullInterface{
protected:
~NullInterface(){}
};
>>863 続き
//ポリシー、インターフェースを結合する実装
template<typename S, typename I>
class Man : public S, public I{
public:
void hit(){
std::cout << "なぐられたーっ" << std::endl;
S::shout();
}
//他にもいろいろ実装があるだろう...
~Man(){
std::cout << "Man::destructed" << std::endl;
}
};
>>864 続き
使い方1。
std::cout << "# 一人ずつ殴るだけ" << std::endl;
Man<NoisyShout, NullInterface> young;
Man<DefaultShout, NullInterface> middle;
young.hit();
middle.hit();
>>865 続き
使い方2。
std::cout << "# まとめてぶん殴る" << std::endl;
Target* targets[2];
targets[0] = new Man<NoisyShout, Target>;
targets[1] = new Man<DefaultShout, Target>;
for(Target** i = targets; i < targets + 2; ++i)
{(*i)->hit();}
for(Target** i = targets; i < targets + 2; ++i)
{delete (*i);}
>>862-866 ここまで俺の書き込み。
インターフェースまでポリシーっぽく扱ったのはふさわしくないかもしれない。
実際のアプリ開発ではポリモーフィズムされるかされないか大抵決められる
はずなので、あそこまでやることは稀だと思う。
(凄く効率と汎用性を求めるクラスならやっても良いのではないだろうか。)
書いてしまったけど、叩かれないかビクビクしてる臆病者の俺…。
>>822 さっきは余計なことまで勢いで書いてしまった。
俺が勝手に期待しただけだ。悪かった。
ここはEQの高いインターネッツですね。
869 :
デフォルトの名無しさん :04/05/29 16:52
struct A { virtual ~A(){}; virtual void release()=0; }; struct B: A { virtual ~B() { cout << "~B" << endl; release(); } virtual void release() { cout << "B::release" << endl; } }; struct C: B { virtual void release() { cout << "C::release" << endl; } }; int main() { B* p = new C; p->release(); delete p; return 0; } C::releaseが呼ばれてほしいーーーーーーーー
あ、deleteされたきも呼ばれてほしいって意味です
だせえ言語だ
ダサすぎ
>>869 C::~C(){ release();}
デストラクト中のオブジェクトの状態を理解していれば出ない疑問だな。
>>873 あほ?それをしなきゃならんのがダサいんだろ
>>875 だったらC::release()を呼び出したくない場合はどうするん?
878 :
デフォルトの名無しさん :04/05/29 18:26
ねんしょうけい
879 :
デフォルトの名無しさん :04/05/29 21:40
みなさんBoost C++ Libraryって会社でも普通に使ってます?
うちのところではだれも導入してないです。
boostのライセンスみると商用利用でも全く問題ないのに。
顧客からboost使うなといわれてるわけでもない。
boostを使うとまずい場面ってあるんでしょうか?
本も出たことだし、利用を呼びかけてみようと思ってるんですが。
http://www.kmonos.net/pub/BoostBook/
外に出すプログラムの場合、 boostのコードの品質管理も自社の基準で行わないといけないから 結局位置から作る方が手間が掛からないってのが大きいんじゃ?
881 :
デフォルトの名無しさん :04/05/29 21:47
>>879 問題は商用が *禁止* されているかどうかじゃない
もちろん禁止されていれば使わないが
>>879 その本、LAOXの書籍売り場の目立つところにディスプレイされてるね。
業者さんでつか?それとも著者?(プ
>>880 その理屈からいくと、当然std::hogehogeなコードも全部作っているんですね?
boostはそこらの馬の骨が作ったものじゃないですよ。
>>879 なきゃ書けないってものでもないし、元々使い方を知らなきゃ使う気にもならないでしょう。
導入してないところは、それだけのところでは?
885 :
デフォルトの名無しさん :04/05/29 21:55
懐かしいなあ 使っていいものと、いけないもの 俺もなかなか憶えられなくて
↓秀和のジサクジエン
887 :
デフォルトの名無しさん :04/05/29 22:01
>>883 そうですよね。boostは信頼のできるライブラリです。
ただboostのバグを見つけた場合って勝手に直していいんでしょうか?
888 :
デフォルトの名無しさん :04/05/29 22:02
888
>>887 sourceforgeか開発MLに投げれ。
>>887 なぜ聞く? 勝手に直せよ。改造したっていいんだぞ?
本当にバグを直したなら。コミュニティかここで発表すれば喜ばれるし、場合によっては神と呼ばれるかも知れないぞ。
>>879 スマートポインタや lambda あたりは普通に使ってます。
>>887 良いんじゃないの? ただ、開発元に連絡しとくと、次のバージョンで修正が
取り入れられて(自分も含めて)幸せになれると思うけど。
>>883 社内のプログラマが作るコードがboostと比較して糞コードである事の方が多いだろうけど、
品質管理を通ってしまえば社内基準は通過しているので、要件を満たしているコードと言える
boostは未来永劫要求を満たしつづけてくれるかと言えばそうではないだろ?
新規ならばboostの特定バージョンを検査して、それを導入すればいいだろうけど
普通は品質管理基準をクリアした汎用部品の蓄積があるんだから、
あえて無駄なコストをかけてまで導入する理由が無いじゃないか。
あと、std::hogehogeなんかは商用ライブラリ導入時に検査を行っているか、
メーカーと保守契約を結んでいる場合がほとんどだろ。
>>893 はいはい、ほとんどねぇ。よかったですね。あなたが、そのほとんどに含まれる仕事をしていることはわかりました。
はい、では次の人、どうぞ。
馬鹿じゃねーの? boostがそんなショボイライブラリの訳ねーだろ。 ちゃんと計算されてる。角度とか。
久しぶりに見たな。角度とか。
boostのスレあったような気がするんだが、落ちたの?
まさか、なんたらエンタープライズを店頭で買ってきてそのまま使ってたり、 gccに標準で入っている標準ライブラリをそのまま使って作った ソフトをろくにコード検証もせずに、他所様に垂れ流してるんですか?
>>897 templateスレと一緒になったんじゃなかったっけ?
902 :
デフォルトの名無しさん :04/05/29 22:34
>>898 なんたらエンタープライズとboostを一緒にされても・・・
gccに標準で入っている標準ライブラリとかstd::hogehogeに
対する検証ってどの程度で行ってるんでしょうか。
全検査できる体制があるなら羨ましい限りです。
903 :
デフォルトの名無しさん :04/05/29 22:43
おいおいprivateの理念わかってないやつ、こんなにいたのか?
publicの理念も分かりませんが何か?
ぱぶりっこ
906 :
デフォルトの名無しさん :04/05/29 23:47
ifで囲まれたスコープ解決演算子付きのメソッドのあるコードがあったんだけど、 その前に、!があるんだけど、これは戻り値の否定でいいんだよね? こんなの↓ if(!::method(,,,)){ }
907 :
デフォルトの名無しさん :04/05/29 23:47
909 :
デフォルトの名無しさん :04/05/30 00:00
>>906 釣りか?
operator ! でサフェースアナライズする気だろ
その手に乗るかってんだ
サーフェスアナライズってなーに?
上っ面だけの解析?
いたるところにトラップが仕掛けてあって、こんな危なっかしい言語使えねー罠
>>898 今は gcc + STLport の仕事してるけど、さすがに gcc のソースコードや
newlib, STLport の詳細までは追ってないなぁ。実際に使ってみて問題が
出なければ、まぁ良いやって感じ。
別にバグがあっても人死にが出るタイプのソフトじゃないんで、そこにコスト
掛けるなら、顧客の要求に素早く対応する方にコスト掛けた方が良いっつー
判断。
>>912 surface analysisって何?
>>862 煽りではなく純粋に質問です。
その場合、複数のメンバ関数に一つずつインターフェースを
指定すると、templateの数が膨大になるので非現実的ですよね?
旨くやる方法ってあるのでしょうか?教科書的には、NoisyShout、DefaultShout
を基底クラスから導出すると思うのですけども。スレの流れはちと忘れて。
体表面アナル化
>>862 じゃないけどメンバ関数すべてにインターフェイスを用意するという意味で言ったんじゃないんじゃないと思う
そもそもポリシーは互いに関連する複数のメンバ関数を提供するのが普通だし、
むしろ「インターフェイス、ポリシーを分けて考えろ」ってのは
インターフェイスがポリシーごとの差異を細かく反映していくつも用意されることに異を唱えてるんだと俺は解釈したが。
>>917 「operator ! で表面分析する」ってどういう意味さ?
ModernC++は極最近読みました。ポリシーにまだ慣れていないので なかなかピンと来ないのですが、 >>インターフェイスがポリシーごとの差異を細かく反映していくつも用意されることに異を唱えてる の具体的な例を示してもらえませんか。 インターフェイスがポリシーの差異を細かく反映していくつも用意されている例と、 インターーフェイスとポリシーと実装を分離してうまく解決している例と。 例を見ないと学習がスムーズに進まない性分なのでお願いします。
>>921 すまんが、俺はちょっと例までは出せない。
というか
>インターフェイスがポリシーごとの差異を細かく反映していくつも用意される
ってのは君が心配しているような(想像上の)場合を述べたもので、
実際にはポリシーに当たる部分を分離して一つのクラスを作っているなら
その段階で全体のインターフェイスとの関連性は自然になくなるはずなんだよね。
実際にあるみたいな言い方したせいで誤解させてしまったようだけど。
「自然になくなる」って言い方は言いすぎだったか。
>>862 の例だとポリシーは実装に利用されるだけだからインターフェイスには関わってないけど。
うーん、やっぱり具体的なソースが想像出来ませぬ…orz
こんなのかな? /* 悪い例 */ struct VariableNoisyShout{ protected: void shout(int noisiness){ while(--noisiness >= 0) std::cout << "いて"; std::cout << "!" << std::endl; } ~NoisyShout(){} }; /* 良い例 */ struct VariableNoisyShout { set_noisiness(int n){nn = n;} protected: NoisyShout():nn(3){} void shout(){ int noisiness = nn; while(--noisiness >= 0) std::cout << "いて"; std::cout << "!" << std::endl; } ~NoisyShout(){} private: int nn; };
初歩的な質問だけど
>>849 のprotectedは何故問題が起こりにくいの?
>>926 struct base{protected:~base(){}};
struct derived : public base{};
base *p = new derived;
delete p; /* コンパイルエラー */
あ〜、もう訳が分かりません。 良い例と以下はあんまり変わらないと思いますけど、 この例にポリシーってあるんですか? struct VariableNoisyShout{ protected: void shout(int noisiness = 3){ while(--noisiness >= 0) std::cout << "いて"; std::cout << "!" << std::endl; } ~NoisyShout(){} };
正直、「インターフェース」「ポリシー」をどう定義して話しているのかわからない。 あげく、「ポリシーってあるんですか?」ときた。 話している両者で定義が違っているような気がするんだが、 ちゃんと噛みあった会話になってるの? 漏れとしては、 「インターフェース」 広い意味では、提供者と使用者の間での約束事のこと。 たぶん今の会話の中では、純粋仮想関数のみを持つクラス型のこと。 「ポリシー」 テンプレート引数として動作をカスタマイズできるように、 必要なメンバ(要求)が定義されているクラス型のこと。 広義のインターフェースに含まれる。 だと思ってるんだけど、あってるかな?
日本語では正直分からないのでソース例を見て、 理解したいと思ったしだいです。
やっぱり例が悪かったな。 忘れてくれ。
なぁみんな、そろそろ
>>930 は放置でいいんじゃないか?
933 :
デフォルトの名無しさん :04/05/30 19:52
>>932 「日本語」と「ソース」が逆だったら賛成だが・・・
現状、あんたがおかしい
>>929 概念ではなく実装レベルで見ると
インターフェース
純粋仮想関数と仮想デストラクタだけを含むクラス
ポリシー
typedef と定数定義だけを含むクラス
かね。形だけ見ても、それをどう有効活用するか理解してないと
意味不明だから、あまり良い説明じゃないんだが。
>>927 誰かが公開してやらなきゃいけない上に
virtualじゃない基底クラスポインタを作れないという事か。
ありがとう。
>>935 どうした、なんか発作でも起こしたのか?
放置して下さい
>>916 俺の書いたソースで混乱させてしまったようですまない。
言葉が足らなかったのでとりあえず
>>862-866 にこめた
気持ちを書きます。ちょっと酔ってるのでわかりにくいかもしれんが
なんとなくこのまま放っておけないので。
ポリシーはModernC++Designで定義されている用語です。
俺がだらだら説明するなんて無駄だから知りたい方は
読まれると良いでしょう。
ポリシーもインターフェースも複数メンバがあっていいです。
どちらも意味的にわかりやすい単位でまとめていいでしょう。
>>939 のつづき
件の話の流れから、「デストラクタvirtual」と「デストラクタprotected」の
使い分けのような部分を示したかったのです。
俺の理想としてはインターフェースから導出→(当然)デストラクタvirtual
実装の再利用及び、アプリケーションの特性を示すクラス→デストラクタprotected
の気持ちを持っています。※基本APIはここでは考えません。
で、インターフェースから導出するのは
なるべく動的にクラスが扱われる場合
(一緒の配列に格納したりStateパターンを使ったりするような場合)
にするべきだということです。使用例2において配列で示しました。
動的でなければほとんどテンプレートでコンパイル時に静的解決できるだろうと
考えています。動的に使用しないなら使用例1で十分(インターフェース不要)
ということです。
こうするとインターフェースばかり(仮想関数ばかり)で
効率が下がってしまうという問題を回避できるのではないかという意味でした。
デストラクタにvirtualをつけるのを嫌がるのは効率を考えるからだ、
というふうに受け止めているからです。
>>940 のつづき
また、もし一つのメンバ関数を一つのポリシーに対応させて作っても
コンパイル時に最適化されて一つのクラスになるし、
ポリシーに分けた部分を継承で実装するならクラス数も同様に
増えると思うので、これに関してデメリットは無いだろうと思います。
ポリシーは似て非なるクラスを作りたい時にその「似て非なる」を
他になるべく影響を与えずに切り出す手段だと思っています。
えらい長文すみません。ちゃんと伝わるといいんですが。
int (*hoge)[10] = new ...; ...には何を指定すればいいでしょうか? int[10]としたらおこられました。
int* (hoge)[10] = {new int, new int, new int, ...};
それは違うだろ
>>942 int (*hoge)[10] = new int[n][10];
947 :
デフォルトの名無しさん :04/05/30 22:44
>>941 >最適化されて
これ言い出したらOOP崩壊
class sine
{
private:
int afo;
public:
void set_afo(int gaikichi);
};
void inline sine::set_afo(int gaikichi)
{
afo = gaikichi;
}
main()
{
sine arasi;
arasi.set_afo(nurupo);
}
inline ってハァ?
>928 そもそもここが分かってないような気がするので。 とりあえず、VariableNoisyShout とか自体がポリシーでしょ? >862 からの流れです。 で、>849 と >925 は主張が違ってるような気がします。 >849 は既に本人が説明されてるんでパス。 で、>925 が言いたかったのは、悪い例ではポリシーが違うことによって shout() の呼び出し方が 変わってしまうため >864 みたいに単純に hit() が作れなくなり、結果としてインタフェースまで 影響が波及しかねず(hit()自体を差し替える必要がありそう)だめぽってことでしょう。 良い例の場合は、>863-864 と組み合わせが可能ですし、何回 Shout するかも制御可能です。 まとめると「ポリシーは問題を切り分けてちゃんと作れ」になってしまいそうな気がしますが(w なお >928 のコードでは結局何回 Shout するかを制御できないですね(実装を使うユーザが)。
皆様どうも長々と付き合ってもらって感謝です。
>>849 氏の説明は、class DerivedA1 : public BaseA {}、class DerivedA2 : public BaseA {}
では、DerivedA1、DerivedA2 を BaseA* と共にしない場合でもvirtualが入ってくるが、
>>862-866 の例では、BaseA*的に扱うか否かを使用者が決める(ポリシー)だと受け取りました。
>>928 は完全に私の勘違いで申し訳ありません。
>>947 は、ナニが言いたいの?意味不明なんだけど
952 :
デフォルトの名無しさん :04/05/31 01:36
>>781 のリンク先の仮想継承のところにある
vbptrが指している仮想基本クラステーブルについてなんですが
テーブルの最初のエントリーがクラスGの場合 GdGvptrG なのですが
ここには何が入ってるんですか? GdGvptrC さえあればよさそうに見えるのですが
各仮想基本クラスへのオフセット値以外に何か必要なのでしょうか
>>949 >>925 の解説ありがとう。
実は俺、昨日読んだ時点では文脈がわかってなかったんだが、
俺のソースから始まったことだからとりあえず返信したのでした。
ちなみに
>>949 のような話なら俺はまず下記いずれかで解決を
試みると思います。どちらを取るかはアプリ次第ですね。
行数足らないのでデストラクタとprotected宣言は補完してください。
//実装側に変更を要求するが、柔軟。
template<typename S>struct IgnoreCountShoutAdapter{
void shout(int count){S::shout();}//引数ありshoutを引数なしshoutへ
};
//型爆発が起こる可能性あり。
template<int C>struct StaticCountShout{
void shout(){
int noisiness = C;
while(--noisiness >= 0) std::cout << "いて";
std::cout << "!" << std::endl;
}
};
>>950 その通り。同じ意識を共有できたと思う。
説明が足りなくてすまなかった。
>>919 ポリシーは実装を作るためのパーツ感覚なので
一般的にインターフェースより粒度は細かいだろうと思う。
件のサンプルではそういう意図ではなかったんだけどね。
多分この辺を感じ取ってくれてフォロー入れてくれたんだよな。
感謝。
955 :
デフォルトの名無しさん :04/05/31 15:25
VBで unload me はC#ではどうやるの? コントロールのボタンを押した時、Form_Closeingをして アプリケーションを終了したいのだけど。
956 :
デフォルトの名無しさん :04/05/31 15:26
亜巣万。まちがった。ごばく。
957 :
C++初心者 :04/05/31 22:23
C++の実行時のメモリの取られ方についてどなたか教えてください とある本で実行時の動作について 1.全ての割り込みを受け付けないようにする 2.ROM から RAM に初期化したデータを全てコピー 3.初期化されていないデータ領域を 0 で初期化 4.スタックを確保して初期化 5.プロセッサのスタックポインタを初期化 6.ヒープ領域を作成して初期化 7.全ての広域変数のためのコンストラクタとイニシャライザを実行 (C++) 8.割り込みを可能にする 9.main を呼ぶ とあったんですが、 "全ての広域変数のためのコンストラクタとイニシャライザを実行" とはどういう意味でしょうか? 広域変数の意味がわかりません。クラスのヘッダ内で宣言している変数のことでしょうか? そのためにコンストラクタとイニシャライザを実行ということは、 そのクラスが使われる使われないにかかわらず、 実行時にヘッダに宣言してある変数がRAM上(何領域?)に取られるということですか?
グローバル変数のことじゃね?
C++ に 「イニシャライザ」 なんて用語あったっけ?
一般的に初期化ってことじゃないの?
C++でのグローバル変数っていうのは、、、クラス外で宣言されている値ということでしょうか? そうするとコンストラクタが実行されることの意味がわかりません イニシャライザって class A { A() : a(0) { とかのa(0)のことかと思ってました
class abc {
int m;
abc() : m(0) { hoge(); }
};
abc a;
main(...) { ... };
なんてのがあったとき、main が呼ばれる前に a のコンストラクタが動くよ、ってこと
>>961
あ、そういうことですか、わかりました それ以外のクラスに関しては、実行時に呼ばれた際に初めてコンストラクタが走ってメモリが獲得されるという理解でいいんですよね? その際の呼び出し方によって、どこにメモリが取られるのかが決まると ありがとうございました
>>954 御丁寧に有難うございました。
ポリシーって、A< Policy > a; の様に使ってAの内部動作を決める事しか
目を向けていませんでした。件のコードはとても新鮮でした。
struct Base {
virtual void func1();
virtual void func2();
];
struct DerivedA : public Base {
void func1() { ... }
void func2() {} // place holder
};
struct DerivedB : public Base {
void func1() {} // place holder
void func2() { ... }
};
の様に無理に共通の基底クラスを作らなくても済みますね。
template< typename Policy > struct A;
struct Policy1;
struct Policy2;
struct Policy12 : public Policy1, public Policy2;
A< Policy12 > a
とやると複数のポリシーを適用できるかなぁと夢想中・・・