1 :
デフォルトの引き篭もり :
02/11/23 15:03 怪しい仕様は細々ありますが大丈夫です!
elegantなソースを目指してね。
( ^-゚).。o(きっと関連URLは
>>2-5 辺りだよ)
焦ってレスした俺が馬鹿だった(ρ_;)
,r‐、 , -、 ! ヽ / } ヽ、 ,! -─‐- 、{ ノ /´∀` r`'、´ <オマエモナ / ,.-─- 、 ヽ、.ヽ !/ ヽ、._, ニ| . { ,' ヽ /,ソ . ヽ、.____r',/ 汎用度::中汎用 << 超汎用 << 小汎用 <<ミニ汎用 優秀度::C++ << C << ASM << CPU配線・回路
>>8 bool operator<< (const Thing& lhs, const Thing& rhs)
{
return lhs.Wonderfulness > rhs.Wonderfulness;
}
[プラットフォーム] [Win32] g++ << VC++7[.Net] << bcc32 フリー << C++Builder <= VC++6 [Linux&Unix] g++ <= intelコンパイラ
11 :
デフォルトの名無しさん :02/11/24 14:54
僕の
12 :
デフォルトの名無しさん :02/11/24 15:23
ローカルクラスをその同じスコープ内でテンプレートパラメータとして 用いることはできないのでしょうか? int mem_fn_mine() { class SomeObject { public: SomeObject( const char* i_name ) : name( i_name ) {} void Print() { cout << name << endl; } private: const char* name; }; std::vector<SomeObject> v; こんな感じです。 g++-3.2 cygwinです。
ローカルクラスって挙動がおかしかった気がする・・・
>>13 やっぱりテンプレートがからんだものはnamespaceレベルで使うべきですかね
特別にローカルクラスが必要ってわけでもないので、どうでもいいんですが。。
たしか、テンプレートの実体化は関数の外(namespaceスコープ)で 行われると思った。だから実体化の時点では、関数内で定義されている ローカルクラスを見ることができないと。
>12 用語の問題だが local class といったら関数内で定義したクラスのこと。 int main() { struct S {...}; // これ } クラス内で定義したクラスは nested class な。このあたりは規格書で用語 が決まってるから、誤解を招かぬよう統一して下さいな。 ANSI C++ の規格では local class はテンプレートパラメタとして使えない、 nested class は OK のはず。class SomeObject の定義を public に移して みたら?
?? 12は適切な用語を使ってると思うが??
>>16 nested classならそれらがテンプレート化クラスであろうと
テンプレートパラメータとして使うことはgccにおいて問題ありませんでした。
細かいところまでやってみてないのでなんとも言えませんが、
local classはテンプレートが絡んだときには、少し特殊なものとなる
という認識でいればよさそうですね。
>>19 ,iノノ
,、ノノ:レ
,,:i,i/:'/'~/ ,/!
,、_,ノ:!~;'彡-三ヾ、 ,从i ,
,i[ !' ~ ~:;;、'~'ヽ ノ ::;i!.ノi
,/゙ ,ヽ!ゝ ~ii::ミ λ ノ'~ :;レ' :;;!
゙i;: `>_:,;ii,ミミミi ,v'.i ,ノ ::;/ ::;ノ _,,、-,-
'!'~`~)||!!ヾ!~ ::i,) ,从,レ :;;/ :;ノ彡-''~゙ :i!'゙
、彡ノノノ ::ii人 /;/;;ノ゙;;;::i-'<、,_,,、-'~
,i'゙~i::ノ゙;: .:: ::iiヾ i', ,ノ゙/-彡'~: ::_;;_;;;::::ヾ、--、_
i゙::i .::; ノ: ,iヾ ::゙i、_ __,,,ノv:レ从)ivト'|'゙::;;-''''~ ;;__ _;;ヾ、|~ ̄
'゙i,:;::/ ;;-'ノ' ~ヾ〉~''~゙ ---、, :;;ノ:i'从iiiニ=彡三ミミミ;;::i, ゙'i,
!,;::i i ;!'゙ ::;i'゙ ~゙彡;゙ノ,レ'~,ノ゙!!=-ii、,゙ヽ, 'i;::i, i
i,i::iミ゙ ::;i 彡彡<゙;;,ノ'二~' 彡 i 彡!,i'
レi; ::;i,; ,、-彡'~~∠゙~ 彡i'゙ '~´
ヽ, ::ゝ, 、 、___ノノ'~~フ ̄ '゙
ヾ、ヽ、i :ゝ,゙'i ''-ミミ= ~'-<
ヾ、;;::::!!、 ゙i.|トトi::::::ミ'~ ̄~
~'ヾヾ-,、____ !__::::ヽ,
,ノ:::;/ ~゙ヽ):::::;)
ノ::;ノ' /゙:::;/
,-'''"ン" /::;/
__,,、、、-‐/'"i-、(、,、,,,,,/゙/
二='''、::::::!、-┘ヾ--/:::;/ゝ
 ̄ ̄ ̄ ,、、-/ー'゙ノ::;∧,、,
∠二―┴,=< ::;ノヾ、,」ニ=ー
./:,、┴゙
//
!'
class foo { foo(); ~foo(); static void threadFunc(foo *p); boo m_boo; }; void foo::threadFunc(foo *p) { while(1) { p->m_boo.xxx(); } } クラスfooはスレッドを扱う。そのスレッドはfooの静的でないメンバbooを扱う このクラスfooがデストラクトされるときに、まずスレッドが止まって、次にbooのデストラクタが呼ばれたい どうすればいいでしょうか?
void foo::threadFunc() { foo* t = new foo();
デストラクタでスレッドに停止命令だせばいいやん
>25 そうするとm_booがさきにデストラクトされるとp->m_boo.xxx()のところで おかしくなりませんか?
∧_∧∩ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
( ´∀`)/<
>>21 先生!漏れクレジットカード持ってないYO!どうしよう
_ / / / \_____________________
\⊂ノ ̄ ̄ ̄ ̄\
||\ \
||\|| ̄ ̄ ̄ ̄ ̄||
|| || ̄ ̄ ̄ ̄ ̄||
.|| ||
fooがm_booを使ってるとわかってるのに、 先にデストラクトするのは変じゃん
29 :
デフォルトの名無しさん :02/11/24 18:35
boo の実体じゃなくてboo*を待たせる。 タイミングをはかりたいなら、クリティカルセクション やらミューテックスを使う。
つーか、threadFunc() を誰がいつ蹴っ飛ばすのかわからん。 とりあえず class foo の外側でロックかけなきゃいけなさそうだが。
どうするんだよ、前スレもう書き込めないじゃん
33 :
デフォルトの名無しさん :02/11/25 13:12
自力でスクロールバーを描画したいのですが、参考ソースとかどこかにありませんか? ググったけど見つからないです。 自力で、の意味は(OSの組み込み機能とかではなく)自分でビットマップとかを使って描きたいという事です。 (長さの割合とかの計算がよくわからない)
↑リアル厨房現る!
>>33 おれも座標とかの計算苦手。でも昔仕事でやったことある。嫌々。
Windowsでの話になるけど、描画用のウィンドウを作ってもいいし、
直接クライアントウィンドウのデバイスコンテキストに描画でもいいけど、
自分でコントロールもどきを作成するのは相当面倒だよ。
codeguruとか行った方が良いかも。
http://www.codeguru.com/
>>35 ありがとうございます。参考になりそうなソースをハッケソできました!
感謝!!
>>34 ばぁか
( ゚∀゚ )<C++C++!
( ゚∀゚ )<サカナサカナサカナー ℃++<
40 :
デフォルトの名無しさん :02/11/26 00:57
ファイルの最後に改行コードがあるかどうか判別して 改行コードがあるならば、 そのまま改行コードがないならば 改行コードを追加して バッファに読み込みを行うという処理をしたいのですが、 ofstream ifstream だと一度ファイルを開いて全部読み込んで 改行コードを追加したファイルを作って 最後にまたそのファイルを読み込むという処理しか思い浮かびません。 それだとかなり処理の工程が増えてしまうのですが なにか方法はありますでしょうか? すでにあるファイルの最後に追加する処理 もしくはファイルの先頭に追加する処理 の方法がわかればもっと簡単にする方法はあるのですが、 そのようなことはできるのでしょうか?
fstreamのin|outで開けばいいんじゃん?
左のウインドウにクラスってありますよね。 今までここに表示されてる内容が 使ってるヘッダーファイルの中身だったんですが いつのまにか使ってるcppファイルの中身になってしまって… どうやって元に戻すのでしょうか?
44 :
デフォルトの名無しさん :02/11/26 05:44
static x; これってxはintになるんですか?
なるよ
46 :
デフォルトの名無しさん :02/11/26 06:13
なんでintなんですか?
規格でそう決まっているから。
48 :
デフォルトの名無しさん :02/11/26 07:11
ふーむ
>>46 ズドゥーン ∧,,∧
_ , . ; :'''"´"'' 、 l)ニ)ニ))ミ∀゚ 彡,
−=" ;,_ ; : . ',,(lllニl============ll仁二三三ミ ノ彡
´"''''- ''" ~ ̄ ̄//└l=,lヽニ⊂ノ 彡ノ
_//'  ̄ '--(,,,, ,,彡,)
>>49 (´Д`;)ヾ チンコ タッテキタ
∨)
((
51 :
デフォルトの名無しさん :02/11/26 07:59
x; これだとエラーになりますよね
昔のコンパイラはそれでも通った
それだとわかる文脈では、int は常に省略できる。
short int x;
>41 すみませんfstream調べてみましたが、 いまいちちょっと使い方がピンときません。 もう少しくわしく説明願えませんでしょうか?
56 :
デフォルトの名無しさん :02/11/26 11:48
class CHoge{ template< int n > inline int func() { return n + 1; } template< int n > inline int operator ()() { return n + 3; } }; int main() { CHoge hoge; hoge.func< 10 >(); //これは通る //hoge< 5 >(); //通らない... } この下のやつを通す方法は無いでしょうか... コンパイラーはVC7です。
>>56 class CHoge{
template< int n >
inline int func() {
return n + 1;
}
template< int n >
static inline int operator ()() {
return n + 3;
}
};
でいいんじゃない?試してないけど。
operator()は非静的メンバとして宣言したときだけオーバーロードできます。 らしいです...
hoge はテンプレート名じゃないんだから hoge<5> のような 書き方はできんでしょう。やるなら、hoge.operator()<5>() かな? とてもコンパイル通るとは思えんけど (w
演算子オーバーロードってテンプレート化できるんですか。。。
> 書き方はできんでしょう。やるなら、hoge.operator()<5>() かな? それはやっぱ通りません C++って面白いんですけど、癖がありますねぇ...
>>55 あまりうまくないが、こんなかんじで
std::fstream fs("hoge.txt",std::ios::in|std::ios::out|std::ios::binary) ;
fs.seekg(-1,std::ios::end) ;
char c ;fs.get(c) ;
if(c!='\n'){
fs.seekp(0,std::ios::end) ;
fs.put('\n') ;
}
fs.seekg(0,std::ios::beg) ;
>>61 bcc32 5.6だと通るけど
63 :
デフォルトの名無しさん :02/11/26 14:27
ヘッダでのクラスの定義なんですけど、 class A; class B; class A { class B b; }; class B : public A { }; このA、B2つの定義を別ファイルでやろうとしてるんですが、 どうにもうまくいきません どうしたら通るんでしょうか
class A; class B; class A { B* b; }; class B : public A { }; こうしといて、AのコンストラクタでBのインスタンスを渡してやればいける。
でもあんまりいいオブジェクトじゃないなぁ...
公安認定C++教習所
template< class A> class B : public A {} ; template<class C> class A { B p; C tmp; }; A<int> a; ヤター、VC6で内部コンパイルエラー!
68 :
終了10分前 :02/11/26 20:59
引き篭もり万歳!
( ゚∀゚ )さいたまさいたま!
>67 bcc や gcc でも、頑張ると内部エラー出せるぞ。れっつちゃれんじ。
56のソースをちょこっと変えればbccでも内部エラーだぞむふふ
みんな設計とかどうしてる? そこらへんのフリーのソースだけじゃ学びにくくない?
>73 > そこらへんのフリーのソースだけじゃ学びにくくない? 企業に入って研修受けると、何か設計の秘技を授けてもらえると思ってる なら大間違いだぞ。
75 :
デフォルトの名無しさん :02/11/28 10:22
operatorの使い道がわからん。 どういう時に使えばいいんだろう?
>>75 より直感的に処理を書きたいときに使えばいいんじゃないかな。
たとえば、リスト構造をもつクラスがあった場合、
n番目のアイテムを得るときに
item = list.getitem(n);
と書くところを
item = list[n];
って書けるから直感的になる。かもしれない。
>>76 リストに[]は計算時間を激しく誤解してしまいそうな
>>77 そう思ったけどパっと例が思いつかなかったのよ。
>>75 俺は長年C++しているけど、クラスとオーバーライドしか
まともに使ったことが無い。
ベクトルクラスとか行列クラスとかモナー
>>75 Money m( 2400 ); // 2400円
Wallet w; // 財布には1円も入っていない
m += 1200; // m は 3600円
m += c; // m は 4600円
w << m; // 財布に 4600円が入る
しまった。 Wallet の下に Coins<100> c(10); //100円硬貨で10枚 が入る。
>>79 なんとなくわかる
長年ってところが却って癌なんだろ
>>75 見た目がゴチャゴチャしてなくて本質的な意味が直感的にわかり可読性があがる
operator定義の中にそれにとっての本質的な処理を記述できる
86 :
デフォルトの名無しさん :02/11/28 21:49
初心者な質問ですいません。 ひとつのクラスから複数のインスタンスをつくったとき、 このクラスのパブリックな変数はインスタンスごとに違う値をとれるのですか? またとれる場合は外部から参照するときどうやったらよいのでしょう・・・?
>85 ただし、気づかぬウチに一時オブジェクトを大量生産することがあるので 注意。逆アセンブルしたら「あらびっくり」ということもある。 あと operator() は良く使うよね。
operator()は関数オブジェクトを作る時によく使うね。STLで多用。
89 :
デフォルトの名無しさん :02/11/28 22:23
>>86 >ひとつのクラスから複数のインスタンスをつくったとき
っちゅうのは、
class hoge{
public:
int m_int[10];//←複数のインスタンス
};
っちゅう解釈でよろしいか?
それとも hoge hogeInstance[2];//←複数のインスタンス ということか?
91 :
デフォルトの名無しさん :02/11/28 22:29
あ。なに言ってるんでしょうおれは。 インスタンス→オブジェクトの間違いです。
92 :
デフォルトの名無しさん :02/11/28 22:34
>>91 それでもどっちとも取れるよ。
あともうひとつ最悪の解釈もできるけど。
93 :
デフォルトの名無しさん :02/11/28 22:40
うーんほんとに初心者なのでよくわからないのですが、 class hoge{ public: int x }; というクラスから hoge a; hoge b; を生成したとき、それぞれの持つxは違う値をとれるのですか?
>>93 合ってる。
同じ値にしたい場合は static をつける。
95 :
デフォルトの名無しさん :02/11/28 22:45
ありがとうございます。 あともうひとつすいません。 こういう場合外部からどちらかのxを参照したい場合はどうすればよいのでしょう?
>>93 とれるよ。
a.x = 1;
b.x = 2;
みたいにそれぞれ別々の値が格納される。
でもその程度ならコンソールアプリで確認しながら
やったほうが2Chで聞くよりも効率いいよ。
97 :
デフォルトの名無しさん :02/11/28 22:49
なるほどそうですね・・・。 でもたすかりました。ありがとうございました!
そこらへん構造体と同じよん
feel ill! tit!
template <typename T, typename U> class hoge { void a(void) { // 処理 }; void b(void) { // 処理 }; // 他にも関数たくさん } template<>void hoge<char, int>:a(void) { // 特殊化 } template<>void hoge<char, int>:b(void) { // 特殊化 } と、あるテンプレート内の関数を2つ特殊化しようと書いたのですが これではコンパイラを通りません。 うまい書き方を教えてください。
>>100 クラス定義の最後のセミコロンが無いってこと以外は問題があるようには見えないけど。
というか、環境くらい書こうよ。
>int>:a(v ん? ::でないのか?
template <typename T, typename U> class hoge { public: void show(void) { cout << "ノーマル <" << typeid(T).name() << ", " << typeid(U).name() << ">" << endl; }; }; template<> void hoge<char, int>::show(void) { cout << "特殊 <" << typeid(T).name() << ", " << typeid(U).name() << ">" << endl; } int main() { hoge<char, char> char_char; char_char.show(); hoge<char, int> char_int; char_int.show(); hoge<int, char> int_char; int_char.show(); hoge<int, int> int_int; int_int.show(); cin.get(); return 0; } きちんと文法守れば何も問題無いはずだが。
バカは死んでくれ
>>105 誰かに言ってるんなら明記してくれ。
別に誰かに言ってるわけじゃないなら、便所で一人で言っててくれ。
>>107 つまり、106 の 「便所で一人で言っててくれ」 という希望は却下という事か?
2ch=便所 2chの書き込み=便所の落書き
便所の落書きの中にも、キラリと光るものがある。 ただの落書きか、砂粒の中の砂金かを見分ける能力がないと 2chを読んでいても何のたしにもならない。
色々スマソ
>>102 g++です。セミコロンは書き忘れ。
>>103 ::の間違いです。
>>104 特殊化する関数が一つならコンパイル通るし
ちゃんと動くんですよ。
何か文法的におかしいでしょうか?
わざわざ臭い公衆便所に入り浸らなくてもいいやん。
emplate <typename T, typename U> class hoge { public: void a(void) { cout << "ノーマル a <" << typeid(T).name() << ", " << typeid(U).name() << ">" << endl; }; void b(void) { cout << "ノーマル b <" << typeid(T).name() << ", " << typeid(U).name() << ">" << endl; }; }; template<> void hoge<char, int>::a(void) { cout << "特殊 1 a <char, int>" << endl; } template<> void hoge<char, int>::b(void) { cout << "特殊 1 b <char, int>" << endl; } template<> void hoge<int, char>::a(void) { cout << "特殊 2 a <int, char>" << endl; } template<> void hoge<int, char>::b(void) { cout << "特殊 2 b <int, char>" << endl; } int main() { hoge<char, char> char_char; char_char.a(); char_char.b(); hoge<char, int> char_int; char_int.a(); char_int.b(); hoge<int, char> int_char; int_char.a(); int_char.b(); hoge<int, int> int_int; int_int.a(); int_int.b(); cin.get(); return 0; } 通りますが? (VC6SP5) コンパイラは何使ってて、アラーメッセージはどう出てるの?
「神のために力を尽くして戦え」 と出てます
不覚・・・笑ってしまった
>>113 今ある環境(BCC)で通りました。
通らなかった環境が今ここに無いのでうろ覚えですが、
コンパイラはg++でエラーメッセージは
「もう実体化されてるぞゴルァ」とかそんな感じ。
とりあえずしょーもないミスしてないか確認してみます。
ありがとうございました。
gcc-2.95.1 MinGW gcc-2.95.2 いずれでもコンパイルできますた。 でも、emplate はさすがに通らないけどな。
118 :
デフォルトの名無しさん :02/11/30 08:06
malloc で初期化したインスタンスのコンストラクターを呼ぶ方法は無いでしょうか... p->T() は無理なのは知ってますが、 void (CHoge::*fpHoge)() = CHoge::CHoge p->*fpHoge(); としようと思うと上の関数ポインターの代入が駄目と言われます。 class CHoge{ CHoge(){ //これを呼びたい } }; template< typename T > func() { T* p; p = reinterpret_cast< T* >( malloc( sizeof( CHoge ) ) ); //p->T(); //これをやりたい } int main() { func< CHoge >(); }
placement new
121 :
デフォルトの名無しさん :02/11/30 11:40
ディレクトリを読み込むには、それぞれOSに依存のシステムコールなり APIなりを使わないといけないんですよね? winならFindFirstFile()、UNIXならopendir()/readdir()とか。 この辺の標準的なラッパとかって無いんですか? みんなどうしてんの? # Cスレで聞くべきか?
クラスをmallocで定義する馬鹿発見!
win環境でもopendirが使えるように APIがラップされたものが提供されていると思うが
>>122 >クラスをmallocで定義する
理解できないのは俺だけ?
クラスのインスタンス領域をmallocで確保する馬鹿発見! なら分からんでもない
>>124 だから、newを使えば自動的にコンストラクタが呼び出されるの!
まあ、allocatorを自作しようとしてるってんなら分からなくもない。 実際SGIのSTLはmallocとplacement newで初期化してたような気がするし(違ったらごめん)。 他に考えられるのは可変長構造体をclassでもやろうとしてるってのもあるかもな。 激しく未定義だが(特に仮想関数を持つ場合)。 それでも、mallocではなく::operator newを使うのが筋だと思う。
何をもめているのか不明だが、すでに
>>119 で答えが出ていると思うが。
そのための placement new なんでないの
132 :
デフォルトの名無しさん :02/11/30 12:59
でもどういう弊害が起こるか、具体的に説明しろといわれたら困るな。
placement newというと、確保と解放はこれでいいのかなあ? class CHoge{ public: CHoge(){ std::cout << "CHoge() called." << std::endl; } ~CHoge(){ std::cout << "~CHoge() called." << std::endl; } }; template <typename T> void func() { T* p; p = reinterpret_cast<T*>(std::malloc(sizeof(T))); new (p)T; p->~T(); std::free(p); } int main() { func<CHoge>(); }
どうもこうしなければいけないような気がする。どちらが正しいのでしょうか。 template <typename T> void func() { T* p; T* q; p = reinterpret_cast<T*>(std::malloc(sizeof(T))); q = new (p)T; q->~T(); std::free(p); } int main() { func<CHoge>(); }
T* p = new (reinterpret_cast<T*>(std::malloc(sizeof(T)))) T(); ・・・見づらい
136 :
デフォルトの名無しさん :02/11/30 17:38
\ │ / / ̄\ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ─( ゚ ∀ ゚ )< C++C++! \_/ \_________ / │ \ ∩ ∧ ∧ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄\∩ ∧ ∧ \( ゚∀゚)< C++C++C++! しぃプラ〜〜〜! >( ゚∀゚ )/ | / \__________ ________/ | 〈 | | / /\_」 / /\」  ̄ / /
これだと、デストラクタが1回しか呼び出されないのですが、 どうやったら10回呼び出せるでしょうか? class CHoge{ public: CHoge(){ std::cout << "CHoge() called." << std::endl; } ~CHoge(){ std::cout << "~CHoge() called." << std::endl; } }; int main() { char* p = reinterpret_cast<char*>(malloc(1000)); CHoge* q; q = new(p) CHoge[10]; q->~CHoge(); std::free(p); }
それともこれでいいのでしょうか。placement newの解放の仕方がよく わかりません。 class CHoge{ public: CHoge(){ std::cout << "CHoge() called." << std::endl; } ~CHoge(){ std::cout << "~CHoge() called." << std::endl; } }; int main() { char* p = reinterpret_cast<char*>(malloc(1000)); CHoge* q; q = new(p) CHoge[10]; for (int i = 0; i < 10; i++) q[i].~CHoge(); std::free(p); }
139 :
デフォルトの名無しさん :02/11/30 20:20
いいよ。
>>139 ありがとうございます。人情的にplacement newには対応するdeleteが
必要な気がしていましたが、そうではないのですね。delete[]なんて
やったらヒープ領域と勘違いして破壊してしまいますね。
cppllでいまなにやら作っている変なnicknameのお方はなんであんなにも偉そうなんですか?彼はCESとCSSの区別はついているんですか?
直接たずねればいいのに
>>140 placement new には対応する delete を書いたほうがよいです。
new(x) T;
でコンストラクトの途中で例外が発生した場合、(もし存在すれば)
対応する operator delete が自動的に呼ばれるからです。
色々ありがとうございます。 Singletonを汎用的に実装するクラスを作ることを考えていたのですが、 newをそのまま呼ぶと色々困るのでこうなりました。
staticメンバ関数の使いどころがわかりません。 class A { static int i; int j; public: static void func() { std::cout << i << std::endl; } }; int A::i; int main() { A a; a.func(); A::func(); } のようにstaticメンバだけにアクセスできるらしいのですが、プログラミング言語C++ 第3版では例えばどの節を読めばいいのでしょうか?§10.2.4などを読んでも今 ひとつすっきりしません。
>145 必要になるまでは、無理して使わんで良いって。そういうものもあるんだと 頭の片隅に起きつつ、勉強進めとけ。 いずれ factory パターンとか state パターンとかに出くわしたときに、あると 便利かなと思える日が来る。
>>145 1.隠れグローバル信仰者の逃げ道
2.インスタンス取得関数等、インスタンスがない状態で行うクラス関連の操作
3.メンバ関数へのフックの為の逃げ道(this を渡し、そこからメンバをコールする。)
基本的には static メンバ(変数、関数両方とも)は
インスタンスメンバと完全に区別して考えるべき。
俺は(俺の中の呼び方として)
static は 「クラス変数、クラス関数」とよび
non static は「インスタンス変数、インスタンス関数」と呼んで
完全にベツモノとして考えている。
staticメンバ関数=特定クラス専用friend関数。
>>146-148 わかりました。今はこういう物もあるのだと記憶にとどめる程度にしておきます。
解説書を読んでもstaticメンバ関数の存在意義について深く考察した本は見た
ことがないので、悩んでおりました。
ところで、staticメンバ関数にはthisポインタは渡るのでしょうか?staticでは ないメンバや仮想関数にアクセスすることはできないようなので、渡ってない ように思えますが・・・・・・
staticの関数の実行時にはthisは渡ってない。
> staticメンバ関数=特定クラス専用friend関数。 語弊ありすぎ
五平餅ウマー
154 :
デフォルトの名無しさん :02/12/01 12:45
初めにお断りします。このコピペは掲示板の本旨とは無関係ですが、世界の子供達の
命に関わる問題なのでどうかお許しください。興味のない方は読み飛ばしてください。
世界では今日もワクチンが足りないために7000人の幼児が亡くなっています。
世界では毎年290万人もの子どもたちが「ポリオ」「はしか」「新生児破傷風」
「結核」「百日咳」「ジフテリア」で亡くなっています。これらは予防可能な病気です。
この子たちはワクチンさえあれば助かる命なのです!
1通話300円の募金ダイヤル 0990-588-889 24時間受付で、1回300円が募金されます。
300円あれば15人分のポリオワクチンを発展途上国の子供達に届ける事が出来ます。あなたの
1通話で世界の恵まれない子供達、15人の命を守る事が出来るのです。どうかご協力をお願いします。
http://www.jcv-jp.org/home.htm http://www.lcv.ne.jp/~ono21/yobousessyu/vaccine.htm *善意の方、この文章のコピペを通常の掲示板運営に迷惑にならない程度に、
他の掲示板にも貼り付けてください。よろしくお願いします。
↑ブラクラ
ルール破る香具師が人助けか。 おめでてーな。
つーか、ノート PC の HDD 壊れたのに買い換える金もない漏れに募金してくれよ・・・
158 :
デフォルトの名無しさん :02/12/01 13:11
>>154 2chなら2chらしく3行以内で書きしる!
超でかいテキストのファイルを開いて編集するプログラム作るとき 世の中ではどういう方法が適切なのかねぇ・・・。
メモリマップトファイルとか・・・
うん、161 程度なら許せるな。 募金しないけどw 154 はいかんともしがたい
>>150 > staticではないメンバや仮想関数にアクセスすることはできない
C++ では static な関数は仮想にできないから、後ろは不要。
漏れが言ってたのはクラス CHoge の static メンバ関数に
CHoge* を渡して、こいつのメンバ関数を呼び出す事ができるって事。
C の時代のコールバック関数等は non static メンバ関数を呼び出せる形になってないので、
static メンバ関数へのポインタを渡すしかない。
コールバック時に void* などとして任意の変数が渡せる場合は
そこに CHoge* を無理矢理詰め込むことで、 non static なメンバ関数への
経由地点として static 関数を利用する事ができるわけ。
147はC++デビューしたて?
> > staticではないメンバや仮想関数にアクセスすることはできない > C++ では static な関数は仮想にできないから、後ろは不要。 (゚Д゚)ハァ? static な関数からアクセスできるかどうかの話じゃないのか?
>>164 どこらへんが?具体的に書いてみなよ(ププッ
>>165 > static な関数からアクセスできるかどうかの話じゃないのか?
何にアクセスできるかですか?
多分 「non static なメンバに」っていう意味だと思うけど、
「アクセスできるか?」だけじゃ意味が通じてないYO。
で、話は static メンバ関数に this ポインタが渡るかどうかの話です。
>>147 でのアドバイスを
>>150 さんが取り違えて、
static メンバ関数への理解に支障がでると悪いと思ったので
>>163 で
補足したのです。
で、
>>150 のはじめの「staticではないメンバ」しか「仮想関数」にできないので
わざわざ「仮想関数」まで書かなくても十分だよ。と言ってるわけですね。
Are you ok?
あぁちなみに static な関数は static じゃないメンバにアクセスできるからね!
ここで
>>164 とかはま〜た勘違いしてやっぱり
>>147 は初心者!とか決め付けてるんだろうけど、
嘘じゃないから。
static な関数が static じゃないメンバにアクセスするには条件があるだけ、
それは対象インスタンスへのポインタが必要という事。
それじゃ意味ないじゃんとか言わないように、
そのメンバが private や protected だった場合にはグローバルスコープの関数からはアクセスできないのだから、
これは static メンバ関数の特徴なんだよ。ok?
>>167 はちょっと用語を間違った。
はじめの 「static な関数」は「static なメンバ関数」に読み替えてくれ。
staticメンバ関数から非staticなメンバをアクセスするには、インスタンスの 参照かポインタを渡さなければいけないんですよね? class A { static int i; int j; public: A() : j(123) {} static void func() { std::cout << i << std::endl; } static void func2(A& ar) { std::cout << ar.j << std::endl; } }; int A::i = 456; int main() { A a; a.func(); A::func(); a.func2(a); A::func2(a); }
170 :
デフォルトの名無しさん :02/12/01 23:11
質問です。 似たような構造体に 共通の関数を使って値をセットする関数を、テンプレートをつかって 作ったのですが、リンクでエラーがでてしまいます。なぜうまくいかないのでしょうか? struct HogeA { int a; int b; }; struct HogeB { int a; int c; }; template < class T > void Set_a( T* p_Hoge , int a ) { p_Hoge->a = a; }
どんなエラーか書かない習性
172 :
デフォルトの名無しさん :02/12/01 23:16
質問です。グローバルの void* operator new(size_t); void* operator new(size_t, void*); は上書きできないんでしょうか?これは規約でしょうか? 少なくともVC++だとすでに定義されているって出てしまいます。
勘違い void* operator new(size_t, void*); だけでした。しかも <new> の中です…。
<new> にはvoid* operator new(size_t, void*);が絶対入ってるんですね。 ありがとうございました。
自己解決と書かないと自作自演に見えるよ。 あと<new>←??
質問です。 クラスのメンバに、そのクラス用コンテナを付けたいです。 (class Aのメンバにvector<A>のヤツがいるとか) C++BuilderでもHPのaC++(此度のミッションで使うコンパイラっす。)でもコンパイルが通るのですが、 こういうマネが通るという事が処理系依存なのかどうかを聞きたひ。(すっげー使いたいんで。) 例は↓の感じ。(本例、aC++で実行確認までしますた。)
int main(int argc, char** argv) { A a1(1); A a2(2); a2.Add(A(10)); a2.Add(A(11)); a2.Add(A(12)); a2.Add(A(13)); a1.Add(a2); a1.Add(A(50)); a1.print(); return 0; } 実行結果: me... 1 me end. children... me... 2 me end. children... 10 11 12 13 children end. 50 children end.
include <string> #include <iostream.h> #include <vector> class A { private: int id; vector<A> v; public: A(int a) : id(a) {;}; void Add(const A& a) {v.push_back(a);}; void print() { if(v.size() > 0) { cout << "me..." << endl; } cout << id << endl; if(v.size() > 0) { cout << "me end." << endl; } if(v.size() == 0) { return; } cout << "children..." << endl; vector<A>::iterator i; for(i = v.begin(); i != v.end(); i++) { i->print(); } cout << "children end." << endl; }; };
>>176-178 規格で定義されてるかどうかはちょとわからんけど、その例で
vector<A> は使えても list<A> が使えないコンパイラはそれなりにあったりする。
比較用のビット数の入った変数(nBitCount)を参照して
そのサイズにキャストして、比較したいのですが
動的にキャストって出来ないですか?
無理やり書いたら、
long func(long cmp,BYTE* _p,long x,long y,long w,long nBitCount)
{
long ret;
switch(nBitCount)
{
case 8:
ret = (char*)(_p + (x + (y*w))*(nBitCount
>>3 ) ) - cmp
break;
case 16:
ret = (short*)(_p..)
break;
case 32:
ret = (long*)(_p...)
break;
}
return ret;
}
・・・
全部書いてたら、死にます。
どうにかなりませんか?
何をしたいのか分からんが、nBitCount をプログラムないで指定しているのだったら template 使った方がいいぞ。
つーかこれ、 > (char*)(_p + (x + (y * w)) * (nBitCount >> 3) ) - cmp 大いに間違っていないか?
比較部分はよくわからないが、こんな感じになるんでは? template <typename T> long func(T cmp, BYTE* _p, T x, T y, T w) { return reinterpret_cast<T*>(_p + (x + (y * w)) * sizeof(T) / 8 - cmp); }
185 :
デフォルトの名無しさん :02/12/02 15:25
すみませんファイルから文字列を取ろうとして #include <iostream.h> #include <fstream.h> ・ ・ ・ ifstream fr("ファイル名"); としたら「'ifstream' シンボルがあいまいです」というエラーが出た。 どういうことなのかよくわかりません。ご伝授お願いします。
>>185 #include <iostream>
#include <fstream>
・
・
・
std::ifstream fr("ファイル名");
とやってもエラーが出るか?
>>186 名前空間!!忘れていました・・・!
ありがとう御座いました
>>187 しかし、fstream.hのように、".h"を付けると、stdネームスペースに包まれる事は
ないので、std::を付けなくても良いはずなのだが・・・・
コンパイラは何ですか?
VC++6.0ですが・・・ あるクラスのメンバ関数内で記述していたのですが、 ::ifstream fr("ファイル名"); のように :: をつけグローバル指定することで解決しました。 名前空間とは関係なかったかな・・・C++暦浅いんでよくわからないけど・・・。 他の場所でVectorやstingつかっているんで using namespace std; は入れております。
190 :
デフォルトの名無しさん :02/12/02 16:11
行列A*行列B=行列C という問題なんですけど、今こんなプログラムを考えたのですが、 これでは手計算と明らかに違ってしまいます。@とAに部分を変えればいいはずなのですがこれじゃただ足した だけになってしまいます。。。どうか教えてくださいませ! #include<stdio.h>#define N 3 #define M 3 void main(); void m_print(double [N] [M]); void m_add(double [N] [M],double[N][M],double[N][M]);void main() {double A [N] [M] = {{1,3,5},{4,8,1},{11,6,8}}, B [N] [M] = {{1.9,3.6,4.7},{7.2,8.5,8.8},{0,4,0}}, C [N] [M] ; m_print(A);printf("\n\n * \n\n");m_print(B);printf("\n\n = \n\n"); m_add(A,B,C); m_print(C); printf("\n\n"); } void m_add(double X[N][M], double Y[N][M], double Z[N][M]) { //@long g,h; for(g=0;g<M;g++) for(h=0;h<N;h++){ C[g][h]=A[g][h]*B[g][h]; // }} void m_print(double X[M][N]) { //Along i,j; printf("_");i=1; while((i++) < N){ printf(" "); } printf(" \n"); for(i=0; i<M; i++){ printf("|");for(j=0; j<N-1; j++){ printf("%10.5f,",X[i][j]); } printf("%10.5f|\n",X[i][N-1]); } printf("~"); i=1; while((i++) <N){ printf(" "); } printf(" ~\n"); // }
191 :
デフォルトの名無しさん :02/12/02 16:28
三行三列行列だからできないんですよね。。。
>>189 VC++は使ってないのでわからんが、ifstreamの多重定義に、std名前空間を
使わなかった場合のバグが残っていると思う。普通は :: なんて付けなくていい
はずです。
>>190 微妙にスレ違いだがまあいいか。n×mの行列とn×mの行列の積は、n≠mの
場合定義されない。n×mの行列とo×pの行列の積は、m==oの場合に限り
定義される。
行列の積は、L×MとM×Nの積とすると
for (i = 0; i < L; i++) {
for (k = 0; k < N; k++) {
c[i][k] = 0.0;
for (j = 0; j < M; j++)
c[i][k] += a[i][j] * b[j][k];
}
}
のように書くべし。
193 :
デフォルトの名無しさん :02/12/02 17:25
>192 ありがとうございますm(__)m この行列は3×3行列と3×3行列の積です。(数字見にくくてごめんなさい) あと、その教えてもらった数列は//@に入れればいいんですか? とりあえず3×3行列同士にして。。。ホント見にくくてすみません。 //Aとかも聞いていいですか?いそいそしてしまってますが、提出が迫り焦っています(汗 よろしかったら教えてくださいませ。
#include <stdio.h> #define N 3 #define M 3 void m_print(double [N][M]); void m_mul(double [N][M], double[M][N], double [N][N]); void main() { double A[N][M] = {{1, 3, 5}, {4, 8, 1}, {11, 6, 8}}, B[N][M] = {{1.9, 3.6, 4.7}, {7.2, 8.5, 8.8}, {0, 4, 0}}, C[N][M]; m_print(A); printf(" * \n"); m_print(B); printf(" = \n"); m_mul(A, B, C); m_print(C); } void m_mul(double X[N][M], double Y[M][N], double Z[N][N]) { int i, j, k; for (i = 0; i < N; i++) { for (k = 0; k < N; k++) { Z[i][k] = 0.0; for (j = 0; j < M; j++) Z[i][k] += X[i][j] * Y[j][k];
} } } void m_print(double X[M][N]) { int i, j; printf("_"); for (i = 0; i < N; i++) printf(" "); printf(" _\n"); for(i = 0; i < M; i++) { printf("|"); for(j = 0; j< N - 1; j++) printf("%10.5f,",X[i][j]); printf("%10.5f|\n",X[i][N-1]); } printf("~"); for (i = 0; i < N; i++) printf(" "); printf(" ~\n"); }
とにかくこれぐらいのプログラムを自分で書けないようだと、 俺たちが答えてやってもまたすぐにつまずくぞ。
そうそう、main()は次のものと差し替えてくれ。 int main() { double A[N][M] = {{1, 3, 5}, {4, 8, 1}, {11, 6, 8}}, B[M][N] = {{1.9, 3.6, 4.7}, {7.2, 8.5, 8.8}, {0, 4, 0}}, C[N][M]; m_print(A); printf(" * \n"); m_print(B); printf(" = \n"); m_mul(A, B, C); m_print(C); } return 0;がないが、C++のプログラムならこれでよい。
まだ間違えていた。 int main() { double A[N][M] = {{1, 3, 5}, {4, 8, 1}, {11, 6, 8}}, B[M][N] = {{1.9, 3.6, 4.7}, {7.2, 8.5, 8.8}, {0, 4, 0}}, C[N][N]; m_print(A); printf(" * \n"); m_print(B); printf(" = \n"); m_mul(A, B, C); m_print(C); }
C++ 相談室なのに、何でわざわざ C で書いてるんだ?
>>199 だから、微妙にスレ違いだと書いておいた(w
もしC++で書いたら、簡易行列クラスを定義して、operator*と matprint()を定義ぐらいするかなあ。printfの代わりにstd::cout を使って。 配列の初期化はコンストラクタにdouble型の一次元配列でも渡すか。
つーか、int main() は値を返せよ。
>>202 C++だと、return文がないと暗黙に0が返されるんじゃなかったっけ?
もちろんmain()に限定の話だけどね。
>>203 そんなご都合なルールが規格にあったっけ?
>>205 知らんの?プログラミング言語C++第3版§3.2(P78)を読んでみそ。
>>206 参考文献より規格を確かめろよ。
でも、そう書いてあるな。初めて知った。
ISO_IEC 14882_1998
3.6.1 Main function
5 ... If control reaches the end of main without encountering a return statement, the effect is that of executing "return 0;".
>>207 これからそうします。しかしあの英文だらけのPDF読むのもなかなか
骨が折れるんだよね。だから軟弱な俺は誤植だらけの参考文献を
読んでオナーニしてますた。
>>208 漏れも英語はあんまり読めない。
しかし、Stroustrup はどうだか分からないけど、書籍にはいい加減なものが多い。
何が正しいかを調べるには規格書が一番。
210 :
デフォルトの名無しさん :02/12/02 22:26
必要ないインクルードファイルをインクルードしていないかを 簡単に調べる方法ってないの?
>>210 コメントアウトしてコンパイルしてエラーが出ないか調べる。
C++は型チェックが厳密だから大抵エラーが出てわかる。
どうも、
>>100 です。
template <typename T, typename U> class hoge
{
public:
void a(void) { cout << "ノーマル a <" << typeid(T).name() << ", " << typeid(U).name() << ">" << endl; b();};
void b(void) { cout << "ノーマル b <" << typeid(T).name() << ", " << typeid(U).name() << ">" << endl; };
};
template<> void hoge<char, int>::a(void) { cout << "特殊 1 a <char, int>" << endl; b();}
template<> void hoge<char, int>::b(void) { cout << "特殊 1 b <char, int>" << endl; }
template<> void hoge<int, char>::a(void) { cout << "特殊 2 a <int, char>" << endl; b();}
template<> void hoge<int, char>::b(void) { cout << "特殊 2 b <int, char>" << endl; }
int main()
{
hoge<char, char> char_char; char_char.a(); char_char.b();
hoge<char, int> char_int; char_int.a(); char_int.b();
hoge<int, char> int_char; int_char.a(); int_char.b();
hoge<int, int> int_int; int_int.a(); int_int.b();
cin.get();
return 0;
}
エラーの原因は特殊化したa(void)内のb()がb(void)を特殊化する前に書かれていることのようでした。
a(void)とb(void)の記述を逆にすれば通ります。
そういうものなんでしょうか?(規格書読めってことですか)
>>212 コンパイラがテンプレートインスタンスを作成する前に、
コンパイラに特殊化を知らせないといといけない。
知らせればいいんだから、
↓こんな宣言だけ先に書いといてやれば、定義の順は逆にしなくてもよくなるけど。
template<> void hoge<char, int>::b(void);
Borland-C++5.5.1だと
>>212 は通りません(T_T)。
216 :
デフォルトの名無しさん :02/12/04 01:55
FreeBSD gcc 3.2でstd::wstringを使うと、 リンクエラーが発生してしまうのですが、 解決方法はないでしょうか? hoge% g++ a.cpp -lstdc++ /var/tmp//ccQ92fTH.o: In function `main': /var/tmp//ccQ92fTH.o(.text+0x2b): undefined reference to `std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::basic_string[in-charge]()' /var/tmp//ccQ92fTH.o(.text+0x92): undefined reference to `std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::length() const' collect2: ld returned 1 exit status ----- a.cpp ---- #include <iostream> #include <string> #include <locale> using namespace std; int main() { wstring* wstr = new wstring(); cout << wstr->length() << endl; return 0; } ---- g++ ---- Reading specs from /usr/home/hoge/gcc/lib/gcc-lib/i386-unknown-freebsd4.5/3.2/specs Configured with: ./configure --enable-languages=c,c++ --prefix=/usr/home/hoge/gcc Thread model: posix gcc version 3.2
テンプレートってコードのサイズが膨れ上がるから駄目だって友達がいうのですけど 本当の所どうなんでしょうか? キャッシュがどうのって言ってたのですけど。
インライン化によって膨れることもあるのは確かだが パフォーマンス的にそれほど劣るとは考えにくい・・・
ソートのclock()比較のプログラム作ってみたけど、インライン展開をONにする とほとんど例外なくclock()が小さくなった。 驚いたのは、Cのqsort()関数まで速くなったことだ。どうなってるの?
>>217 テンプレートを使ってコードサイズを減らす細工もつくれる。
結局は、使う側の問題。
でも普通に使ってる分には増えるのが普通だと思う。
>>217 よく聞く話だが
実例をあげて議論すべきだと思う
例えばMFCとATLのように
222 :
デフォルトの名無しさん :02/12/04 15:28
class Parent { Child child; public: Parent(): child(this){}; }; と書くとchild(this)で怒られます。 ブロック内でnew/deleteやchild.parent=thisならできますが 他にうまいやり方はないですか?
>>222 何故怒られるのかを考えましょう。最適な答えがみつかると思います。
(一定ルールを守れればその警告は無視できます。)
>>217 まぁCPUのキャッシュ使用効率とかを考慮してカリカリにチューンする
ような局面では、コードサイズが増えがちなテンプレートは嫌うだろうな。
ただ、チューンが必要なところだけinline asm使ったり、gogoやlame
みたいに一部nasm使ったりする手もあるわけで、いきなり全面否定も
どうかと思うが。
>(一定ルールを守れればその警告は無視できます。)
これは文法的に回避する方法があるということですか?
それとも
>>222 のような書き換えによってですか?
>>217 templateをコンパイラがどう処理するのかよくわからないので何とも言えませんm(_ _)m
テンプレートって上級者の証? 俺まだクラス覚えたばっかり。
>>222 エラーメッセージをちゃんと読めよ
いやだろうけど教科書読むのと同じくらい大事だぞ
>>222 エラーメッセージはコンパイラが怒ってるわけじゃないんだよ。
コンパイラ:
「すいません。私にはコンパイルできませんでした。
たぶん***が原因だと思うんですが・・・。
申し訳ないですが***を直してもう一度やってもらえないでしょうか?」
って感じだ。エラーメッセージを読めば大体理由はわかる。
(しゃべるのが下手なコンパイラもいるけどね。cl.exeとかcl.exeとかcl.exeとか・・・)
>>229 別にコンパイルできないんじゃなくて、潜在的にバグの温床になりかねんから
警告してくれてるだけじゃねぇか。
「こういうことをしてると痛い目にあう可能性があるが覚悟はいいな?」
ってだけの話。
普通にコンパイルできるじゃないか。 class Parent; class Child { public: Child (Parent* p = 0) {} }; class Parent { Child child; public: Parent(): child(this){}; }; int main() { }
警告の意味は理解しているつもりです。 知りたいのはC++では初期化リストでメンバの初期化で コンストラクタの引数にthisポインタや参照を要求されたら 一般的にどう対応するのかということです。 1.そもそもChild(Parent &parent), Child(Parent *parent)のようなコンストラクタを作らない。 2.警告を無視する。 3.parent/childの関係はよくあるので何かうまい方法があるはずでは。 なるべくなら1.2.は選びたくないので3.の方法はないのかということです。
>>235 まず、どっちが正しいか間違っているかを大局的に判断すれ
ChildをParent*で初期化するのが間違っているのか
ChildがParent*で初期化できないのが間違っているのか
これで次の1手は決まる
class Parent { Child *child; public: Parent(): { child = new Child(this); }; ~Parent() { delete child; }; };
つーかそれってクソ設計じゃん
まあ、未初期化の Parent& を渡して何が (゚д゚)ウマ- なのかはよくわからない
>235 警告を無視する。あるいは親子間のリンクを張るメソッドを別に用意して、 コンストラクタの「中」で呼ぶ。 どっちも一長一短だから、好きな方を選んでくれ。
>239 その時点では使わずに、あとで別のメソッドから使うんでしょ。 メンバ変数として Parent* ではなく Parent& を持たせたい場合、コンストラクタで 初期化するのは必須。
>>241 Parent に Child の実体を持たせて、Child に Parent の参照を持たせるような
事はできたっけ?
できたね、ごめん。
結局半端な&の仕様が糞ってことで。
a?
参照型メンバの初期化の方法がわかりません。 class Bのメンバaをどうやって初期化すればよいのでしょうか? class A { public: A() {} }; class B { class A& a; public: B() {} }; int main() { B b; }
>>246 class B {
A& a;
public:
B(A& aa):a(aa){}
};
main(){
A a
B b(a);
}
>>247 ありがとうございます。早速試してみます
249 :
デフォルトの名無しさん :02/12/04 21:43
class MyClass{ char *sDat; public: void SetDat(char *s); MyClass(char *s); MyClass(); MyClass(const MyClass &mc); ~MyClass(); MyClass & operator=(const MyClass &mc); }; C++の本で勉強中なのですが、練習問題の○×問題で、 ア.void SetDat; はprivate: なメンバ関数である。(答え ○) とあるのですが、なんで○になるのでしょうか? 激しく混乱しています・・・
なんて本?
>>250 Visual C++(2) はじめてのオブジェクト指向プログラミング
>>251 やっぱそうですか!ありがとう!
どうしてこんな誤植が発生するんだ・・・
256 :
デフォルトの名無しさん :02/12/04 22:49
ヘッダに長大なインラインメンバ関数書いたとき インライン展開されるかどうかの境目ってどこらへん?
コンパイラの機嫌によるんじゃないか? ネスト制限もあるだろうし
258 :
デフォルトの名無しさん :02/12/05 00:14
質問よろしいでしょうか? VC6を使っている者ですが、 newで確保した領域に対して_msize()で サイズを得るコードは問題が発生する可能性がありますか?
サイズを得るだけなら、VC6専用になるという問題以外は 思いつかないなあ。 つかそのサイズ使って何やるの?
260 :
デフォルトの名無しさん :02/12/05 00:26
状態遷移図を直接クラス化したようなライブラリってないですか?
>260 えぴすてーめーが本で紹介してたような気がする。
262 :
デフォルトの名無しさん :02/12/05 00:57
>>259 可変長の要素をもつ動的配列をダブルポインタで管理するので
それを元に、newで作った動的配列の要素数を知ることができれば
管理が楽になると思ったのですが…
それともSTLのlist<>などを使うべきなのでしょうか?
現状ではこうしています
inline int GetArrayLength(void* p, int typesize) {
return _msize(p) / typesize;
}
std::vectorがいいと思う
>>258 newがmalloc()したアドレスの先頭を返すなんて保証がない。
げっ通る。気持ち悪い。 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を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。