げっ通る。気持ち悪い。 gcc3.2(MinGW)です。 template <class $> class A { public: $ i; }; int main() { A<int> $; }
@(アットマーク)も通ったっけ?
bcc5.51は通んないね。 エラー E2206 doltest.cpp 1: 不正な文字 '$' (0x24) エラー E2206 doltest.cpp 4: 不正な文字 '$' (0x24) エラー E2303 doltest.cpp 4: 型名が必要 エラー E2206 doltest.cpp 9: 不正な文字 '$' (0x24)(関数 main() ) エラー E2108 doltest.cpp 9: typedef 'A<int>' の使い方が間違っている(関数 main()
f[no-]dollers-in-identifier
>>268 さすがに @ はだめなようだ。
parse error before `@' token
272 :
デフォルトの名無しさん :02/12/05 01:54
class Aをclass Bとclass Cへ継承させたいんですけど こんなエラーが出ます error C2011: 'super_class' : 'class' で示される型としてすでに定義されています。 うーーん助けてください・・・・・・
274 :
デフォルトの名無しさん :02/12/05 02:46
275 :
デフォルトの名無しさん :02/12/05 03:01
class Aとclass Bとclass Cはそれぞれ異なる3個のヘッダファイルに存在します。 class AのファイルをclassBのあるファイルとclassCのあるファイルヘインクルードし、 classB:public classA classC:public classB とすると先ほどのエラーが出ました。 今原因がわかったのですが、これは2重定義なのでしょうか? (classAが、classBとclassCの2つのファイルで定義されたことになる?) どうしてもこのclassAを他の複数のファイルにあるクラスへ継承させたいのですが かのうでしょうか?
↑訂正 classB:public classA classC:public classA です
classAのヘッダをガードしてないに一票。 #ifndef classa_h #define classa_h #endif で囲ってるか?
>>276 ヘッダーで
#ifndef ... #define ... #endif
(通称インクルードガード?)
してますか?
すみません、解決しそうです。 ご迷惑かけました
>>278-279 おっしゃるとおりやってみたところ、解決しました!
ありがとう御座いました!!
>>274 有り得ないなんて決め付けずに実験してみなさい。
cppll でその話題が出た時
ソート済み vector に対して
std::binary_search
std::lower_bound
set,multiset に対して
メンバ find lower_bound count
のベンチマークを要素数・要素の型・最適化の有無等の条件を変えて実験してみた。
STL の実装は は dinkumware, STLport の2つ。
コンパイラはVC7。
その結果
1.ソート済みベクタが速度・メモリ効率の両面で連装コンテナを上回る場面は
それほど多くはない。
2.ソート済みベクタが速度・メモリ効率の両面で連装コンテナを上回る場合でも、
その差は大きいとは言えない。
3.検索速度のみに限ればソート済みベクタが勝る場合が多いが
その差は大きいとは言えない。
となった。
結論:
More Effective STL 第23項
連装コンテナをソート済みベクタに置き換える事を検討しよう
これは大抵の場合ほとんどメリットが無いと言える。
検索速度・メモリ効率に不満を感じた場合の解決にはならない。
その場合はその他のデータ構造を考えるべきだろう。
> 有り得ないなんて決め付けずに実験してみなさい。
実験したもん。検索時間に関してだけど。(メモリ効率の測定方法がわからんない)
結果は、それぞれソート済みベクタが、
1.連想コンテナを上回る場面がある。
2.連想コンテナを下回る場合でも、その差は大きいとは言えない。
んで、1については、要素数が多い場合が該当しやすいような気がする。
2については、「比較」の処理に比べて「次の比較対象へ移動」の処理が
無視できない場合に該当しやすいような気がする。
> ソート済み vector に対して
> set,multiset に対して
そのテスト、vectorの内容をset,multisetと等価にするために、
vectorに対してどんな操作がしてありますか?
わざとそこらへんをしくじった状態でテストしたら、
http://www.tietew.jp/cppll/archive/5687 ↑と同様な結果が得られたのですが。
ちなみにテスト環境はcygwin gcc-3.2。
ってなわけで結論:
More Effective STL 第23項
「連想コンテナをソート済みベクタに置き換える事を検討しよう」
検索速度・メモリ効率に不満を感じた場合には、検討の余地が十分にある。
C++のソースを解析して クラス毎のメンバ関数名/メンバ変数名を抜き出す 手っ取り早い方法を教えてください。
VC++
いや 抜き出したクラスのメタ情報を元に処理をおこなうプログラム を書きたいんですが
perl
>>284 パーサ書くなりすればいいじゃん
たいした手間じゃない
289 :
デフォルトの名無しさん :02/12/05 12:32
map::operator[]でkeyからmapdataを探して見つからなかったとき、 自動的にデフォルトコンストラクタでmapdataが作成されて登録されますが、 mapdataがポインタの場合、mapdata==0は保障されるのでしょうか? それとも素直にfindを使うべき? ちなみにBCBで試してみたらちゃんと0になってましたが…。 そもそもポインタを入れるな、って解答はナシでお願いします。
「Koenig参照」という言葉を聞いたのですが、具体的な例が思い浮かびません。 C++の場合どのような時にこの規則が適用されるのですか?
294 :
おっぱいあげ :02/12/05 16:24
おっぱいあげ
質問
>>293 ありがとうございます。namespaceに関連する機能のようですね。
std::プリフィックスが場合によっては省略できそうですね。
297 :
デフォルトの名無しさん :02/12/05 19:26
iostreamでファイル操作しているのですが ファイルサイズはどうやって調べればよいでしょうか?
>>297 getline(strm, str, '0')でstd::stringに読み込んでからsize()またはlength()とか。
299 :
デフォルトの名無しさん :02/12/05 19:35
GetFileSize
>288 C++ フルスペックのパーサー書くのはめんどいぞ。template とか名前空間とか 絡んでくると、そりゃーいろいろと。
>>298 やはりそういう方法しかないんですか
>>300 できるだけWin32APIは使いたくないんですが
std::ifstream ifs("manco", std::ios_base::binary); ifs.get(); std::streamsize size = ifs.rdbuf()->in_avail() + ifs.gcount();
>>288 たいした手間じゃないなら書いてアップしてあげたら?
無理しなくてもいいけど。
>>296 つーか、Koenig参照がなかったら、
namespace NS {
class A {};
void operator<< (std::ostream& os, const A& a) {}
}
int main()
{
NS::A a;
std::cout << a; // ここの << は、NS::operator<< を呼ぶ
}
みたいなことはできんわな。
>>308 > namespace NS {
> class A {};
friend
> void operator<< (std::ostream& os, const A& a) {}
> }
か?
>>283 実験の結果
「なんだ、ほとんど差が無いじゃないか」というのが私の結論。
「いや、この差は大きいよ」と思うんならそれは貴方の自由。
要素数が少ない場合・要素の型が単純な場合は有意な差が無い、
場合によっては連装コンテナの方が速い場合もある。
要素数が多くその数が予測できない場合
vector は大抵の実装ではメモリを大量に消費する。
メモリ容量・要素数にもよるが、これは速度の大幅な低下をもたらす。
Effectiv STL 第23項 にもある通り、連装コンテナをソート済みベクタに
置き換えるにはいくつかの条件を満たさなければならない。
また、その条件を満たした場合でも、様々な制限が発生する。
その後の保守にも悪影響を与える可能性が大きい。
つまりソート済みベクタは守備範囲が極めて狭いと言える。
これらを考慮すると、わざわざ連装コンテナをソート済みベクタに置き換える
メリットは見出せない。
検索速度を重視する場合、ソート済みベクタを検討している暇があるのならば
まともなハッシュテーブルを使うべきだろう。
>>309 あー、マジメに書くと、
namespace NS {
class A {
friend std::ostream& operator<<(std::ostream& os, const A& a);
};
std::ostream& operator<<(std::ostream& os, const A& a) {
return os;
}
}
ですな。ま、Koenig参照の本質には関係ないということで、許してたもれ。
Koening Lookupをkoening参照と訳すのは 激しく誤解を招く気がする
検索ルール?
>310 なんで「あなたの自由」と言いつつ、 > これらを考慮すると、わざわざ連装コンテナをソート済みベクタに置き換える > メリットは見出せない。 と断言したがるかね。両者とも、もう判断するに十分な情報は出してるんだから、 そのへんで止めとけ。
連想コンテナをソート済みベクタに置き換える見返りは、
メモリ効率に関する効果がメインなのだと思いました。
検索速度については、劇的な変化は期待できません。
メモリ効率の向上は劇的なものが期待できます。
たとえば、要素数の上限が分かっている場合に、
動的メモリの使用を回避できる可能性もあります。
>>310 ×連装
○連想
この辺で止めときます。
316 :
デフォルトの名無しさん :02/12/06 05:05
C++をはじめようとおもうのですが、 フリーでC++ができるようになるソフトって何ですか? 今のところボーランドのフリーのコンパイラしかないです。 使い方もわからないです 学校の授業でC++Builderを使っていて自宅でもやりたいのですが。
317 :
デフォルトの名無しさん :02/12/06 05:08
C++Builder風で無料なものは無い
319 :
デフォルトの名無しさん :02/12/06 06:02
ぼーらんどのBCCは まず、ファイル→新規作成 で出てくる窓でプロジェクトのタブをクリックして ディレクトリ名は適当なフォルダ(自分のCの作業場所) を指定して、プロジェクト名を決める。 このプロジェクト名で指定したフォルダのしたにその名前の フォルダができる、そして、C/C++ソースタブを開いて CもしくはC++のソースファイルを適当にhello.cppとかすると ソースの編集画面がぱっと開き、そこにソースを書き できたら プロジェクト→メイクで実行ファイルがプロジェクト名の 下にできるdebugフォルダにできてる。 ライブラリのパス設定はbccの使い方説明してるサイトの 通りにしとく。
320 :
デフォルトの名無しさん :02/12/06 06:05
>>316 >使い方もわからないです
おいおいC:\borland\bcc55\readme.txtくらい読めよ
>>316 つーかフリーに頼らずに買えよ。
たった1〜2万の自己投資をケチるなよ。
borlandなら買え。 マイクロソフトなら落せ
(´-`).。oO( 今にも死滅しそうだってのに悠長だね…)
(´-`).。oO( すまん、誤爆だ…)
g++使え
327 :
デフォルトの名無しさん :02/12/06 13:47
Stroustrupマンセー! 凄いですね。
328 :
デフォルトの名無しさん :02/12/06 13:59
センセイ質問! CString hoge(int a) { CString s; s.Format("%d",a) return s; } hoge()の呼び出し元で戻り値は破壊されちゃってますか?
C++言語自体の学習だけが目的なら、VC++もBCBもいらないだろう。 Borlad-C++5.5で十分過ぎる。gcc-3.2でもいい。 しかし、そこは人情というもの、C++を覚えたらすぐにWindowsプログラム を書いて画面に表示してみたくなるに違いない。やっぱりコンソール画面 だけでは飽きる。 で、VC++でMFCか、BCBでVCLを弄びたくなるはずだ。飽きが来てやめて しまわないように、製品版の言語を買っておくとよい。また、金を払ったと いう自覚があれば、触らずにお蔵入りなんて勿体ない事もせずに済む だろう。
>>328 CString& hoge() なら破壊されるが、実体を返しているので、return文を
実行した時にコピーコンストラクタが呼び出されて、コピーを返すので
問題ない。
331 :
デフォルトの名無しさん :02/12/06 14:19
質問させてください。 ポインタのポインタの所で (void *)*a というのが出てくるのですが (void *) の意味が分りません。 何でvoidをつけるんですか? 教えてください。
>>330 CString&返しなら「戻り値」は隠しポインタであって
hoge()の呼び出し元では破壊されてないだろ
>>328 はs自体が戻り値であると勘違いしているように見受けられるが
お主もそのケあるんじゃないか?
>>331 正体不明のオブジェクトへのポインタ
(void *) なんて必要なのか?
そもそも*なんて必要なのか? &でいいじゃん。
なんだかCすら理解していないくせにC++を語ろうとする香具師が紛れ込んでるな。
気に食わなきゃchar**でもなんでも使え。
レスありがとうございます。 、、、皆さんの会話がまったく理解できません 出直してきます><
>>339 ,
>>340 struct giko { virtual void wara() = 0; };
void wara(giko& r) { r.wara(); }
void wara(giko* p) { p->wara(); }
限界とは?
>>333 そうか?「ローカル変数への参照をreturnしようとしている」というエラーが
出てコンパイルできないぞ。
>>343 コールバックとかスレッドとか使えばいやでも
ありがたく感じるよ。
>>346 あんた、関数の型を CString じゃなくて CString& にしてないか?
ごめん、何か勘違いしていたよ
333は頭がおかしい
>>347 >>349 スマソ。
> CString&返しなら「戻り値」は隠しポインタであって
> hoge()の呼び出し元では破壊されてないだろ
の意味を勘違いして、CString&返しなら破壊されないと読んでいた。
ネタ萎え。 ネタは単発糞スレでどうぞ。
>>333 は参照と値の区別が付いてない上に
「ポインタの値」の類推で勝手に「参照の値」なるものを捏造している。
多くの実装で参照がメモリ間接を利用していようが、それは
C++において参照がポインタと同等であることを意味するわけではない
第一それ以前にメモリ間接=ポインタということが言える訳でもない
>>355 では訊こう
貴殿の考える参照と値の区別とは?
328 のようなコードでは、関数の型にかかわわりなく s は破棄される。 だから関数の型が CString& では正常に返せない。 関数の型が CString の場合は、return の時点での s のコピーが渡る。 コンパイラによっては s の実体をとっておき、それをそのまま返すように最適化 するかも知れないが、漏れは見た事がない。
>>356 その前に、あんたが参照と値をどう捕らえているのか説明してくれ。
みなさんレスさんくす。 よーするにs自体は破壊されるけどsの内容は呼び出し元でも保証される…って認識で合ってますか?
(´-`).。oO(…貴殿?)
そうだね
>>361 (´-`).。oO(イタいよね、その言い方。
>>328 関数がリターンするところをステップでトレースすると理解が深まるよ。
365 :
宿題教えて! :02/12/06 15:56
#include<iostream.h> /*行列を表すクラス*/ template <class T=int,int a=3> class Matrix { T x[a]; public : Matrix(); T &set(int row,int col){return x[(row-1)+(col-1)*a];} //+演算子 friend Matrix<T,a> operator+(Matrix<T,a> &n,Matrix<T,a> &m){ int i; Matrix<T,a> ret; for(i=0; i<a*a; i++){ret.x[i] = n.x[i]+m.x[i];} return ret; } void show(); }; //コンストラクタ template<class T,int a> Matrix<T,a>::Matrix(){ int i; for(i=0; i<a*a; i++) x[i] = 0;} //表示関数 template<class T,int a>void Matrix<T,a>::show(){ int i; for(i=0; i<a*a; i++){cout << x[i] << " " ;if(i%a == 2)cout << "\n";} }
つーか、CString の代わりに、コンストラクタとデストラクタで this のアドレスを cout に投げる class を書いて実験すればいいのに。
367 :
宿題教えて!続 :02/12/06 15:56
int main(){ int length=3; Matrix<int ,3> a,b,c;//3行3列の行列 int bNumber[9] = {6,5,4,3,2,1,9,8,7}; int i; for(i=0; i<length*length; i++){a.set(i%length+1,i/length+1) = (i+1)*10;//i*10をセットする} for(i=0; i<length*length; i++){b.set(i%length+1,i/length+1) = bNumber[i];//あらかじめ用意されたbNumberを入れる} c.show(); c = a + b;//ここが実行されない c.show(); return 0; } /*C++ですが、行列のクラスをテンプレートで実現して、 + - * の演算子とinverse関数を実現せよ!とか云って来るんですよ だから・・・お願いします。教えてください。 +のとこだけでよいので・・・*/
> 365 :宿題教えて! :02/12/06 15:56 叩かれまくりたいスレ違い君の登場
>>357 まあそうなんだが
話というか因果の順序に違和感を覚えるぞ
関数の型がCStringの場合はreturn式が何であるかにかかわりなくCString型の戻り値が生成され、戻り値を初期化するコンストラクタに渡されるのがreturn式の評価結果である
関数の型がCString&の場合はreturn式が何であるかにかかわりなくCString&型の戻り値が生成され、戻り値の参照先として渡されるのがreturn式の評価結果である
hoge()の呼び出し側でCString&型の戻り値がデッドリンクになっていれば未定義動作
ポインタという用語を使うのが気に入らなきゃこんな説明だろうさ
最適化の過程の中で一時オブジェクトを削減するコンパイラは結構あるぞ
コピーコンストラクタが実行されないのにコピーコンストラクタをprivateにすると
文句たれるコンパイラ見たことないのか? 某ランドもその1つ
(´-`).。oO(…おっぱい?)
372 :
宿題教えて! :02/12/06 16:01
>>359 おまえ
>>355 か?
漏れに反問する前に
漏れを「区別が付いていない」と言い切った
ことの挙証責任を果たしてからにしろ
374 :
デフォルトの名無しさん :02/12/06 16:10
(・∀・)オオ!
「区別していない」と言い切ったことを実証するために 333がどう区別できていないかを検証したいので 333が参照と値をどう捕らえているのか聞かせて欲しいな
376 :
デフォルトの名無しさん :02/12/06 16:30
#include <stdio.h>など良く使う物をみなさんは単語登録してるのでしょうか? マジ質問です
>>375 おまえは
>>355 か?
おまえは333の時点の発言内容だけで
漏れを「区別ができてない」と断定できたんだろ
自分に揚げ足取られない自信がないからって
逃げ回ってんじゃねえよ
恥をかくのが怖ければとっとと引き下がれ
>>378 説明できないかどうか漏れの今までの発言を読み返してみろ
>>376 してません。
小説家は「目次」のハンコを持っているのか、というくらい馬鹿らしい質問。
時間がかかるのは本文。
>>376 俺もしてない。
イチイチIMEをON/OFFしたり変換候補を選択するくらいなら
そのまんま打ったほうがはやい。
333の言いたいのは、 スタック上のCStringが破棄されて不正なアドレスを指している「CString &」がちゃんと返っている、 ということ? それならそのとおりじゃん。何がおかしいのかな? ようわからん。 でも貴殿なんて言葉を使う変な奴の味方はしたくないね…。
>>383 >でも貴殿なんて言葉を使う変な奴の味方はしたくないね…。
なんだよー
煽り厨と議論の相手を区別して呼んだのが
そんなに気持ち悪かったんか?
まあ相手あってのことだ
気に入らないなら気をつけるよ
>>376 それすらタイプするのが面倒ならプログラマーやめたほうがいいよ。
その数千倍くらい毎日タイプするのが仕事なんだから。
#includeなんて全体のタイプ量の0.1%以下。
まだ初めて3日くらいだったので タイピングですね、わかりました ありがとう
間違い 386→376です
>>389 遊んで欲しけりゃ○○しろつーたら
○○しよったんで約束を守った
ちゃんと遊んでやろうとしたのに
ずいぶんつまらん香具師だったんで
結果的にああなってしまった
すまそ
333 は 383 を同意または否定してくれ。 話が決着してない。
ほかでやってよ(´・ω・`)
他でやれよ( ´∀`)
ローカル変数の参照を返すような関数はそもそもコンパイルが通らない。
int &f(int x){int *p=&x;return *p;} これはもちろん未定義だ。 「ちゃんと返っている」とか言ってる馬鹿は誰だ?出て来い
つまんねえよヴォケ( ´∀`)
蒸し返してなんだが、 「参照と値の違いって?」と聞く奴と 「参照とポインタの違いって?」と聞く奴で どちらがセンスがいいかというと、 もちろん後者。
>>397 そうか?pを返すならともかく、*pを返すのなら話は別では?
xはろーかるヴぁりあぶる
>>401 関係ない。
return *p; は x の参照ではなく、x の値を返している。
ごめん、関数の型読み違えてた。
405 :
デフォルトの名無しさん :02/12/06 21:50
以下のコードについて質問です。 -- const char* getName() const; -- const は java でいうところの final でメソッド再定義禁止というのは分かります、が、 カッコ の後の const はどういう意味ですか?
> java でいうところの final でメソッド再定義禁止 そーゆーモノは C++ にはありません。 const char* は getName() が (const char*) 型を返す事を示します。 後ろの const は、そのメンバ関数がメンバ変数を変更しない事を示します。
>>397 リンク自体がないこととデッドリンクの違いがわからない馬鹿は誰だ? 出て来い
>>399 では訊こう
const float* p = &float(1); // a
const float& r = 1; // b
aとbの違いは何だ?
↑ あんたの考えるaとbの違いは何だ? ^^^^^^^^^^^^^^ ここが訊きたい
> const float* p = &float(1); // a コンパイル通りませんけど。
何か変な風が吹き荒れてるな。
333は「未定義」を理解していないようだ さらに実装において有効であることと C++の仕様上未定義であることは別問題。 333は実装と規格という違う次元のものを完全に混同してしまっている ある実装において int &f(int x){int *p=&x;return *p;} がint f(int x){return x;}と同様に動くからといって これが規格に沿ったコードであるというわけではない いうなればコピーコントロールCDだ
>>410 なあ、それじゃ答えになってないんだよ
int a[1];
int& r[1] = { a[0] };
int* p[1] = { &a[0] };
「違い」って何だ?
>>410 もうネタはいいから真面目な質問してくれよ
ここまで粘着してるヤツも久しぶりだな
416 :
デフォルトの名無しさん :02/12/06 22:56
VBで作成したactivex.dllをVC6.0で 使用しようとしているのですが、 どうしてもスレッドクラスから呼び出すと エラーになってしまいます。 なにかやり方があるのでしょうか? (クラスウィザードを使用しCOleDispatchDriverから派生された クラスで試みてます)
>>416 釣りやネタでないならどんなエラーか書こうな。
>>417 すみません。
バンドルされていない例外は???.exe(MSVBVM60.dll)にあります
0xc0000005: Access Violation.
です。
>>413 p には代入できるけど r には代入できない。
>>413 質問の仕方がまちがっていないか(w
inta;
int&r = a;
int*p =&a;
>>420 いんや、まさしくお前さんに聞きたい質問だ
int a;
int& r = a;
int* p =&a;
int a[1];
int& r[1] = { a[0] };
int* p[1] = { &a[0] };
「違い」って何だ?
333が何をしたいのか今一分からない。 ちょっと言いたいことを簡潔にまとめてくれないか?>333
>>421 だから、コンパイル通らないものの違いを訊いてどうするんだよ。
> int& r[1] (゚Д゚)ハァ?
>>422 漏れの言いたいことは
>>369 ですでに述べ終えたが
まだ遊んで欲しそうに因縁つけてくる小僧の相手をしてやってる
CString hoge = s; CString &hoge = s; が実行されてるだけだろう。 で、s は関数を抜けるとデストラクトされるので CString& だとデッドリンクになる。 だから 369 は間違っていないが、あのように回りくどく言う必要はない。 で、それと今話してる内容と何の関係があるんだ? てっきり新しい話題だと思っていたのだが。
つーか、421 の質問が何を目的としてるのか知りたいんだが。
>>427 わからん。精神的に病んだものを感じるんだよな。なんだか。
だよなあ、質問が間違っていないかと指摘されて上での再掲だからなあ・・・。
431 :
デフォルトの名無しさん :02/12/07 00:03
じゃんけんのプログラムをつくっているのですが、コンピューターの手をランダムに 出す必要があるのでsrand()を使うのはわかるのですが #include <iostream> #include <cstdlib> using namespace std; static int pre=0;//前回の手 static int crn=0;//今回の手 extern int draw; extern int win; extern int lose; int kettei() { srand(pre*(win+lose)+draw);←()の中の仕組みを解説してくれる方がいたら教えてください crn=rand()%3; pre=crn; return crn; }
>>431 1 回のプログラム実行で srand() を 2 回以上呼ぶのが間違い。
> extern int draw; > extern int win; > extern int lose; 本気で C++ を使うつもりある?
>>431 スレ違い。C++に関わるのは、
#include <iostream>
#include <cstdlib>
using namespace std;
の無問題な部分だけ。
436 :
デフォルトの名無しさん :02/12/07 00:14
> つくっているのですが > そう書いてあった (゚Д゚)ハァ?
>>431 掻き回していない。
これだと、同じ入力をすれば必ず同じ結果になる。
>>432 疑似乱数の周期を嫌って、結果によってシードを再設定しているんだろ。
世の中にはそういうのが必要なプログラムもあるんだよ。
で、式の中身はだいたい適当でいいんだよ。
>>438 drawがどんな動きをするのか不明だけれど、
前回の手を元データにして勝ちてる手を推定しようとしているのでは?
>>440 こう書いてありますが何か?
> コンピューターの手をランダムに出す必要があるので
> シードを再設定 それが必要な理由を教えてください。
443 :
デフォルトの名無しさん :02/12/07 02:33
friendは、極力使わないほうがいいとのことですが、goto のループ2重抜けみたいに 使わなくてはいけない時って、どんな時ですか?
プライベートメンバが必要な関数オブジェクトとか・・・。
>>443 2項演算子のオーバーロードで、左右両項に暗黙の型変換を適用したいとき。
>>443 コンストラクタをpublic以外にするなど特殊な生成のされ方をするクラスのインスタンスを
生成・解放・取得なんかするのを別なクラスのメソッドで行なおうとする時。
>>443 まず、あるメソッドをprivateに保ちたい、という要求があるとする。
特別なクラス、たとえばシステムの中枢部や、デバッグ用のクラスがあり、
そのメソッドを使わなければならない、という要求が生まれることがある。
これを実現するには、そのメソッドをpublicにしなければならない。
しかしそうすると、想定したシステム中枢部やデバッグクラスではない
普通のクラスからもアクセスできてしまう。これはよろしくない。
friendを使うと、そのメソッドをprivateでキープしたままに、
システム中枢部がアクセスできるようになる。
>>443 friend を乱用してはいけない。既に言われているように
どうしても使わなければいけない場面もあるけれど、
それ以外の場面で性能を気にしないなら、
外部用にインターフェイス分けをして、見せたい部分には実体を、
「外部」には外部用インターフェイスのみのプロクシを渡すと良い。
>448 > 「外部」には外部用インターフェイスのみのプロクシを渡すと良い。 わざわざプロクシクラス作らなくても、必要なメソッドのシグネチャだけ純粋 仮想関数で宣言した基底クラスを用意してやって、それを多重継承するの が普通かと。 実装の多重継承はいろいろトラップが多いが、インターフェースの多重継承 なら、あまり問題ない。性能面でも間接参照が一回入るだけなので、タイトな ループ中で呼ぶのでなければまず問題ない。
333は逃げたか
>>449 そういえば、g++にはsigofってのがあった
453 :
デフォルトの名無しさん :02/12/07 14:54
VC++.netで、codecvt、wcin使ったことある人いますか? おれ、使ってみたんすけど、うまく変換できません。 わかる人いたら、まともに使えてるかどうか教えてください。 よろしく
454 :
デフォルトの名無しさん :02/12/07 14:55
C++にはコンテキストの概念が存在する! ?
>>454 にはコンテキストの概念が存在しないようです。
(・∀・)?
>>453 ここは言語のスレであって、VC++.netのスレではありません
他いけや
コンテキストの概念とは?
何についてのコンテキストの事を指しているのだろう?
おまえのコンテキスト(文脈)がわからん。
というわけで
>>456 に激しく同意。
460 :
デフォルトの名無しさん :02/12/07 18:50
.netとついてるスレなら山になって腐ってるだろうが。
めんどくせ
馬鹿はもういいよ。さっさと死んでくれ。
464 :
デフォルトの名無しさん :02/12/07 19:42
インドくせー
∧_∧ _ _ .' , .. .∧_∧
( ´_ゝ`) _ .- ― .= ̄  ̄`:, .∴ ' (
>>464 / '' ̄ __――=', ・,‘ r⌒> _/ /
/ /\ / ̄\-―  ̄ ̄  ̄"'" . ’ | y'⌒ ⌒i
_| ̄ ̄ \ / ヽ \_ | / ノ |
\ ̄ ̄ ̄ ̄ ̄ ̄ \__) , ー' /´ヾ_ノ
||\ \ / , ノ
||\|| ̄ ̄ ̄ ̄ ̄ ̄ ̄|| ̄ / / /
|| || ̄ ̄ ̄ ̄ ̄ ̄ ̄|| / / ,'
|| || || / /| |
!、_/ /
なんか笑えた。
468 :
デフォルトの名無しさん :02/12/08 12:01
stringstreamに出力して、出来上がった内容を2回繰り返して入力に使いたいです。 でも、seekgして2回読ませるとダメだったです。 そこで、1回目の出力の前にstrでstringに覚えておいて、 2回目以降は覚えといた奴を設定しなおしてから読ませるようにしたら、うまくいきました。 でも、出来上がった出力のサイズによっては巨大なコピーが発生すると思います。 ↑のやつよりもっと上手い方法は無いでしょうか?
469 :
デフォルトの名無しさん :02/12/08 13:15
ちょっと聞きたいんだが、コマンドラインからパラメータ受け取るとき、 例えばperlなら Getopt::Long とかがあるけど、C++でそういうライブラリって無いの? 世の中一般に出回ってるものが既にあれば、そっち使ったほうがいいなと思って。
471 :
デフォルトの名無しさん :02/12/08 13:22
∧_∧ ∧_∧
_( ´∀`) (´∀` )
三(⌒), ノ⊃ ( ) ←
>>470  ̄/ /) ) | | |
. 〈_)\_) (__(___)
∧_∧ .∧_∧
( ´∀) (´∀` )
≡≡三 三ニ⌒) .)
/ /) )  ̄.| | |
〈__)__) (__(___)
∧_∧ ,__ ∧_∧
( ´)ノ ):;:;)∀`)
/  ̄,ノ'' )
C /~ / / /
/ / 〉 (__(__./
\__)\)
ヽ l //
∧_∧(⌒) ―― ★ ―――
( ) /|l // | ヽ
(/ ノl|ll / / | ヽ
(O ノ 彡'' / .|
/ ./ 〉
\__)_)
 ̄ ̄ ̄ ̄ ̄
死ね!
じゃあ自分で作るか。どうせ大した手間じゃないし
>>472 フツーにGNUのgetoptでも使っとけば?
俺何か悪いことした??
>>474 いや・・・全然悪くないと思うけど・・・。
>>471 はAA貼りたかっただけじゃないのかな。気にすんな。
俺はgetoptにSTLの皮かぶせて使ってる。
getopt見てみたけど、C++でこのライブラリ使うのはアレだなと… C風の要素が入るとなんか嫌な感じなんで、やっぱ作る
>>477 だからラップしたらいいんじゃないの?
Argument::immediately_return(false);
Argument::check("help", no_argument);
Argument::check("version", no_argument, true);
Argument::check('o', required_argument);
Argument::parse(argc, argv);
if (Argument::error()) {
cout << "エラー" << endl;
exit(-1);
}
cout << "オプション" << endl;
for (Argument::result_type::iterator it = Argument::options().begin(); it != Argument::options().end(); ++it) {
cout << (*it).first << " = " << (*it).second << endl;
}
cout << endl;
cout << "オプションではない引数" << endl;
for (Argument::result_type::iterator it = Argument::no_options().begin(); it != Argument::no_options().end(); ++it) {
cout << (*it).first << endl;
}
↑みたいな感じで。(今一ダサい感があるのだが)
>>468 こういう事?
int main()
{
std::stringstream ss;
int i, j;
ss << 1 << ' ' << 2 << std::endl;
std::cout << ss.str();
ss >> i >> j;
std::cout << i << ' ' << j << std::endl;
ss.seekg(0);
ss >> i >> j;
std::cout << i << ' ' << j << std::endl;
}
C++のことならここで話せ!
>>480 そうそう、それでつ・・・
って、それ動かしたらちゃんと2回読めてる・・・。
なにがちがうのか調べてみます。
483 :
デフォルトの名無しさん :02/12/08 23:38
"class"ってtypenameかstructにすべて置き換え可能だと思うんだけど、合ってる? 必ずclassを書かなければなければならない所って無いよね。 いや、素朴な疑問・・・
>>483 template<template<class> class Tn> class ttp {};
2番目のclassだけは置き換え不可能と思われ。
>>484 thanks.
テンプレート引数がテンプレートの奴か・・・
見逃してた。うーん、不覚。
while( std::getline( ss , buffer ) ) { ... } という処理を繰り返そうとしてたのですが、最初のループの終了条件で、 ss.fail()な状態になってしまって、ストリームが使用不可になってた模様。 ss.clear()してからss.seekg(0)したらもっかい最初から読めました。 これにて解決。
C++の標準ライブラリのストリームは、一旦failbitやeofbitが立ってしまうと、 seekしてもこれらのフラグはクリアされず、明示的にclear()してやる必要が ある。 CからC++に移ってきた人は大抵一度はここで引っ掛かるようだ。
488 :
デフォルトの名無しさん :02/12/09 03:57
継承についてお聞きしたいんですが class Aとclass Bがあり、Aの中にはprivateでCというメンバが あったとします。このときmainでAとBのオブジェクトを生成し, Bのオブジェクト内のメンバ関数からAのオブジェクト内のCに アクセスしたいときどうすればいいんでしょ?
489 :
デフォルトの名無しさん :02/12/09 04:04
>>488 class Aの中にfriend class Bを埋め込むとか?
どのあたりが継承の話なんだろうか。。。?
class A{ friend class B; int c; }; 友達になっておけば、BからはAの中は見放題。 #なぜに継承?
492 :
デフォルトの名無しさん :02/12/09 04:12
class A { friend class B; } class B : public A ←多分このあたりじゃない? { }
493 :
デフォルトの名無しさん :02/12/09 04:14
>>490 >>491 すみません全く継承の話じゃないですね。
friendが関数以外に使えるとは知りませんでした
早速やってみます。
>>492 もしそうならfriendの必要はないな…。
class A
{
protected:
int C;
};
class B : public A
{
foo() { C = 0; }
};
495 :
デフォルトの名無しさん :02/12/09 12:06
すみません、下記のコードがコンパイル時にエラーになるような、 「クラスじゃなくて実体に対して定義されるイテレータ」のようなものはないですか? なんでこんな怖い仕様にしとくのかなと思って・・・ #include <string> #include <iostream> using namespace std; void main() { string a, b; a = "abcde"; b = "f"; for (string::iterator i=a.begin(); i!=b.end(); ++i) ←このb.end() cout << *i; }
>>495 それはC++には期待できないだろう。
STLportのデバッグモードで実行時エラーにするのが精一杯かと。
497 :
デフォルトの名無しさん :02/12/09 12:34
c++で pop3に接続して list取得して 文字は化けててもいいからメールを見る というだけのプログラムって結構コード長くなるんですか? perlだと、数行で実現してるの他スレでみたけど やっぱりc++だとめんどいんですか?
>>497 C/C++の場合、言語仕様にそういうのは含まれてないので適当なライブラリを使います。
使うライブラリはOSやコンパイラ、その付属ライブラリに依存します。
PerlとC++を同列にしないで欲しいなぁ。
C++Builderみたいに簡単にWindowsアプリを作れない言語だろ?
>>497 Perlだってライブラリ使ってるか外部コマンド使わないと数行にはならない。
その辺用意すればC++だって手間はあんまり変わらん。
言語仕様上多少ソースコードは長いかもしらんが。
500ゲットね。
>>495 「実体」というのは実行時に定まるものだから、コンパイル時に決定するのは無理だ。やるなら、
template<typename Cont, typename Func>
void for_each_c( Cont& c, Func f ) { std::for_each(c.begin(), c.end(), f); }
を常にかますようにして気をつける、程度だろうねぇ。
>>498 なるほど、解説どうもです。
Winsockをいかに使うかが味噌なんですね。
UNIXだとsocketをうまく使いこなせと。。。
503 :
デフォルトの名無しさん :02/12/09 16:40
C++おもしろいあげ
boostでSocketライブラリの実装が始まってるね。 かなーり、期待してます。
えっsocketライブラリって標準であるようなものじゃないの?
507 :
デフォルトの名無しさん :02/12/09 19:50
g++のコンパイル結果のオブジェクトコードが, gccでのオブジェクトコードに対して大きくなりすぎて困っています. オブジェクトコードが小さくなる様に, コンパイルする方法ってあるでしょうか? パソコン初心者板総合質問スレッドVol.235から 誘導されてきました.
gcc, g++ で int main(){} をコンパイルしてみた -rwxr-xr-x 1 tohkubo tohkubo 13548 Dec 9 19:53 g++.out* -rwxr-xr-x 1 tohkubo tohkubo 13298 Dec 9 19:53 gcc.out* 確かにg++の方が大きいな(w
>>508 私の環境だと,g++.outが 60kB, gcc.out 24kBになります.
実際にコンパイルする必要があるプログラムでは,
サイズに10倍以上の差が開くのですが,
NFSでファイルサーバ上でコンパイルするため,
この差がコンパイル速度に致命的な影響を与えます.
/tmp/は容量が少なすぎて,オブジェクトコードを格納するのに足りません.
>>509 #include <iostream>とかすると、それだけで膨大な量の継承をリンクするので
大きくなるぞ。だから、小さくしたければC++標準ライブラリをできるだけ使わない
ようにするしかない。
ちなみに strip かけるとこうなる。 -rwxr-xr-x 1 tohkubo tohkubo 3244 Dec 9 20:33 g++.out* -rwxr-xr-x 1 tohkubo tohkubo 2972 Dec 9 20:33 gcc.out* でもコンパイル速度じゃぁ strip 意味無いねぇ。 # なんか user 名を晒してしまった事に今更気付いた・・・
コンパイルオプションに -g 付けてると gcc より g++ の方が大きくなるよ
ソケットライブラリって・・・I/Oストリームのクラス階層に組み込んだりするんだろうか。 basic_socketstreambuf とか basic_isocketstream とか・・・ UDPはダメか。
gccでもコンパイル出来るプロジェクトならgcc使っとけ
strings の結果を diff とってみますた
/lib/ld-linux.so.2
__gmon_start__
-libc.so.6
+libstdc++-libc6.2-2.so.3
+_DYNAMIC
+_init
__deregister_frame_info
+_fini
+_GLOBAL_OFFSET_TABLE_
+__register_frame_info
+libm.so.6
_IO_stdin_used
+libc.so.6
__libc_start_main
-__register_frame_info
+_edata
+__bss_start
+_end
GLIBC_2.0
PTRh
>>512 今は -g は関係無いかと。
# って俺のやってる所もかなり関係無いに近いけど(w
RTTIの情報が入っているのかなあ。
>>510 CからC++に乗り換えた理由がSTLだったので,
標準ライブラリできるだけ使わないというのは,
何だか哀しい気分です.
>>511 stripしたら1/6以下に小さくなりました.
コンパイル後にstripで小さく出来るんなら,
コンパイラが吐くファイルを直接小さくして
おく事は可能なはずですね.
何か余計なオプションつけてるんですかね.
>508 バイナリサイズを比較するなら static link にしないと、意味がないような。
>517 > コンパイラが吐くファイルを直接小さくして > おく事は可能なはずですね. んなわけない。 オブジェクトファイルからシンボル名を消し去ったら、どうやってリンク時に名前を 解決するのやら。
>>509 > NFSでファイルサーバ上でコンパイルするため
これがそもそも間違い。コンパイラを動かしてるローカルマシンに
ビルド環境を構築すべし。CVS などのソース管理ツールを使って、
リポジトリはファイルサーバーに置いて共有するようにすれば、
バージョン管理もできて一石二鳥だ。
>>518 イヤ、オイラのはただのお遊びなので・・・
リンク情報とかチョット違うゼって、それだけのお話でございまして・・・
重箱の隅をつついて遊んでるだけでござりますれば・・・
>>522 一般ユーザーなので,ローカルマシンへの書き込み権限は
/tmp/しかないのですが,/(/tmp/)に割り振られている
ディスク容量は何故か13MB程度しかありません.
(ハードディスク全体では4GBあるのに..)
ちなみに使ってるマシンはCOMPAQのalpha系CPUで,
Digital UNIXが入ってます.
システム構築したのは確か,COMPAQの方々だったと思いますので,
なんで13MBにしたのか,というツッコミはしないで下さい.
>>507 何故素直にホームディレクトリを使わないの?
もしホームが一杯なら NFS の方にホームにあるいらなそうなファイル群を移
したらダメなん?
まぁそれがダメなら NFS に直吐きもやむなしですなぁ。
>>522 何故なら,/homeへの書き込み権限が無いからです.
>522 ファイルがローカルか NFS サーバ上かで、コンパイル時間にそれほど差が 出るかねぇ……。ウチは NFS のサーバ上にホームディレクトリ置いてあって、 そこで作業してるけど、それほど困ってないぞ。 >507 ファイルサーバーの性能が足りんか、キャッシュ周りのパラメタチューニングが イマイチか、ネットワーク混みすぎてるんじゃないのか? どっちにしても gcc で云々するよりは、ネットワーク管理者捕まえるのが正道と思われ。
つーか/tmpが13Mってかなりヤバくないか?
>>527 NFS上でコンパイルした場合に一番時間がかかるのが,
ldの実行部分なのですが,小さいファイルで
/tmpとNFS上ででldの実行時間を比較すると,
/tmpの方が圧倒的に早かったです.
>ネットワーク管理者捕まえるのが正道と思われ。
ネットワーク管理者に聞いてみることにします.
>>527 データを 1 バイトくらいでちょこっとずつ読み書きしようとすると、NFS は速度が
ガタ落ちしたと思ったが。
>>531 ハードディスクは逼迫(ひっぱく)してるのに,
メモリは余裕という意味で書きました.
C++と関係なくなってきましたね.
>>532 gccのldはg++のldに対して,NFSでも非常に早かったので,
gccとg++で違うldを使ってるって事でしょうか.
それとも,gccとg++で,ldに渡すデフォルトの
オプションが違うとか?
g++でコンパイルするとcrt0がC++版になる と嘘を言ってみる
536 :
Stroustrup FAQ! :02/12/10 19:12
537 :
bloom :02/12/10 19:12
538 :
デフォルトの名無しさん :02/12/10 20:58
>>538 # 何のコンパイラを使ってるかくらいは書いた方がいいぞ。
多分 int (たぶん4Byte) * 1000000個 = 4MB もローカル変数に
割り当てられなくて死んでいるのだろうから、
・static を付ける
・グローバルにする
・new で動的に確保
のどれかをすれば解決する。
>>539 ありがとうございます。
よくわかりませんが本を読んで勉強してみます。
コンパイラは・・・VC++って書けばいいのかな?
ちなみにintは4バイトです。
>>539 とりあえずint型の変数を全部グローバルに定義したら
計算はしてくれました!!!(速度はVBよりも遅かったですが・・・)。
ありがとうございます!!!更に勉強する気になった!!!
>>538 バグとは関係ないところでいろいろあるが
>for(j=2*i;j<=l;j++){
>if(j%i==0){
>p[j]=0;
これはないだろ。そんなわけでちょっとかえてみた
#include <iostream>
#include <fstream>
#include <cmath>
const max=10001 ;
main() {
bool p[max];
int k=int(std::sqrt((double)max));
std::ofstream fout("素数.txt");
for(int i=2;i<max;i++) p[i]=true ;
for(int i=2;i<=k;i++) if(p[i]) for(int j=2*i;j<max;j+=i) p[j]=false ;
int c=0 ;
for(int i=2;i<max;i++) if(p[i]){
fout << i << '\n';
c++ ;
}
std::cout << "素数は全部で" << c << "個です" << '\n';
fout.close();
}
> 速度はVBよりも遅かった ・・・一体何をしたらそんな事になるの?
> 速度はVBよりも遅かった ワロタ
ヽ(・∀・)ノ VB>>>>>>>>>>>>>>>>>>>>>>>>>>VC
>>542 速い!!!
それだ同じアルゴリズムなのにしこたま速い!!!
驚いた!!!これがCの凄さの一つか!!!
>>545 うんこ
>>546 うんこはおまいのソースコード
↓これを解説してくれよ
> 速度はVBよりも遅かった
548 :
デフォルトの名無しさん :02/12/11 00:43
>>546 素数を求めるのでしたら、エラトステネスの篩という方法を
試してみては?
549 :
デフォルトの名無しさん :02/12/11 00:44
(´-`).。oO(タイトルのC++って一体・・・)
何が問題?
例えばstd::bitsetとか使え。
(´-`).。oO(std::bitset使わなければC++ではないと。。。)
素数格納するのに、bitset と set ではどっちが効率いいんだ?
(´-`).。oO(変なのが来たな。。。)
(´-`).。oO(何か粘着君が一人居て嫌だな。。。)
>551-557 ( ´д)ヒソ(´д`)ヒソ(д` )
559 :
引き篭もり :02/12/11 14:27
あらやだあの人引き篭もりじゃないの? ( ´д)ヒソ(´д`)ヒソ(д` ) ほんとよね 最近は変な人増えたものねぇ。
560 :
デフォルトの名無しさん :02/12/11 18:45
std::valarrayでMatrix計算はできますか?
>>560 出来ますけど面倒です。std::valarrayは一次元配列に最適化されています
ので、二次元以上の配列を扱うのが下手です。
二次元配列と見なしてアクセスするにはstd::slice、二次元以上の配列には
std::gsliceをstd::valarrayに適用すればよいが、面倒。
m(_ _)mサンクスです。
カンマ演算子のオーバーロードなんて初めて見たよ・・・
>>564 ちょっと思いつかないんだが、どういう風に使われてる?
>>565 行列の値設定
m =
1, 2, 3,
4, 5, 6,
7, 8, 9;
とか。
プロトタイプはどう書くの? 組み込み型のオーバーロードってできないんじゃ?
class array;があるとして array &array::operator=(int); array &array::operator,(int); みたいになってるから組み込み型は関係ない
>>567 たぶん、カンマ演算子は = より優先順位が低いので
a = b, c は (a = (b , c)) でなくて ((a = b) , c) と解釈される
ことを忘れていると思われ。
ああ、そういう事か。理解した。
>>567 > 組み込み型のオーバーロードってできないんじゃ?
話題とは関係ないけど、逆にこれを利用して組み込み型と
ユーザ定義型を見分けるtemplateってのを見つけたよ。
かなりトリッキーだけど。
>566 久しぶりに C++ の深淵を覗いたような…… (落とし穴にはしょちゅうハマってるが)
>566 久しぶりに C++ の深淵を覗いたような…… (落とし穴にはしょちゅうハマってるが)
>572,573 aboneユーザでつか?
575 :
デフォルトの名無しさん :02/12/11 23:48
C++で、データを壊さずに配列の動的割り当てのサイズ変更は どのようにするのでしょうか? VBでいうと、 Dim a() Redim a(10) Redim Preserve a(20) Redim Preserve a(5) みたいな処理をしたいのですが・・・
>574 そうです。多重カキコごめん。
577 :
デフォルトの名無しさん :02/12/11 23:56
>>575 特にないので、新しく新規サイズで new[] して、そこに古いデータを
コピーして、古い領域は delete[] する。
配列用のコピー・コンストラクタを作っておくと便利。
std::vector なら resize() メンバ関数を使おう。
578 :
デフォルトの名無しさん :02/12/11 23:57
>配列用のコピー・コンストラクタを作っておくと便利。 意味不明だった。この行はなかったことにしてほしい。
579 :
デフォルトの名無しさん :02/12/11 23:59
すんません・・・。 VB厨なんですが、C++を勉強してまして、質問させてください。 VBだと配列をとりあえず Dim a() as long と定義しておいて、後で値を確保しつつ配列の長さを変えることの出来る宣言 ReDim Preserve a (10) as long ってのがあります。 これと同等なことがC++でできないものでしょうか・・・。
>>579 new[]はdelete[]とペアにして使うために、ヒープ領域に配列の大きさを覚えて
おくようになっているので、Cのrealloc()のような事は無理。
新たにnew[]して、転送するしかなかろう。それから、new[]したらデフォルトコンスト
ラクタが呼び出されてしまうので、この事が動作に悪影響を及ぼさないように注意
を払う必要がある。
あ、575が同じ質問してたのか・・・すみませんでした。 逝って来ます。
#include <vector> C++だととりあえず std::vector<long> a; と定義しておいて、後で値を確保しつつ長さを買える a.resize(10); とすると良い。
>>577 やはりコピーしかないのですね。
VBも何気に見えないところでコピーしてるのかな。
ありがと!
>>579 組み込みの配列じゃなくて、std::vector をつかえ
>>579 組み込みの配列じゃなくて、std::vector をつかえ
C++ は何でキーワード renew を用意しなかったんだろう・・・。
>587 C++ では配列は見捨てられた存在ですから。おとなしく vector 使いましょう。
>587 C++ では配列は見捨てられた存在ですから。おとなしく vector 使いましょう。
キーワード renew はないが、renew と呼ぶにふさわしいものはある。 それは placement new だ。
なんかエコーがかかってるスレだな
Abone使いがいると見える。
なるほど、placement newの方がいいかもしれない。 delete[]するとデストラクタが呼び出されてしまうので、転送した後これが動くと 妙な事になる恐れがある。 そこへ行くとplacement newした領域をdeleteしても自動的にはデストラクタを 呼び出さないのでいいかも。
>>587 初期のC++には例外が無く、newは0(NULL)を返すことで
エラーを表現できたが、renewは…
>>588 。・゚・(ノД`)・゚・。
>>591 その領域の確保には malloc() とか使うの?
あと配列を縮めたい時、どうやってデストラクタ呼ぶの?
renew には、要素が増えた時その分だけのコンストラクタを呼び、要素が減った時には
その分だけのデストラクタを呼び、領域確保は基本的に自動である事を期待したい。
・・・それって結局 vector と似てるけどさ。
>>594 そうか、そういう問題があったのか・・・。
間違えてる。 >591 は 590 宛て。
>>595 > あと配列を縮めたい時、どうやってデストラクタ呼ぶの?
どうやってって、普通に呼べばよいのでは。
1 コずつか?
599 :
デフォルトの名無しさん :02/12/12 10:14
y'=x+y, y(0)=1のとき、2段法(k=2)のアダムス・バッシュフォース法を用いてy(1)を求めよ。 なお、hの値と2つめの初期値は、 ・h = 0.5, y(0.5) = 1.7974425414 ・h = 0.1, y(0.1) = 1.1103418362 ・h = 0.05, y(0.05) = 1.0525421928 ・h = 0.01, y(0.01) = 1.0101003342 ・h = 0.005, y(0.005) = 1.0050250417 ・h = 0.001, y(0.001) = 1.0010010003 についてそれぞれ計算すること。 プログラム。 各hについての計算結果と誤差。 計算方法がわかりませんどなたか教えていただけませんか
∧_∧∩ ( ´∀`)/ ___∧__________ 先生、質問です。 物凄い初歩的な質問ですみません。ランダムに0から9999 の整数を、(理論的に)等確率で出したいのですが、 for(k=1;k<10000;k++){ (int)i=10000*(float)rand()/(int)RAND_MAX; } これでは、(その範囲のものは)出ませんよね。どうしたらよいのでしょうか?
AA がズレているので失格
602 :
デフォルトの名無しさん :02/12/12 11:12
>>600 0〜RAND_MAXまでは、(RAND_MAX+1)個の要素があるので、
(RAND_MAX+1)で割るのがよろしいかと。
∧_∧∩
( ´∀`)/
___∧__________
>>600 先生、早速ありがとうございます。これから、がんがって、
勉強します。
>>601 (´・ω・`)
∧_∧∩
( ´Д`)/
___∧__________
>>602 先生、間違えて、自分にお礼してしまいました。
勉強しても、こういう間違いは直りませんか?
>>595 いや、renew っていう言葉の意味を考えると VB の ReDim のようなものは
ふさわしくないって言いたかったんだけどな。
っていうか、どう考えても std::vector か、その模倣品しか考えられんから
素直にあきらめた方がいい。
昔からヴァカは氏ななきゃ治らない、と申します。
>>600 徐々にC++のキャストについても知りましょう。
608 :
デフォルトの名無しさん :02/12/12 15:07
template <class T> void redim(T *array, unsigned long arraySize, unsigned long newSize) { unsigned long copySize = (arraySize > newSize) ? newSize : arraySize; T *newArray = new T[newSize]; std::memcpy(array, newArray, copySize); delete[] array; array = new T[newSize]; std::memcpy(newArray, array, newSize); delete[] newArray; } でいいんでは。VB でも内部的に似たようなことをしているんじゃ? コンパイルしていないんで動作確認はしてないけど。 unsigned long oldSize = 10; int *a = new int[size]; unsigned long newSize = 3 でも 20 でも; redim(a, oldSize, newSize); で VB と等価かと。
609 :
デフォルトの名無しさん :02/12/12 15:11
あ、std::memcpy の引数が逆だ。 正しくは、それぞれ std::memcpy(newArray, array, copySize); std::memcpy(array, newArray, newSize);
C++ must be supreme language! so, I believe firmly it!
C++ must be chou-creme language! so, I believe delicious it!
>>600 int a[10000];
for(int i=0;i<10000;++i){ a[i]=i; }
std::random_shuffle(&a[0], &a[10000]);
これで a の中身を順番に使えば等確率だけど、どう
以下の設計について教えてください。 template <typename X> class AAA { private: X mem1; }; があった時、 class BBB { private: AAA<case1> mem1; public: }; class CCC { private: AAA<case1> mem1; AAA<case2> mem2; }; 等のように、AAA をメンバ変数と持つようなクラスを設計したいのですが、変数の数が固定されていません。 どのように設計するのが一番スマートなのでしょうか?思いついたのは、AAAの基底クラスを作って、 BBBでvector<AAA_BASE> *mem として、BBBを定義してから、vector<AAA> mem(2)等 のポインタをBBBに渡す 事なのですが。もっとスマートに出来ないでしょうか?
Win32SDK のようにキャストがボロボロでるプログラムでも C++ キャストを 使わなきゃいけないかい? むしろ可読性下がると思うんだけど。
> AAA<case1> mem1; > AAA<case2> mem2; これがどうして必要なのか知りたいけど。
>>614 ボロボロと言っても、実際キャストが必須なのって
GDIオブジェクトのHANDLEと、メッセージ系のLPARAMと
コールバックパラメータのvoid*からの取り出し、
ぐらいでない?最初のは普通C++のクラスでラップするし、
二番目はreinterpret_castした方がわかりやすくていいし、
三番目もstatic_castって書いた方が読みやすいと思う。
あとconst_castが大量に必要になるが、
あれを他のキャストで表現すると余計冗長だし。
>>616 const_castなんかどこで使うの?
>614 C++ を使ってるのに SDK 直ってのが考えにくいが。だいたい ATL::CWindowImpl なり何なりのフレームワークを一枚かぶせるでしょ。 C++ キャストに関しては、俺は場合によりケリだなぁ。一行に複数の cast が入る 場合、特に reinterpret_cast + const_cast が必要になる場合とかは、C++ キャス トだと行が長すぎて却って読みにくくなるから C スタイルキャストで済ませる。
static_cast<T>(x) って書くのが長いからって T(x) と書くのは OK?
620 :
デフォルトの名無しさん :02/12/13 12:19
どこかに整数演算だけで浮動小数点演算をエミュレートしてる C か C++ の ソースとか落ちてないでしょうか(勉強用)。
>>618 APIを直で叩くケースが少ないBCBな俺の場合、
旧式キャストは一切使わないなぁ。
可読性も大切だけどコンパイルエラーのほうがもっと大切。
つーかキャストって思ったほど使ってないなぁ。
フォーム2つにつき1回つかう位のペース。
ちなみに手持ちのプログラムで一番大きなものにgrepかけてみたらこんな感じ。
static_cast 3個
dynamic_cast 11個
reinterpret_cast 3個
const_cast 0個
組み合わせたものは0個
おりょ、const_castを一番使っていると思っていたのに我ながら意外な結果が…。
>>613 何をやりたいのかわからないけれど、そのコードは明らかに異常。
何か根本的に間違っていると思われます。
まずは何をしたいのか、どうしてそのコードが必要になったのか、書いてみそ。
> const_cast 0個 > おりょ、const_castを一番使っていると思っていたのに ちょとワラタ
つーか、わざわざ4つも予約語増やしてキャスト導入した意味ねえだろが。 アフォか。
>>625 gotoがあればbreakなんかいらん、と言っているに等しい発言だな。
んー? 625 は、「わざわざ 4 つも予約語増やしたんだからちゃんと使え」 という意味か?
>>629 単純に 「4 つも予約語増やして導入した意味なんかない」 という風に取れたんだが。
631 :
デフォルトの名無しさん :02/12/13 18:18
VC6でSTLportを使うときにあるシンボルを定義していると, cmath等のインクルード時にC標準ライブラリをstd名前空間に 押し込んでくれたように記憶しているのですがどなたかご存知ありませんか。 ドキュメントやstl_user_config.h,_site_config.h等調べてみたのですが 一向にわかりません。
template 統合スレのネタだな。 スレ違い。
>>630 そうか。スマソ (ノД゚)
引き篭もりなんで許してくれ。
>>632 申し訳ありませんでした。そちらに行ってみます。
>>633 生まれも育ちも東京都江戸川区ですが何か?
インラインが淫乱を連想させて困るのですが何とかなりませんか?
もっと乱rていxhgkい
回答は日本語でお願いします。
I love to play C++ programming!
長文ですんません。株式売買のシミュレーションっぽい事を行いたいのです。 class 内部自由度1 {}; ... class 内部自由度N1 {}; class トレーダー1{}; ... class トレーダーN2{}; class 全体{}; void func(全体*){} で内部自由度がN1個あって、N2人のトレーダーが個性を持って、1...N1の内部自由度を適当に持つとします。 N2人のトレーダーが全体クラスに集まって、互いに影響を受けながら関数funcでやり取りを行いたいのです。 トレーダーが持つ内部自由度の個数が色々変わるのでどうしようかと悩んでいます。トレーダークラスに基底クラス(vector<基底内部自由度>持ち) を作って、継承させてコンストラクタの書き方を変える事でトレーダークラスを作るのがいいかな?と思ったのです。 最終的には、全体クラスにトレーダー以外の人間も入れたいのです。設計がダメダメなのでしょうか?
>641 > 設計がダメダメなのでしょうか? はい。
そうですか。もう少し考えてみます。
自律行動するロボットのシミュレータと似てる?
そちらの事は知りませんが、異なる内部自由度を持った複数の関節が互いに協調し合って 歩行を実現するシステムなら似ていると思います。
646 :
デフォルトの名無しさん :02/12/15 11:15
独自にクラス作るのが意外と大変なんで STLか何か使って簡単にプロパティ型出来ませんか?
648 :
デフォルトの名無しさん :02/12/15 11:32
>>646 プロパティ型って何?教えて君でスマソ。
649 :
デフォルトの名無しさん :02/12/15 11:32
こんな感じの奴です。 struct A { int param1, param2; public: class prop { A& ref; public: Prop(A& a) : ref(a){} int operator = (int s){ return ref.param1 = s > 0 ? s : 0; } operator int (int s){ return ref.param1; } }Prarameter1; ・・・Prarameter2; }; Get、Setを一つにまとめてシンプルにしたいので。
>>649 は間違いだらけですが、
ようはSetPrarameter1、SetPrarameter1の動作をまとめて
obj.Prarameter1 = -1;
count << ob.Prarameter1 << endl;
見たいな使い方が出来るようにしたいのです。
>646 Cプリプロセッサを使え
>>651 調べました。__declspec(property)ですね?
ありがとうございまし。
reference counter!
654 :
デフォルトの名無しさん :02/12/15 18:23
>>651 C++ では、インクルード・ガード以外、マクロは極力使わないこと。
定数の定義やマクロ関数の定義等はもってのほか。
>>652 __declspec(property) って C++ 言語じゃないんですけど。
やるなら、
TSomeType& Parameter();
というメンバ関数にする。
>>654 是非マイクロソフトさんにも言ってあげてください。
>654 > TSomeType& Parameter(); それだと問題が全く解決しないと思うが…。プロパティ化したいメンバ変数が一つなら 良いけど、複数あったら NG だよね。 現実的な解としては、マクロ使うのが比較的マシな回答だと思う。他に Loki の Tuple を使うって手もあるが、あまりお奨めはせん。
こんなんどうよ。 // property.h template<class T, class O, T O::*M> class property { O &obj; public: property(O &o) : obj(o) {} property& operator=(const T& x) {obj.*M = x; return *this;} operator const T&() const {return obj.*M;} operator T&() {return obj.*M;} };
// proptest.c #include <iostream> #include "property.h" class foo { int a; public: property<int, foo, &foo::a> x; foo() : a(0), x(*this) {}; friend ostream& operator<<(ostream &os, const foo &f) { return os << "foo<" << f.x << ">"; } }; int main() { foo f; cout << f << endl; f.x = 10; cout << f << endl; }
>>658 それ漏れも考えて書こうと思ったけどやめた。
値の範囲チェックとかどうすんのよ?
>>657 しかもそれだけでいいのなら
template<class T>
class property {
T obj;
public:
property() : obj(T()) {}
property& operator=(const T& x) {obj = x; return *this;}
operator const T&() const {return obj;}
operator T&() {return obj;}
};
でいいんじゃないか?
>>659 これじゃダメ?
class foo
{
int a;
class prop1 : public property<int, foo, &foo::a> {
typedef property<int, foo, &foo::a> super;
prop1& operator=(int s) { if (s < 0) s = 0; super::operator=(x); return *this;}
};
prop1 x;
}
>>660 それだけでいいのなら
property<T> の代わりに T でいいんじゃないか?
#include <boost/bind.hpp>
#include <boost/function.hpp>
template<typename T>
class property {
boost::function<T> getterFunc;
boost::function<void, const T&> setterFunc;
public:
template<typename Owner, typename G>
property( Owner& p, G g )
: getterFunc( boost::bind( g, p ) ) {}
template<typename Owner, typename G, typename S>
property( Owner& p, G g, S s )
: getterFunc( boost::bind( g, p ) )
, setterFunc( boost::bind( s, p, _1 ) ) {}
public:
operator T() const { return getterFunc(); }
property& operator=( const T& rhs ) {
setterFunc( rhs ); return *this;
}
};
>>663 思いっきりテンプレートに見えるのは、気のせいか?
setX, getX でいいでしょ なんでわざわざそんな不要なコード書きたがるかね
>>665 私はいろいろやって(C++でのプロパティを)諦めた人なので
> setX, getX でいいでしょ
は同意だけど
> なんでわざわざそんな不要なコード書きたがるかね
これ、コボラーの発想だよ。
いいものがあればそれを求める。それが ぷらぷら使いさ。
667 :
デフォルトの名無しさん :02/12/16 12:49
virtual void* Create()=0; この、末尾の「=0」ってどういう意味?
>>667 pure virtual function・・・・・・
669 :
デフォルトの名無しさん :02/12/16 13:15
ヘッダファイル(拡張子が .h)のファイルの中で、こんな一行が class ISerialize; ソースの後の方で、ちゃんと class ISerialize { public: .. } というように、定義されているのですが、最初の方で 「class ISerialize; 」と書く意味がわかりません。 どういう意図があるのでしょう。 これは省略できるのですか。
> class ISerialize; ここから >class ISerialize { >public: >} までの間で ISerialize *p ; とかやったりするため
Do you know declaration of class?
class ISerialize; class Test { class ISerialize& is; }; class ISerialize { public: .. }
>>672 class ISerialize;
class Test {
class ISerialize& is;
};
class ISerialize {
public:
Test *t; //ここがなけりゃ意味ないだろ?
}
海外サイトで通用しなかった英語を 避難先の日本語サイトでひけらかして何になる? (water
>>673 >Test *t;
は参照よりも実体のほうが趣旨に合うと思うが
677 :
デフォルトの名無しさん :02/12/16 14:26
virtual int GetType() const = 0; これはつまり、サブクラスは必ず GetType() で値を返して、しかも、そのサブクラスのサブクラスでは、GetType() をオーバライドできない、ということでしょうか。
>>677 サブクラスって意味知ってる?
まあそれはそれとして、純粋仮想関数を一つでもメンバとして持っているクラスは
抽象クラスとなり、インスタンスは作成できない。
かならず継承して、純粋仮想関数をすべてオーバーライドして初めてインスタンス
を作成できるようになる。
>>677 こんな物だと思いたまへ。
class A {
protected:
int i;
int j;
public:
virtual int f() = 0;
int g() { return j; }
};
class B : public A {
public:
int f() { return i; }
};
int main()
{
// A a; // インスタンスは作成できない
B b;
b.f();
b.g();
}
683 :
デフォルトの名無しさん :02/12/16 15:17
純粋仮想関数のメリットって何ですか?
>>683 インターフェースと実装を切り離す時に便利。入出力関数が決まっていて、
実装にバリエーションがある時、インターフェース部だけを抽象クラスにして
おいて、一種のテンプレートのようにして使う。
ところでこの板、連続書き込みが規制されてない? 今は串を変えて書いてるけど、プロキシ使ってる人は、まとめて規制食らっ ちゃうよ。
>>684 ありがとうございます。よく分かりました。
void penis_fumble(){ (;´Д`)ハァハァ; }
gotcha!
>>683 メンバ関数のグループ化と規格化
「○○対応をうたうクラスにはこんな関数セットを用意すること」
690 :
デフォルトの名無しさん :02/12/16 17:52
class A { }; class B : public A { }; というのがあり、 A* boo(A* obj); という関数なら、クラスAクラスBのどちらのオブジェクトもとれるのは分かるのですが、 A& boo(A& obj); なら、Aしか引数,戻り値にすることはできませんか?
やってみりゃいいだろ B b; A& boo(A& obj) { return b; } main() { boo(b); }
すいません。聞きたかったことを間違えました。 A boo(A& obj) { B b = new B(); return b; } という場合に、bを返したら、どうなりますか? 外で B b = (B)boo(obj); みたいなのはできないんでしょうか?
return *b;
どうでもいいが激しくわかりづらいソースだな。AとかBとか。
>693 実体を基底クラスにキャストするとオブジェクトのスライシング、派生クラス分の オブジェクトが捨てられて基底クラスに詰め込まれる、が起きる。 ポインタ・参照の場合は(多重継承・仮想継承が絡むと細かいことが色々あるが、 それを忘れれば)何も起こらない。 class Base {}; class Deriv : public Base {} Base* pb = new Deriv; // OK 特に Base に仮想関数が定義してある場合、pb 経由で仮想関数を呼び出すと Deriv の関数が呼ばれる。 class Base { public: virtual void foo(); }; class Deriv { public: virtual void foo(); }; Base* pb = new Deriv; pb->foo(); // Base::foo() ではなく Deriv::foo() が呼ばれる 逆に基底クラスから派生クラスにキャストするのは、実体の場合には論外。ポインタ・ 参照の場合には「実はそのポインタ・参照は派生クラスを指している」という場合に限っ て OK。そうでない場合には、直後にメモリ領域壊すことになる。 Base* pb = new Deriv; Drive* pd = static_cast<Deriv*>(pb); // OK Base* pb = new Base; Deriv* pd = static_cast<Deriv*>(pb); // コンパイルは通るが、直後に惨状が待ち受けてる っつか、基本事項だから「プログラミング言語 C++」でも買ってきて読んどけ。一から 十まで説明してたら 1 スレ使っても字数が足りんよ。
>>666 >> なんでわざわざそんな不要なコード書きたがるかね
>これ、コボラーの発想だよ。
余計なコードを書かないってのは言語を超えた開発の鉄則。
新規コードは最小限に抑えるべし。
念のために言っておくが、変数・関数名を短くしろとか、
改行を惜しめって意味じゃないからね。
無論ひまつぶし等は別だが、その場合はその旨を明記して欲しい。
>>697 一人の人も救えないのに世界を救えるはずがないよな!
701 :
デフォルトの名無しさん :02/12/16 22:31
>>683 言語に純仮想関数の機構(late binding)があると、
オブジェクト指向プログラミングができるようになる。
>>701 ・・・・・単なる仮想関数でもそうでしょ?
704 :
デフォルトの名無しさん :02/12/16 23:33
ポリモーフィズムできりゃOOPはできる。 (向き不向き存在価値なしはあるにしても)
「オブジェクト指向=多態」と思い込んでいる馬鹿がいるな
708 :
デフォルトの名無しさん :02/12/17 06:59
typedef aiueo *kakikukeko; ってのがよく分かりません。 typedef aiueo* kakikukeko; のことですか?
ソーデース
>>703 そらそーだ
ただ、金属バットで家建てようとしているようなもんだけどな
711 :
デフォルトの名無しさん :02/12/17 11:30
//文字列でNULLがないときってやばくない? struct OOO { char c[4]; char j; }; #include<iostream> #include<string> #define print(x) std::cout << (x) <<std::endl; int main() { OOO nn = {'3','3','3','3',22}; print( sizeof( nn.c ) );//4 print( strlen( nn.c ) );//11 std::string BadStr= nn.c; print( BadStr );//3333??????? std::string TrueStr = BadStr.substr(0,(strlen(nn.c) > sizeof(nn.c) ? sizeof(nn.c) : strlen(nn.c))); print( TrueStr );//3333 }
>>708 kakukikeko は aiueo へのポインタってこと。
aiueo を *kakikukeko であらわせるなら、
&aiueo は kakikukeko でしょ?
aiueo a;
kakukikeko k;
k = &a;
>>697 > 余計なコードを書かないってのは言語を超えた開発の鉄則。
ま た Y A G N I か
715 :
デフォルトの名無しさん :02/12/17 15:29
クラスローカルな定数って定義できます? class MyClass{ const int err = 1; } はできませんでした。
>>715 こういうのはどう鐘。
class MyClass{
static const int err;
}
const int MyClass::err = 1;
class MyClass{ static const int err = 1; } なら可能(整数だけだが)。できないコンパイラはヘタレ。
>>714 つまり、度々無駄なコードを書いては先輩や上司から叱責されていると?
class MyClass{ const int err; } MyClass::MyClass() : err(1) { }
セミコロンを忘れずに・・・
>>722 正直、すまんかった。
浮気性なもんでJava子や#子の癖が出るんでね。
class MyClass{
const int err;
};
MyClass:MyClass() : err(1){
}
コンロも一つ
蝉を退治する殺虫剤で「セミコロン」とか作ったら面白いよね。
(゚Д゚)ハァ?
>>726 オレはオマエのほうが面白いと思うがどうか。
328 は意味不明だが、728 には同意
随分と突飛だな。
>>728 面白いというかおっぱいしゃぶりたいよね。
732 :
デフォルトの名無しさん :02/12/18 23:17
void* から非void型への変換のキャストって???
???
>>732 何がいいたいのかサパーリわからん。
template<typename T>
T void_ptr_to_hoge(void* p)
{
return reinterpret_cast<T>(p);
}
↑でいいのか?
void* は非 void 型だよな
borland C++ 使ってるんですが マルチスレッド化のやり方がわかりません。 教えてください 頼みます
>>736 WindowsならWin32APIのCreateThreadでいいんじゃない?
猫を呼んで来い
=⊂(ΦωΦ)⊃ 呼んで来ました!
。 猫じゃないものがキタぁぁぁぁ!! 。 ∧_∧。゚ ゚ (゚ ´Д`゚ )っ゚ (つ / アァァァァ | (⌒) し⌒^
static_cast でいいのか? reinterpret_cast のが妥当だと思うが・・・。
reinterpret_castだよ。
C++で作成したアプリケーションについてですが Spy++とかで確認することができる クラス名があるじゃないですか。 あれはバイナリ(exe)にはどんな風にして格納されてるんでしょうか? やりたいことはメインウィンドウのクラス名を バイナリエディタで書き換えたいのです。 よろしくおながいします(´・ω・`)
> Spy++とかで確認することができる > クラス名があるじゃないですか。 ・・・え? もしかして、ウィンドウクラスの事? ならスレ違いと言っておこう。
>>745 すれ違いでしたか(´-ω-`;)
C++で作られたプログラムということだったので
こちらで質問してしまいました。ごめんなさいです。
もしよかったらどこのスレッドで聞けば
答えてもらえるのかだけでも教えてもらえませんでしょうか。
ほんとすいません・・・。
C++ で作られたプログラムだろうが、C++ の事について訊きたいのでなければ スレ違い。 妥当なのはぱっと思いつかないけど、近そうなのは Win32API スレ、Windows Programing スレあたりか。
>>747 ありがとうございますです。
さっそくそちらのほうに尋ねてみたいと思いまつ(´・ω・`)
749 :
デフォルトの名無しさん :02/12/20 18:54
class Baka { friend ostream& operator<<(ostream& os, const Baka& obj); private: int aho; }; として、cppファイルのほうでoperator<<のほうを実装すると、 この関数は、privateにアクセスでききない。と出ます。 クラス宣言の中で、インラインで書いてやると、コンパイル通ります。 コンパイラはVS.NETを使っているのですが、コンパイラの仕様ですか? 何か間違っているのでしょうか?
>>749 classのデフォルトのアクセス権はprivateです。
751 :
デフォルトの名無しさん :02/12/20 19:04
d2fc22-022.tiki.ne.jp
>>749 > 何か間違っているのでしょうか?
お前の関数の書き方。
>>749 普通に通るけど何か問題でも?
class Baka
{
friend std::ostream& operator<<(std::ostream& os, const Baka& obj);
int aho;
public:
Baka(int i) : aho(i) {}
};
std::ostream& operator<<(std::ostream& os, const Baka& obj)
{
os << obj.aho;
return os;
}
int main()
{
Baka b(123);
std::cout << b << std::endl;
}
friend ostream& operator<<(ostream& os, const Baka& obj); がprivateだから外からアクセスできないってことだろ。 あ た り ま え だ ボ ケ
>>755 (゚Д゚)ハァ?friend宣言はメンバじゃないよ。
>754 全く同じ様にしてるのですが、 できないんです。何故だろう。 os << obj.aho; の部分がエラーになります。 因みに、friend関数をpublicにしようが、 privateにしようが同じです。
758 :
デフォルトの名無しさん :02/12/20 22:26
>>757 「全く同じ様にしてる」ってコピペしてみればいいかも・・・
同じよ同じ。でもちょっとだけ同じじゃないの。
760 :
デフォルトの名無しさん :02/12/20 22:31
>>757 friendは宣言だけなんだから、privateにしようがpublicにしようが関係ない。
gcc3.2.1(MinGW)では問題なく通ったぞ。
>758 すいません。コピペしてみて試してみました。 なんと、コンパイル通りました。 よく見てみると、全く同じでは内容です。 baka.hで namespace Orokamono { class Baka { friend std::ostream& operator<<(std::ostream& os, const Baka& obj); int aho; public: Baka(int i) : aho(i) {} }; } baka.cppで #include <iostream> #include "baka.h" using namespace std; using namespace Orokamono; std::ostream& operator<<(std::ostream& os, const Baka& obj) { os << obj.aho; return os; } とやると、フレンド関数がクラスのprivateメンバにアクセスできなくなります。 これは、書き方がおかしいのでしょうか?
自己解決しました。ありがとうございます。 どうやら baka.cppで ostream& Orokamono::operator<<(ostream& os, const Baka& obj) { ・・・ } としたら、できるようです。 これって、標準の正しい書き方ですか? 名前空間をusingしているのにこの書き方はおかしい気がします。
>>762 こうやったら通ったぞ。
std::ostream& Orokamono::operator<<(std::ostream& os, const Baka& obj)
{
os << obj.aho;
return os;
}
>>763 定義する識別子にはusingは関係ない。
>>763 <<演算子そのものもOrokamono名前空間で包んでおかないとだめなのでは?
例えば、 namespace Orokamono { class Baka { friend std::ostream& ::operator<<(std::ostream& os, const Baka& obj); int aho; public: Baka(int i) : aho(i) {} }; } のような書き方が意味を持つならば(<<がOrokamonoの外にある事を示す)、 <<の定義部ではOrokamono限定子は不要だったろうが、いろいろ試してみたが、 名前空間の外にあるという指示を出すことは出来ないようだ。
名前空間の中にある、クラスの中で friendの宣言をしているだけで、その関数は名前空間の中で 宣言されてるってことなのでしょうか。 別の名前空間にある関数をfriendにするってこともできなくなるのでは?
>>768 >>769 どうも、friendと名前空間は相性が悪いようです。混ぜて使わない方が
良さそうです。
>>771 でも、いろいろやってみたけど、他の名前空間に含まれる関数をfriendに
できなかったよ。何か方法あるの?
>772 前方宣言しとけば良いだけでは? namespace NS { void func(); } class Foo { ... friend void NS::func(); };
>>773 おお!うまく行った!しかし、operator<<の名前空間の解決のためにかなり
おかしな書き方をしなければならんようです。何とかならないものか?
-- baka2.h
namespace Orokamono {
class Baka;
}
namespace Hentai {
std::ostream& operator<<(std::ostream& os, const Orokamono::Baka& obj);
}
namespace Orokamono {
class Baka {
friend std::ostream& Hentai::operator<<(std::ostream& os, const Baka& obj);
int aho;
public:
Baka(int i) : aho(i) {}
};
}
続き -- baka2.cpp #include <iostream> #include "baka2.h" namespace Hentai { std::ostream& operator<<(std::ostream& os, const Orokamono::Baka& obj) { os << obj.aho; return os; } }; int main() { Orokamono::Baka b(123); Hentai::operator<<(std::cout, b) << std::endl; //これが嫌らしい。何とかならんか? }
int main() { using Hentai::operator<<; Orokamono::Baka b(123); std::cout << b << std::endl; } のように、こういう時こそusing宣言が役に立ちそうだ。
えーと、議論してる皆さん、Exceptional C++読みなさい。 要点は ・friend関数はclassの構成要素の一部である (したがって同じヘッダファイル・同じ名前空間に入れるべきである) ・同じ名前空間にあれば、koenigの名前照合規則が適用される
こんな感じ? namespace Orokamono { class Baka { int i; friend void print(Baka& b); public: Baka(int j) : i(j) {} }; void print(Baka& b) { std::cout << b.i << std::endl; } } void wrapper(Orokamono::Baka& b) { print(b); // Koenig lookup } int main() { Orokamono::Baka b(123); wrapper(b); }
もう一つわかっちまった。 int main() { Orokamono::Baka b(123); std::cout << b << std::endl; } が動かないのは、operator<<と、bが違う名前空間に属しているため、 koenig名前照合が働かないからだね。この例では、friend宣言した<< 演算子は、bと同じ名前空間に入れてKoenig名前照合が働くようにす るのがスマートな解決法だと言えるね。
>この例では、friend宣言した<<演算子は、bと同じ名前空間に入れてKoenig名前照合が働くようにする
そう、それを言いたかったの。
それと、
>>778 はwrapperかまさなくても、main中で直接print(b)と書けるよ。
koenig則のおかげで。
それがprintでなく、operator<<だとしても同じこと。
>>780 ありがとうー!おかげで名前空間に関する理解が深まりました。
friendが名前空間をまたぐことができるという仕様はそのままにして
おいて、スマートにKoenig則が働くよう、無意味に名前空間を
またぐようなプログラムは書かない方がいいみたいですね。
782 :
デフォルトの名無しさん :02/12/21 15:13
C++はIEEEされてますか?
yes, C++ was IEEEd.
784 :
デフォルトの名無しさん :02/12/22 20:14
struct SA{ struct {int nn;}NN; SA():NN.nn(NULL){} }; なんでコンストラクタで初期化できないんだろう? SA(){NN.nn=0;} は、うまくいくのに。
>>784 NN.nn っていうのは SA のメンバじゃないから。SA のメンバは NN であって、だから NN のコンストラクタを呼ばないと。
struct SA{
struct NN{
int nn;
NN(int x):nn(x){}
}NN;
SA():NN(NULL){}
};
・・・まで。なんで int を NULL で初期化してるんだ。
>784 nested class のコンストラクタを自分で宣言してないから。コンストラクタを 宣言しない場合にはコンパイラによって暗黙のコンストラクタが生成される けど、それは引数無しと決まってる。 どうでも良いが int を NULL で初期化するのは、C++ の syntax としては 正しいが、やめた方が…。
788 :
デフォルトの名無しさん :02/12/22 21:07
>>786 >>787 サンクスです。理解できました。
それはそうとして、intをNULLで初期化してはいけないのですか?
ちょくちょくやるんですが・・・。
>>788 NULL は NULL ポインタの値であり、多くのポインタ演算や関数で使われます。
MSDNより。
>>788 いけないっつうか・・・・慣習的に NULL はヌルポインタを表すものだから、ポインタじゃない int に NULL を使うのは好ましくない。
要らぬ物議を醸さぬよう、早々に0を使うようにされよ。
792 :
デフォルトの名無しさん :02/12/22 22:13
793 :
デフォルトの名無しさん :02/12/22 23:41
inlineとかいた関数がインライン展開されない場合は 関数ポインタをとろうとした場合以外にどんなときが ありますか?
でかすぎるとき
つーか、そもそも展開されるという保証はない。
staticローカル変数があると、ほぼ確実。
797 :
デフォルトの名無しさん :02/12/23 00:03
インライン展開されているのをたしかめる簡単な方法 ってありますか?
バイトコードを読むくらいしか…
>>797 機械語で出力して確認する。
ソースコードをコメントに入れるオプションを使えば
わかりやすい。
>>793 BCCの警告から知ったんだけど
ルーブ文があるとだめだって、あと例外指定付きの関数とか。
ヽ(`Д´)ノウァァン
NULL と 0 の話題が出ているみたいなので、便乗質問。 ポインタに 0 を代入しても良いのかな? (void*)0 とかにしなければ駄目? くだらない質問なのでスルーしてもらっても良いです。
良い。 詳しくはC-FAQを参照。 C++の0(NULL)は、ほぼCと同じと考えて良い。 (void *の扱いが違うので、NULLの#define等が違う場合が多いが)
C++第三版に確かNULLより0を使えとあったはず
そのとうり!!
>805 定期的に繰り返される話題だが、規格上 C++ では - 何も有効なオブジェクトを指さないポインタを null ポインタという - NULL は null ポインタ定数であり、これをポインタ変数に代入すると、その変数は null ポインタになる - NULL は整数型で 0 と等しい。(型は int, long, どれかは決まってないけど、とも かく 0 と比較すると真になる値) と決まってる。よって NULL と 0 どちらを使うかは、趣味の問題。
ざっと見たけど、 乳首がポインタでNULLNULLな訳か・・・・ なるほど・・・奥が深い・・・
>>797 処理系によっては、インラインで宣言されているにもかかわらず、インライン展開
できなかったら警告を出すように指定できる。gcc だと -Winline とか。
>794 >796
あとは、末尾再帰以外の再帰がある時もインライン化されないね。このあたりは
Efficient C++ って本が参考になるかな。
ソース書いて、コンパイルしたところ、特定のファイル名によって実行スピードが 速くなる場合があります。 例えば、 g++ -o test1 test1.cpp cp test1.cpp test11.cpp g++ -o test11 test11.cpp とコンパイルすると、test11の方が速いといった具合です。 g++ -S でアセンブラを比較したら、ファイル名の部分だけ異なっているのですが このような事は一般的に起こるのでしょうか? 今まで気にしていなかったのですが、禿しく気になりました。
禿たくは無いんですが、 timeでの計測も差が出るし、プロファイラで見ても差があるのですが・・・。 気のせいですかね?
>>813 ソース出してみ。argv[0]でなんか変わってるとかないだろうな。
>>810 バイナリレベルで二つの実行ファイルを比較したら?同じ?
違うとしたら、微妙な所でキャッシュメモリのヒット率に大幅な差が出ている
のかもしれないな。そんな事は滅多にないと思うが。
816 :
デフォルトの名無しさん :02/12/23 05:01
リフレクションって出来ないの?
>>810 以前fj.comp.lang.c辺りで話題になっていたが、
gccはアライメントがファイル名で狂うため、
その長さで実行速度が実感できるほど変わるらしいよ。
ファイル名を一文字ずつ増やして実行ファイルのサイズを変えてtimeで計ってみました。 ソースは長いのでちょっと出せません。スマソ サイズ timeの結果 ------------------------------------------------------ 36232 8.000u 0.000s 0:08.00 100.0% 0+0k 0+0io 139pf+0w 36233 8.010u 0.000s 0:08.01 100.0% 0+0k 0+0io 139pf+0w 36234 8.000u 0.000s 0:08.00 100.0% 0+0k 0+0io 139pf+0w 36235 8.000u 0.000s 0:08.00 100.0% 0+0k 0+0io 139pf+0w 36236 7.850u 0.000s 0:07.85 100.0% 0+0k 0+0io 139pf+0w 36237 7.830u 0.000s 0:07.83 100.0% 0+0k 0+0io 139pf+0w 36238 7.830u 0.000s 0:07.83 100.0% 0+0k 0+0io 139pf+0w 36239 7.840u 0.000s 0:07.85 99.8% 0+0k 0+0io 139pf+0w 36240 7.610u 0.010s 0:07.84 97.1% 0+0k 0+0io 139pf+0w 36241 7.840u 0.000s 0:07.84 100.0% 0+0k 0+0io 139pf+0w 36242 7.850u 0.000s 0:07.85 100.0% 0+0k 0+0io 139pf+0w 36243 7.830u 0.010s 0:07.84 100.0% 0+0k 0+0io 139pf+0w 36244 8.000u 0.000s 0:08.00 100.0% 0+0k 0+0io 139pf+0w 36245 8.010u 0.000s 0:08.01 100.0% 0+0k 0+0io 139pf+0w ファイルサイズ36236〜36243まで微妙に速いんですよね〜 これやっててかなり萎えました・・・
>> 817 おお!禿げずにすみそうです。ありがとうございました。
>>816 C++に出来ないことはありません。
出来ないように見えるものはすべて不要なものです。
821 :
デフォルトの名無しさん :02/12/23 05:05
>>821 不要です。要するにリフレクションなんて機能は使う必要ありません。
VBでは出来るリフレクションがC++で出来ないとは一体どういうことだ?
826 :
デフォルトの名無しさん :02/12/23 05:11
>>822 例えば設定ファイルによって
実行時に使うクラスが変わる場合は、
どう実装すればよいのでしょう?
>>824 C++でJavaを実装してもC++のリフレクションは出来ませんよ。
829 :
デフォルトの名無しさん :02/12/23 05:14
C++やっぱダメだな…
>>826 それはリフレクションを使用する例としては不適切だと思う。
managed C++ なら使えますが、なにか?
>>829 お前はC++の進化の歴史を知らんのか?
まだまだこれからもC++は進化する。
「プログラミング言語 C++ 第4版」はさらにページ数が倍に。
>>833 むしろ.NET対応言語なら使えるといった方がいいな。
837 :
デフォルトの名無しさん :02/12/23 05:23
In function `int main()': ANSI C++ forbids implicit conversion from `void *' in assignment 59: array = malloc( n_array ); ↑のようなエラーが出ましたが、どういうことでしょうか?
メッセージの通り。
#ifdef __cplusplus #define NULL 0 #else #define NULL (void *)0 #endif
>>832 リフレクション風のクラスだか関数だかをお前が管理しなきゃ良いだろ。
>>837 mallocの返り値をarrayの型にキャスト。解決。以上
>>837 つーかC++でmalloc()使うなよ。new使え。
アプリケーションに一つしか使わないやつを static で生成して、 それを使うクラスは、継承して内部(?)に持たせて使う やりかたってやってもいいのでしょうか? 例) class CDXGraphic{ public: static LPDIRECT3DDEVICE8 s_pDevice; static void Initialize(); } class CRender : public CDXGraphic{ public: void render(){ ここで、s_pDevice を使って書く。 };
問題ないっしょ。 俺なら、変数をprotectedにするか、変数はprivateにして取得/設定メソッド をprotectedにする。
つーか、問題あると思うなら、それが間違っててもいいから 「自分はこんな問題があると思うんだけど、これって不味くない?」 とかなんとか書かないと、問題点が整理されなくて結局質問者の損な気が・・・
リフレクションを要らないと言う奴はCppUnitも使ったこと無い素人
>846 C++ だと、ふつー Perl か ruby でスクリプト書いて、テストメソッド順番に呼ぶ コードを自動生成。
848 :
デフォルトの名無しさん :02/12/23 12:32
Your program exited with signal #11 (segmentation violation [maybe caused by accessing memory out of bounds, array indexing out of bounds, using a bad pointer (failed open(), failed malloc), or going over the maximum specified memory limit]) . と出ているけどどう直せばいいんでしょうか?
>>847 リフレクションが無いからそうなる。
リフレクションのありがたみを感じられる場面ですな。
http://www.st.rim.or.jp/~phinloda/cqa/cqa10.html Q 【Segmentation violation】
"Segmentation violation"というメッセージが出てプログラムが
異常終了してしまう。原因は何だろうか。
A
簡単にいえば、使ってはならないメモリを使おうとした場合に
このようなメッセージが出ます。具体的には、ポインタの使い方を誤ったとか、
printf に指示したフォーマットと与える引数の型が一致しなかったりすると、
このような状況になることがあります。
n_array = (max-1) / 2;
array = (char *)malloc( n_array );
memset( (void *)array, 1, n_array );
ここの部分が原因でしょうか?
>>すとらうすとらっぷ 要らぬ物議を醸さぬよう、早々にC++仕様に空のオブジェクト参照 null を追加せよ。
>>850 そこじゃないような気がするけど、そこだけ単体で試してみたら?
あと、そこの部分だったら微妙にスレ違い(Cのスレに行け)。
つーか他の部分のソースは?
853 :
デフォルトの名無しさん :02/12/23 13:31
>>852 プログラムのソース
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define print_usage(s) \
fprintf( stderr, "Usage: %s <min> <max>\n"\
" 5 <= MIN < MAX <= 100,000,000\n",\
s )
static int reverse_int( int i ) {
int res = 0;
while ( i ) {
res *= 10;
res += i % 10;
i /= 10;
}
return res;
}
>>853 の続き…
static void sieve( char *array, int max ) {
int i;
for ( i = 3; i < max/3; i += 2 ) {
if ( array[i/2-1] ) {
int j;
for ( j = i*2; j <= max; j += i ) {
if ( j&1 )
array[j/2-1] = 0;
}
if ( i != reverse_int(i) )
array[i/2-1] = 0;
}
}
for ( ; i <= max; i += 2 )
if ( array [i/2-1] && i != reverse_int(i) )
array[i/2-1] = 0;
}
>>854 の続き…
int main() {
FILE *fin, *fout;
int min, max, n_array, i;
char *array, number[20];
fin = fopen("pprime.in", "r");
fout = fopen("pprime.out", "w");
fgets(number, sizeof number, fin);
sscanf(number, "%d %d", &min, &max);
n_array = (max-1) / 2;
array = (char *)malloc( n_array );
memset( (void *)array, 1, n_array );
sieve( array, max );
for ( i = min/2-1; i < n_array; i++ )
if ( array[i] )
fprintf(fout, "%d\n", i*2+3 );
return 0;
}
読み込むデータが大きすぎてこのようなエラーが起こりました。
>>848 スレ違いだが。
SIGSEGVが来るんなら、coreはできてないのか?
デバッガで見てみろ。
>>856 malloc()に失敗してるだけじゃん。阿呆。
C言語スレで聞けよ
>>861 C == C++;
>>863−864 if(C == C言語 && C++ == C++言語) C = C++;
>>847 CppUnitなら、
CPPUNIT_TEST_SUITEマクロ書くのも対した手間じゃないじゃん。
スクリプト起動するほうがかったるいや。
>>865 ばーか
ネタをネタと・・・ てか nxt ってだいぶローカルネタだな
全角は資源の無駄ですので辞めましょう。 STOP! 全角
ja, zenkaku ha tukawanai youni ne
871 :
デフォルトの名無しさん :02/12/23 20:59
晒しあげ
>866 ふつー make を使う。
873 :
デフォルトの名無しさん :02/12/23 23:11
xv_overlay.cpp:13: ISO C++ forbids defining types within return type xv_overlay.cpp:13: return type specification for constructor invalid "gcc -c xv_overlay.cpp"で上のエラーがでて困っています。 コードを下記に晒します。 一体どこが悪いのでしょう? #include <X11/Xlib.h> #include <X11/extensions/Xvlib.h> class XvAdaptor{ public: XvAdaptor(); private: Display *dpy; XvAdaptorInfo *adaptor; void Init(void){}; }
/** 873の続き **/ XvAdaptor::XvAdaptor():adaptor(NULL){ // xv_overlay.cpp:13 はここになります。 Drawable root; XvAdaptorInfo **ppAdaptorInfo; int nAdaptorInfo; dpy = XOpenDisplay(NULL); root = DefaultRootWindow(dpy); XvQueryAdaptors(dpy, root, (u_int*)&nAdaptorInfo, ppAdaptorInfo); if(nAdaptorInfo>0){ int num; XvAdaptorInfo *tmp; for(num = nAdaptorInfo-1; num >= 0; --num){ tmp = *(ppAdaptorInfo + num); if(tmp->num_ports > 0){ if(adaptor != NULL){ XvFreeAdaptorInfo(adaptor); } adaptor=tmp; }else{ XvFreeAdaptorInfo(tmp); } } } if(NULL != adaptor) Init(); }
クラス定義の後、コンストラクタの前
あっ、そうか。classはstructと同系列だった。 数年ぶりにC++に手をだしたもんで… ひー、趙単純ミス! 逝っときます…
クラス外で変数名を意識しないとダメなクラスはダメだと何かの本で読んだのですが、 メンバにクラスをってる場合もそうなのでしょうか? class A { private: int i; public: void show(void){return i;} }; class B { private: A a; public: void show(void){return a.show();} }; って書くのめんどくさいんで、 class C { public: A a; } a.show()ってやりたいんですけど。
あっ、 C c; c.a.show();です。
余計面倒くさくしてる気がものすごくする.....
うっ、どうすればいいんでしょう?Aに関数がたくさんある場合、 Bはやってられないんですが...
883 :
デフォルトの名無しさん :02/12/24 03:06
無名structとか無名classとかってどんな使い方があるんですか? あんまり意味がないような・・・。
class X { static int size; }; class Y: public X{ }; class Z: public X{ }; でY、Zでstatic int sizeを持つことって出来ませんか? Y y1, y2, y3は同じsizeをもって Z z1, z2, z3はも同じsizeを持つけどyとは違うみたいな。 Y,Zにstaticメンバを書けばいいんでしょうが、基底クラスの 概念ではこちらの方が気持ちいいんで。
staticメンバはその名前について一つという原則から考えれば、無理だという ことが分からんか?
分かってはいるのですが、何か無いかと思いまして。 static_delayか何かあると気持ちいい〜
887 :
デフォルトの名無しさん :02/12/24 05:11
fscanf(fin, "%s", name); 配列として宣言されたname、式の中ではポインタに書き換えられる。 そのポインタが指すところってname[0]でcharacter1字しか格納できない、 なのになぜstringを格納できるのでしょうか? また、この%sのstringには\0が最後に入っているのでしょうか?
888 :
デフォルトの名無しさん :02/12/24 05:16
fscanfっていう関数って、空白または改行に出会うまで指定された フォーマットに従って引数にデータを格納するのですか? 例えば、 fscanf(fin, "%s %d %d", string, &number, &number_2); とすれば、 stringSample 100 50 でも、 stringSample 100 50 でも、同じデータを格納するってことですか?
ポインタの理解が足りない fscanfなんて使わないから知らない(ヘルプ見れば) C言語スレへ行け
>>879 C::aに対して外部からどんなアクセスをしてもCの整合性が保てるなら、
それでもいいと思う。
同じ条件で、aをCのメンバにする意義はあまり無いと思う。
>886 template <class T> class X { protected: static int size; }; class Y : public X<Y> {}; class Z : public X<Z> {};
>>879 隠蔽の意味がわかってないみたいですね。
おそらくclassの切り分け方が根本的におかしいのでしょう。
最終的に楽をしたかったら隠蔽についてよく考えてごらん。
プログラムを組むとき、動くか動かないかだけで考えるのはもう卒業しましょう。
オブジェクトには責務の範囲というものがあります。
そのオブジェクトがやるべき事は、確実に成し遂げなければなりません。
そのオブジェクトがやらなくていい事は、全く気にしなくても済むようでなければなりません。
そしてpublicにしたら面倒になる、という感覚が身に付いたとき、
初めてオブジェクト指向が身に付いたと言えるようになるんじゃないかな。
それには関連も同時に学んでいかなければなりません。
オブジェクト指向の設計では、インターフェイスを設計することは当然として、
オブジェクト同士の関連を設計する事も重要です。
だからデザインパターンもあわせて強しましょう。
>>879 憂鬱なプログラマのためのオブジェクト指向開発講座
でも見ればわかるんでない?
>> 892 なるほど〜。これって良く使われるテクなんでしょうか? 皆さんどうもありがとうございます。ちょっと勉強して出直してきます。今後とも宜しくお願いします〜。
892 のコードはどういう場面で必要なんだ?
>> 890,893,894 コメントどうも。 class Bはclass Aをprivateで持っていてもいいんですが、 Bのメンバを表示したいためだけなのです。
>897 良く使うのは、仮想関数呼び出しのペナルティなしに template method を実装 したいときかね。ATL の CWindowImpl とかが良いサンプル。
>>896-898 おまいらわざとレスリンクしないようにしてるんですか?
そうじゃなかったらレスリンクして欲しいです。。。
レスリングはしません。
>>900 おまいのケツを捧げたら考えなくもないれす。
ツケが溜まっています
906 :
デフォルトの名無しさん :02/12/26 16:47
次スレ逝きますか? 逝っていい? ねえ逝っちゃうよ ん…んっっ逝くっ
がいしゅつだったらすまんが... クラスのインスタンスをグローバルで宣言すると デストラクタが呼ばれないのはコンパイラが糞ってことなのか!? ちなみにコンパイラはVC。 ====> #include <iostream> using namespace std; class global { public: global(){cout<<"global start..."<<endl;} ~global(){cout<<"global end."<<endl;} } g; void main(void) {cout<<"main"<<endl;} <==== これを実行すると... ====> global start... main <==== となってデストラクタが呼ばれないのだが。 これがC++の仕様だったら漏れ、 …拳銃らしきものもって銀行襲っちゃうかも…
908 :
デフォルトの名無しさん :02/12/27 17:20
あ、278は間違い。
main() 終了後に呼ばれるから cout が死んでるのかも。
>>909 そっか。順番で言うと、
cout, global, main, ~cout, ~global
となってタイミングの問題なのね。
十二分にありえる…。
う〜ん…意外だった。
THX!
STL ハッカーさんはいますか?
επιστημη
少なくとも何の説明もないリンクを踏むやつはいないと思うが…
>914 JTC1/SC22/WG21 is the international standardization working group for the programming language C++.
>>907 ん?ちゃんと呼ばれるよ。@VC6
global start...
main
global end.
終了時に呼ばれる関数テーブルが壊れてるのかも。
atexit/_onexitが正常に動くか試してみたら?
>>907 Borland-C++5.6.2ですが、正しくデストラクタも呼ばれました。
918 :
デフォルトの名無しさん :02/12/27 23:22
std::ostreamの << 演算子をオーバーロードして、 自分で作ったクラスのインスタンスを出力できるようにしたいのですが、 うまくいきません。 グローバル関数として std::ostream& operator<<(std::ostream &p_rcLOStrm, CMyClass myclass); という関数を作ったのですが、VC++で error C2678: 二項演算子 '<<' : 型 'class ostream_withassign' の左オペランドを扱う演算子は定義されていません。(または変換できません) というエラーになります。 お助けください。
>>918 それだけでは不明です。CMyClassの定義と、operator<<の定義全体をうp
してみて下さい。
>>919 CMyClassは、演算子[] をオーバーロードしていて、
int operator[](int i);
この関数は正しく動作することを既に確かめています。
で、operator<<は、
std::ostream& operator<<(std::ostream &p_rcLOStrm, CMyClass myclass) {
return p_rcLOStrm << myclass[0] << myclass[1] << myclass[2] << myclass[3];
}
となっています。
>>920 うーん普通に動くが?
class CMyClass {
int i;
public:
CMyClass(int j = 0) : i(j) {}
int operator[](int j) {
return i + j;
}
};
std::ostream& operator<<(std::ostream &p_rcLOStrm, CMyClass myclass) {
return p_rcLOStrm << myclass[0] << myclass[1] << myclass[2] << myclass[3];
}
int main()
{
CMyClass cl;
std::cout << cl;
}
なんでだろう。BCC5.5.1では通らなかった。 struct T { int operator[](int i) const { return i; } }; std::ostream& operator<<(std::ostream& os, const T& t) { os << t.operator[](0); //これは通った os << t[0]; //駄目だった return os; }
921です。 Borland-C++ 5.6.2及びgcc3.2.1(MinGW)では通ります。
>>921 #include <iostream.h>
の .h を取って、
using namespace std;
を書いたら正しく動くようになりました。
今まで適当に書いていても動いたので、なめてました…
ともかくありがとうございました。
あれ。今度は上手くいった。さっきコンパイルしたときは +演算子がどうのってエラーが出たんだけどな。。。
#include <iostream> #include <typeinfo> using namespace std; class Base { virtual void f() {} }; class Derived : public Base { }; int main() { Base base; try { Derived& dr = dynamic_cast<Derived&>(base); } catch(bad_cast &) { cout << "here." << endl; } catch(exception& e) { cout << e.what() << endl; cout << typeid(e).name() << endl; } return 0; } VC6のcl.exeだと、確かにbad_castが投げられてるようだがcatchできない・・・ bcc5.5.1だとうまくいく。どうなってるんだ・・・
927 :
デフォルトの名無しさん :02/12/28 16:43
Functorまんせー
928 :
デフォルトの名無しさん :02/12/28 21:12
質問なんですが、 STLのsetでupper_boundの逆、 引数より小さい最初の要素を探す ってないでしょうか? もしないなら、何らか代替えはないでしょうか?
929 :
デフォルトの名無しさん :02/12/28 21:36
こんにちは。 外部シンボルinp,outpが未解決となってしまうエラーについて質問させてください。 I/Oボートにアクセスしステッピングモータを動かす プログラミングをC/C++で行っています。 しかし Error: 外部シンボル '_inp' が未解決(C:\DOCUMENTS AND SETTINGS\INFODRIVE\デスクトップ\program.OBJが参照) Error: 外部シンボル '_outp' が未解決(C:\DOCUMENTS AND SETTINGS\INFODRIVE\デスクトップ\program.OBJ が参照) というエラーが出てしまいmakeできません。 いろいろ調べて #include "conio.h" #include "IOBIN.h" というのをインクルードしてみたのですがうまくいきません。 Win95、Cpad、Borland C++ Compiler 5.5 を使っています。 ちょっと制御関係の話かもしれませんが、 どなたかアドバイスをいただけませんか? よろしくお願いします。
>>907 ,916
VCだと /MD オプションでランタイムライブラリにMSVCRTを使うように
するとちゃんとデストラクタも呼ばれます。スタティックリンクのLIBCだと
ダメです。たしかこれってずいぶんまえに一時期さかんに議論されていた
内容だったと思います。
SOCKADDRとSOCKADDR_INのように、同じサイズの構造体があって、 例えばSOCKADDRをSOCKADDR_INに、キャストするようにコピーする方法はありますか?(ちょっと言い方が苦しいですけど) 構造体は型キャストではできないみたいなので。
こういうこと? SOCKADDR sa, *psa; SOCKADDR_IN si, *psi; si = (SOCKADDR_IN *)&sa; *psi = (SOCKADDR_IN *)psa; 普通はmemcpyするけどな(理由は略)。
>>930 lower_boundは違うようです。
lower_boundは <= という意味で、
upper_boundは < みたいです。
>>930 std::lower_bound(v.begin(), v.end(), value, std::greater());
っていうのはどう?
>>928 いろいろやってみたが、なかなか難しい。
まず、std::upper_boundにstd::greaterを与える方向で調べてみた。しかし、
コンテナが逆順にソートされている事になってしまい、うまくいかない。
std::upper_boundは比較基準と同じ基準でソートされているコンテナに
しか適用できない。
次に、rbegin(), rend()を与えてみた。ところが、std::upper_boundにnormal_
iteratorを与えなさいというエラーが出てだめだった。std::upper_boundの
返り値がnormal_iteratorだかららしい。これは意外だった。
結局、方法は一つ、コンテナを逆順に並べ替えてからstd::greaterを与える
という結論に落ち着いた。
他にスマートな方法があったら教えて下さい。
>>928 おっとごめん。std::setに対する処理か。std::setはすでにソートされている
から、そのソート基準を切り替えることはできないだろう。
メンバ関数upper_boundで反復子を取得し、それに対しstd::advance(-1)を
適用してはどうか。
upper_bound(key) がkeyより大きいはじめの値、 lower_bound(key) がkeyより大きくないはじめの値、 setは値の重複を許さない、ってことで set<T> s; *--s.lower_bound(key) が所要の値になる、ってのは?
>lower_bound(key) がkeyより大きくないはじめの値、 keyより小さくない、だった。
>>938 multisetでもlower_boundの一個前でいけるだろ。
ただ、
> *--s.lower_bound(key)
これはイクナイ。
beginが返ってきたときに恐ろしいことが。
こんなんでどうかな?std::setで順位もつけてテストしてみた。 typedef std::pair<int, int> PII; struct Cmp : public std::binary_function<PII, PII, bool> { bool operator()(PII i, PII j) { return i.first <= j.first && i.second < j.second; } }; int main() { std::set<PII, Cmp> s; s.insert(std::make_pair(1, 1)); s.insert(std::make_pair(1, 2)); s.insert(std::make_pair(2, 3)); s.insert(std::make_pair(3, 4)); s.insert(std::make_pair(3, 5)); std::set<PII, Cmp>::iterator pos; pos = s.upper_bound(std::make_pair(3, 1)); pos--; std::cout << "key = " << pos->first << ", value = " << pos->second << std::endl; }
>>940 begin()でないかテストを付けました。
if (pos != s.begin()) {
pos--;
std::cout << "key = " << pos->first << ", value = " << pos->second << std::endl;
}
>>941 比較関数差し替えるのは、928の要求に合わないと思う。
>>943 しかし、比較関数を差し替えないと、std::pairのようなクラスをstd::setに
挿入できないよ。
それから、lower_boundは、elem*以上*の最初の位置を算出するので、
キーの重複を許さないstd::setはいいとして、std::multisetでは同じキー
が連続する場合、最初のキーの位置を出してしまうのでまずいんでは?
upper_boundでelem*より大きい*最初の要素の位置を出して、それが
begin()でない事を確認してから--するのがいいと思う。
>しかし、比較関数を差し替えないと、std::pairのようなクラスをstd::setに >挿入できないよ。 スマソ。これは取り消します。
>>928 が何をしたいんだかよく分からんのだが、
”引数より小さい最初の要素”ってのはset.begin()か、コンテナ中に存在しないか、
のどっちかだと思うんだが。
うーんいろいろ試してみたんだが、比較関数を差し替えない限り、std::setと std::multisetはlower_boundでいけますね。 std::setはそもそも重複がないんだし、std::multisetは、同一のキーであっても 順序が重要ではないんだから。 upper_boundだと、同一のキーを検索した場合、それ*より大きい*キーを指して しまうので、--しても、同一のキーを指してしまい、それ*より小さい*キーを 指してはくれない。 それからキーが同一でも順序が重要な場合はstd::multimapを使いますよね。
>>946 0 1 2 3 4 5 6 7 8 9
set内がこうなってたとき、引数として5を与えたら4が帰ってきて欲しいって意味だと思うが
>>948 それだと”引数より小さい最後の要素”じゃないか?
>>949 おお、確かに・・・
引数の値から小さい方向に進むこと最初の、と意訳していたが・・・
>>949 upper_boundの逆ってことで、推して知ってやるところだと思われ。
std::vector, std::deque, std::listの場合は話はややこしくなるな。もっとも これらのコンテナにはメンバ関数にはupperboundはないが。だから 標準アルゴリズムのstd::upper_boundを適用したと仮定して、 1 2 3 4 4 4 5 6 7 となっていたとして、upperbound(4)の逆とは、 1 2 3 4 4 4 5 6 7 ^ ここを指すのか(lower_bound)、 1 2 3 4 4 4 5 6 7 ^ ここを指すのかで話が違ってくる。 連想コンテナではどちらでもよい。同一キーの順序づけがないんだから。
下みたいに{〜}の中で作成したオブジェクトは{〜}抜ける場合に必ず破棄されるの? 実装依存? printf("before); { foo b: } printf("after");
>>933 解決しました。memcpyでOKでした。レスありがdございました。
SOCKADDR sock; SOCKADDR_IN soin;
memcpy( &sock, &soin, sizeof(SOCKADDR) );
>>955 サイズが全く同じなら
SOCKADDR sock;
SOCKADDR_IN soin;
soin = *reinterpret_cast<SOCKADDR_IN *>(&sock);
で出来ないことはない。
一応参考までに。
色々ありがとうございます。 説明も悪かったみたいで、 例えばset内に 1 2 4 とある場合、引数が 5の場合4 4の場合2 3の場合2 2の場合1 1の場合エラー 0の場合エラー という処理をしたかったんです。 結局、 if (s.empty()) return false; pos = s.lower_bound(key); if (pos == s.begin()) return false; pos--; // 以降該当したものがある場合の処理 というようにしました。 みなさんありがとうございました。
958 :
デフォルトの名無しさん :02/12/29 17:50
激しく初歩的な質問ですみません。 class A{ public: A(int n); // コンストラクタ }; class B: public A{ } int main(){ B x(5); } とやったらエラーが出るんですけど、コンストラクタって継承されないんですか?
class B:public A{ public: B(int n):A(n){} };
>コンストラクタって継承されないんですか? yes
961 :
デフォルトの名無しさん :02/12/30 01:26
template<typename T>T t=0; が通る(VC)だけど、意味あるの?
>>961 ちょっと訊きたいんだけど、どうしてそういうコードを書こうと思ったの?
偶然書き間違えて、F7押したらエラーが出なかったの。
>>961 > test.cpp(10): error C2998: '<template parameter>t': テンプレート定義にはなれません。
と言われてしまったが。
961 の VC は、実はビタミン C
966 :
デフォルトの名無しさん :02/12/30 13:29
C with classes のソースとかってどこかに落ちてないでしょうか? 検索に引っかかりにくい名前なもので探せないのです。
わかりづらかったような気がするので補足です。 コンパイラ(コンバータ)のソースという意味です。
スレ違いじゃないか?
10年以上前の代物でわ・・・
そういえば、ないね リッチーのHPにはBのソースとかあるのに ストラウストラップのHPには昔話が見当たらない
スレが終了する間際なので厨房質問をさせてください。 基底 class CGorua{略}; 派生1 class CMorua : public CGorua {略} 派生2 class CHorua : public CGorua {略} 派生3 class CForua : public CGorua {略} があり、派生クラス1〜3のオブジェクトを1つずつ作成しました。 また、別のクラスとしてCAhyaがあり、オブジェクトを1つ作成しました。 派生1〜3から、CAhyaのオブジェクトを使うにはどうしたらいいのでしょうか。 グローバルでCAhya ahyahya;と宣言するのでしょうか。 どうぞよろしくおねがいします。
>>980 you should stand thread of continuing!
>>974 ありがとうございました。
やってみます。
>>968 微妙な所ですけど、汎用相談スレに書いて解答が得られるとも思えず、
専用スレを立てるのは明らかに荒らしなので、結局ここしかないんですよね。
>>969 文化的価値から知的興味+この間の C マガの特集を見て
コンバータ作りたいなぁ…なんて思ってたりして、その参考も含めてなんです。
>>970 エイプリールフールのジョークならあるのにね(あれはストラウストラップのページじゃないんですっけ?日本語訳しか読んだことないので不明かも)
>>972 サンクスコです。…でも商品ぽいですね…。さすがにお金だして買う気はしないです。ごめんなさい。
せっかくなので初心者さんの質問にも答えてみます。
>>973 質問の意図が不明です。public な部分を使うだけならどこからでも出来ますよ。
全体で唯一のインスタンスを使うならグローバル変数より Singleton と呼ばれる方法を使う方がスマートです(わからなければ検索サイトで Singleton を検索してみてください。)
アクセスコントロールの話の場合は
>>974 さんの回答の通り friend にするのが手っ取り早い方法ですが、あまり好ましくありません。
アクセスを制限する Adapter クラスを通して使うとよいかもしれません。
ってなんかデザパタの宣教師みたいな回答になっちゃったな…。
978 :
デフォルトの名無しさん :02/12/31 06:53
char size[sizeof(T)]; と、したときの領域を動的に削る方法ってあります?
冬休みだから久しぶりに覗いてみたけど、このスレはまともですね(w
>>973 >オブジェクトを使う
とあるから、単に関連を張りたいだけの気がする。
CAhyaがプログラム中で一度しか出てこないならsingleton
多数出てくるなら、派生1〜3のコンストラクタに
ahyahyaへのポインタを渡すか、関連を張る関数を用意する。
>>978 いみふめ
静的に確保した領域は動的には変更できませんよ?
多分 vector<char> が望みのものだと思うけど
980 :
デフォルトの名無しさん :02/12/31 12:41
placement newで質問です。 void* operator new(size_t size,void* buf){return buf;} template<typename T,size_t reg=1>struct TSA{ enum{num=reg}; char p[sizeof(T)*num]; T* pt; TSA(){pt=new(p)T;} }; class X{void func(){}}; /**************************************************************/ void main(void) { TSA<X> tsa; cout<<&tsa.p<<sizeof(tsa.p)<<endl; cout<<&tsa.pt<<sizeof(tsa.pt)<<endl; } となっているとき、pとptのサイズが違うんですが、これって正しいのですか? あと、アドレスも違うのですが。
> これって正しいのですか? 正しい > アドレスも違うのですが。 あたりまえ
int main() { char p[100]; char *pt; pt = p; cout<<&p<<sizeof(p)<<endl; cout<<&pt<<sizeof(pt)<<endl; } となっているとき、pとptのサイズが違うんですが、これって正しいのですか? あと、アドレスも違うのですが。
>>982 ptの「中身が」pのアドレスっていうだけだからどっちもそれで正しい
いや、俺は980の疑問をわかりやすく書き直しただけなんだが。
986 :
デフォルトの名無しさん :02/12/31 15:43
質問です。 sscanf( argv[1]+1, "%2x", &x ); ココのargv[1]+1の部分はどういった処理なんでしょうか。 argvはchar型なので文字列連結では無いとは思うのですが。。
man sscanf
そろそろ埋めるか
>>986 argv は char **型じゃないの?
あんたのプログラムがどうなってるか知らんから分からんけどなー
990!!
ところで新スレは?
992
梅
996
埋めて埋めて
998!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
とっとと埋め
999!!
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。