- 1 名前:デフォルトの名無しさん mailto:sage [2008/03/09(日) 19:37:43 ]
- C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。 IDE (VC++など)などの使い方の質問はその開発環境のスレに お願いします。
- 182 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 09:41:11 ]
- >>180
freind じゃダメな理由を書いた方が答えが得られやすいと思う。
- 183 名前:>>182 mailto:sage [2008/03/23(日) 09:42:51 ]
- ミスった... orz
freind ⇒ friend
- 184 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 09:45:07 ]
- friend先に依存が出来るからじゃね?
普通、friendは最終手段だし
- 185 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 12:07:26 ]
- そんなことはない。
- 186 名前:>>182 mailto:sage [2008/03/23(日) 13:05:05 ]
- friend 先に依存って何?
- 187 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 13:58:48 ]
- 一部のクラスだけ特別扱いするというのがManagerクラスの仕様なら、
friendによる依存は妥当だと思う。
- 188 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 14:45:51 ]
- 一部のクラスの基底クラスとして
Manager を取得するクラスを作って、 その1つだけを friend にすれば?
- 189 名前:180 mailto:sage [2008/03/23(日) 14:58:22 ]
- friendが結構な数になってしまうんです。
下手すれば私のリアルfriendより多いぐらい それが悔しくて
- 190 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 14:59:16 ]
- 誰が上手い事を言えと
- 191 名前:184 mailto:sage [2008/03/23(日) 15:01:24 ]
- 俺は181に一票で
- 192 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 15:02:43 ]
- その方法を聞いてるんだろw
- 193 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 15:09:28 ]
- パスワード掛ければいいんじゃないですかね
- 194 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 15:14:48 ]
- w
- 195 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 15:25:03 ]
- 権限プログラミングってのも面白そうじゃないか
- 196 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 15:42:23 ]
- singletonなら簡単なのにな
- 197 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 16:01:39 ]
- 思い出したw
____ |← reject| boostの中の人 singleton ユーザー . ̄.|| ̄ ̄ ┗(^o^ )┳(`Д´)┳(^o^ )┛≡=- || ┏┗ ┗┗ ┏┗ ≡=-  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
- 198 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 16:06:07 ]
- ユーザーは欲してると思うが
- 199 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 16:34:52 ]
- にわかに得た知識で面白いこと考えた!
Managerのインスタンスを受け取る関数の引数に関数オブジェクトを使って 内部で一定のアルゴリズムで正しい値を返すもの(パスワードの暗号化みたいな)にのみそのインスタンスを渡してやる風にすればいいんじゃね? 更にインスタンスを受け取る関数をテンプレート化してやり、欲しい権限までのクラス型インスタンスを返すようにしてやればアクセス制限も出来て完璧! とここまで考えてわざわざこんなことしてもオーバーヘッドが大きいだけなことに気づいた そもそも何の意味があるんだっけか
- 200 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 16:45:12 ]
- だから >>188 でいいだろ、別に。
- 201 名前:デフォルトの名無しさん [2008/03/23(日) 16:57:35 ]
- Managerクラスコンストラクタなどをprotectedにして、使うクラスはManagerを継承する。
- 202 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 17:02:41 ]
- >>188 >>199 >>201
これらの方法は、Managerクラスの許可なく好き勝手に権限のあるクラスを作れる。 そういうのを>>180は制限したいんじゃないの?
- 203 名前:>>182 mailto:sage [2008/03/23(日) 17:08:28 ]
- >>201
そう言うのは最悪。 あとから見て、継承が本当に必要だったのか、単に特定のメソッドを 使わせるために継承しているのかがわからなくなるから。
- 204 名前:201 [2008/03/23(日) 17:21:39 ]
- >>203
意味がよく分からないけど、、、「特定にメソッドを使わせるために継承が必要かどうかがわからなくなる」ってこと? そんなこと言ってたら何もできない。 friendだったら、なぜfriendにしたか分からなくならないの? friend よりいいと思うけどな。 friend じゃprivateのメンバにアクセスできてしまう。 Managerクラスを機能を利用するんだから、継承しかないでしょ。 使う側のクラスに持たせるとなると、コンストラクタとかはpublicになってしまうし。
- 205 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 17:40:32 ]
- 継承すると
Managerの中のstaticでない変数とか勝手に作られない?
- 206 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 17:41:03 ]
- >>203
Manager クラスじゃなくて単に許可コントロール用の class を作る というのは有りじゃない?そういう例をまともな本で見た記憶がある。
- 207 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 17:42:27 ]
- -カーズは-
2度と地球へは戻れなかった…。 鉱物と生物の中間の生命体となり 永遠に宇宙空間をさまようのだ。 そして死にたいと思っても死ねないので ―そのうちカーズは考えるのをやめた。 全部globalにすればいいじゃん
- 208 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 17:44:01 ]
- >>206
電波の缶詰の人のサンプルもそうだった ライブラリ的なものを 外部からいじられないようにするためだったら そんな感じでもいいんじゃまいか 村八分
- 209 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 17:47:19 ]
- Managerインスタンスを受け取るために、Managerにコールバックしてもらえばいいんじゃない?
class FriendClassA; // 前方宣言 class FriendClassB; class Manager { public: class Friend { public: virtual void authorize(Manager* m) = 0; }; void getInstance(Friend* p) { if( dynamic_cast<FriendClassA*>(p) || dynamic_cast<FriendClassB*>(p) || /* 権限のあるクラスかをチェック */ ) { p->authorize(this); } } };
- 210 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 18:25:34 ]
- それは、インスタンス取るのに時間かかるし
friendでいいじゃんって話になるも
- 211 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 18:40:51 ]
- 速度が重要ならtemplate部分特殊化とかで。
class Manager { public: template <class Unauthorized> static void authorizedProc(unauthorizedClass * p) { std::cout << "not authorized" << std::endl; } template <> static void authorizedProc(authorizedClassA * p) { p->Proc(m_instance); } // 以下許可するクラス分同じコード private: Manager m_instance; }; 冗長だし検証してないけど。
- 212 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 18:45:30 ]
- Manager を使えるクラスを作成する場合には
ファクトリクラスを通すようにする。 で、そのファクトリクラスを friend にして、 そこで Manager クラスを取得して、 各クラスにそれを渡すようにする。 設定関数は各クラスの共通基底クラスに作って、 それをファクトリクラスの friend にする。
- 213 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 18:46:54 ]
- 先輩から聞いたのですが、extern "C" {}せずに構造体を宣言すると、
余計なクラス情報がくっつくって本当ですか?
- 214 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 18:52:41 ]
- そんなことは聞いた事が無いが、
特定のコンパイラでそういう事があるとかいうんだったら俺は知らない。
- 215 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 18:55:11 ]
- クラス情報って具体的には何なんだ?
- 216 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 18:57:34 ]
- >>213
マングリング名にクラス情報がくっつくって話だと思う。
- 217 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 18:59:55 ]
- >>214-216
言ってたのはシリコンバレー帰りの先輩です 純粋なCの構造体にするにはやはりextern "C"が必要なのですね。 ありがとうございました。
- 218 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 19:00:36 ]
- >>217
どこからそういう判断をしたんだ?w
- 219 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 19:01:52 ]
- 構造体にextern "C"は関係無いだろ
- 220 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 19:02:10 ]
- >>216
構造体名って C でそもそも何らかのマングリングされるの?
- 221 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 19:07:59 ]
- C++なら名前空間やらなんやらくっつくだろ。
- 222 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 19:10:41 ]
- C で付かないなら
純粋な C の構造体かどうかなんて どう区別するんだろうか。
- 223 名前:>>182 mailto:sage [2008/03/23(日) 19:46:38 ]
- >>204
まじめな話、もう一度継承についてちゃんと勉強した方がいいと思う。 (>>205 の内容を理解できてる?) 継承はアクセス制限のためにあるものじゃない。 極端な話、全てが public であったとしても、継承は有用。 これに対して、friend は純粋にアクセス制限を回避するもので、かつ アクセス制限を回避する以外の機能は無いから、なぜ friend にしたか がわからなくなることはない。 (もちろん、なせアクセス制限を回避する必要があるかはどっかに書いて おく必要があるだろうけど。) >>206 それならアリだと思う。
- 224 名前:201 [2008/03/23(日) 19:54:02 ]
- >>223
>>205 作られるけど。外から参照されたくないものはpublicにしなけらばいいじゃん
- 225 名前:201 [2008/03/23(日) 20:00:37 ]
- >>223
>継承はアクセス制限のためにあるものじゃない。 >極端な話、全てが public であったとしても、継承は有用。 だから、継承が駄目なんですか? 継承は色んな意味で使えて「わかりにくい」から駄目ってこと?
- 226 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 20:00:37 ]
- 何かもう駄目だなここって思ったの俺だけだろうか
- 227 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 20:02:29 ]
- Manager 使ってる部分を別プロジェクトにする。
あとは各クラスのオブジェクト生成を外部から隠せばいい。
- 228 名前:>>182 mailto:sage [2008/03/23(日) 21:01:54 ]
- >>224
> 作られるけど。外から参照されたくないものはpublicにしなけらばいいじゃん おいおい、ほんとにもう少し勉強してからこいよ。 引っ込みつかなくなってるだけならいいけど、マジでそう思ってるとしたら ちょっとまずいよ。 まずい理由の一つは、private でもその変数が見えなくなるわけじゃない、 アクセスできなくなるだけだから。 この違いわかってる? >>225 > 継承は色んな意味で使えて「わかりにくい」から駄目ってこと? >>203 に書いたのはそう言うこと。 それしか方法が無いならしょうがないけど、friend と言うもっといい方法があ るのにわざわざ使わないのは、別の意図があるようにとられる危険性が高い。
- 229 名前:201 [2008/03/23(日) 21:17:23 ]
- >>228
>マジでそう思ってるとしたらちょっとまずいよ。 Managerを継承していないクラスから参照されたくない場合はpublicにすれば良いって事だよ? >まずい理由の一つは、private でもその変数が見えなくなるわけじゃない、 >アクセスできなくなるだけだから。 「見える」→メンバ変数の値が取得できる。(getter) 「アクセス」→メンバ変数の値が書きかえれる。(setter) って意味で言ってるのなら getter、setter定義してやれば、当然見えるしアクセスも可能。
- 230 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 21:42:53 ]
- もしかして201氏は、
Managerは1つのクライアント(Managerを使うクラスオブジェクト)の管理のみ引き受けるもので、 クライアントと同数のManagerオブジェクトが必要と考えているのではないだろうか。
- 231 名前:>>182 mailto:sage [2008/03/23(日) 22:07:14 ]
- >>229
> 「見える」→メンバ変数の値が取得できる。(getter) > 「アクセス」→メンバ変数の値が書きかえれる。(setter) ほら、全然理解できてない。 簡単な例でいうと、 int a, b; class X { private: int a; }; class Y: public X { int foo(){ return a; } int bar(){ return b; } }; ってやると、foo() の中で X::a をアクセスしようとするからエラーになるよね。 もし、C++ の private が変数を「見えなくする」なら bar() の b と同じように、 foo() は ::a を返すはずだろ? これが、「見えなくなること」と「アクセスできなくなること」の違いなわけ。 これによる、影響は自分で調べてみてね。 >>230 まあ、それはそれでそれこそもっとよく考えろとしか言えないわけだが...
- 232 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 22:11:42 ]
- 何でこんな残念なスレになってしまったんだ。
- 233 名前:デフォルトの名無しさん [2008/03/23(日) 22:12:43 ]
- だって にちゃん だもの
- 234 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 22:56:01 ]
- VSyncの話したらひどいことになりそう
- 235 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 22:57:56 ]
- >>231
初心者スレでやれ ウザイ
- 236 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 23:03:27 ]
- 結局>>182って文句言ってるだけで答えて無いじゃん
- 237 名前:>>182 mailto:sage [2008/03/23(日) 23:14:58 ]
- 答えは >>188 で既にでてるだろ。
まあ、10個ぐらいなら全部 friend 宣言してもいいと思うけど。 もしかして君も >>201 みたいに理解できてないやつなの? (w
- 238 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 23:32:29 ]
- >>188だとManager::getInstanceみたいなので取得するのと大差無いと思うが・・・
まぁ、それはともかく、>>180にfriendなどを使ってまで 制限する必要性があるのか、疑問だな。 クラスごと使わせなくするとこにfriendを使用している時点でおかしいと思う。 無名名前空間やdetails名前空間で十分なんじゃないか?
- 239 名前:201 [2008/03/23(日) 23:44:18 ]
- >>231
>foo() の中で X::a をアクセスしようとするからエラーになるよね。 アクセッサをManagerの方に定義することを考えていたんだけどな。 「見える」「見えない」の話じゃんくてprivateだからだろ。 >もし、C++ の private が変数を「見えなくする」なら bar() の b と同じように、 foo() は ::a を返すはずだろ? グローバル変数よりメンバ変数を参照しにいくのは知ってます。 Managerの方に「一部のクラス」に使わせたい機能だけ、protected または public にして 一部のクラスがManagerを継承すればいい。 Manager のprivateのメンバには「一部のクラス」も参照できない。 「一部のクラス」以外にManagerクラスのインスタンスを作られるのが困る場合は コンストラクタなどをprotectedにすればいいんでは? 「一部のクラス」に対してManagerは一つらしいので、また違ってきますが・・・・
- 240 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 23:58:52 ]
- これで friend いらない
-- friends.cpp #include "A.h" #include "B.h" namespace { class Manager {}; Manger& manager(); } void A::f() { manager().a(); } void B::g() { manager().b(); }
- 241 名前:>>182 mailto:sage [2008/03/24(月) 00:06:26 ]
- >>238
> まぁ、それはともかく、>>180にfriendなどを使ってまで > 制限する必要性があるのか、疑問だな。 それは、>>180 に聞いてもらわないとダメだけど、そう言う状況はありえると思うよ。 例えば、デバッグのためにマネージャの状態を直接見たりいじったりするクラスとか。 ただ 10個もあるのは、ちょっと多すぎるような気はするけどね。 >>239 頼むから、もう少し勉強してからレスしてくれ。 全然俺の言ってることが理解できてないよ。
- 242 名前:デフォルトの名無しさん mailto:sage [2008/03/24(月) 00:08:40 ]
- で、アホなのはどっちなの?初心者なのでよく分かりません
- 243 名前:デフォルトの名無しさん mailto:sage [2008/03/24(月) 00:51:50 ]
- >>242
やり方は色々ある。って話に落ち着けていいんじゃないのw メイヤーズもそんなことeffective c++に書いてたでしょ。
- 244 名前:デフォルトの名無しさん mailto:sage [2008/03/24(月) 05:56:56 ]
- >>242
「そいつの中にあるもの」の質はともかく、 「そいつの中にあるものを説明する能力」はどっこいどっこいです。
- 245 名前:デフォルトの名無しさん [2008/03/24(月) 17:47:39 ]
- 仮想関数を持たないクラスXとクラスYがあります。
YはXを継承しています。これらのクラスに対応する インターフェイスのクラスIXとIYを以下のように定義しました。 しかし、コンパイルエラーでした。クラスYは抽象クラス とみなされたようです。でも、クラスYはf()の定義も g()の定義も持っているので抽象クラスではないように思えます。 XとYのインターフェイスを作る方法を教えて下さい。 class IX { virtual void f() = 0; }; class X : public IX { void f() {} }; class IY : public IX { virtual void g() = 0; }; class Y : public X, public IY { void g() {} }; int main() { Y y; // エラー(抽象クラスあるいは構造体のオブジェクトが宣言されています) return 0; }
- 246 名前:デフォルトの名無しさん mailto:sage [2008/03/24(月) 17:54:22 ]
- IX IX
↑ ↑ X IY ↑↑ Y という継承木になっている。 X::IX::f は定義されているが、 IY::IX::f は定義されていない。 インタフェースクラスを作るなら、IX を仮想継承する必要がある。 ただ、それでも Y で f を定義する必要がある。 あと、インタフェースクラスに限らず、基底クラスには 必ず仮想デストラクタを定義するのを忘れないように。
- 247 名前:デフォルトの名無しさん [2008/03/24(月) 18:14:09 ]
- >>246
ありがとうございます。 以下のように変更したらエラーが警告になりました。 この警告は無視していいような気がします。 >あと、インタフェースクラスに限らず、基底クラスには >必ず仮想デストラクタを定義するのを忘れないように。 OKです。 class IX { virtual void f() = 0; }; class X : virtual public IX { void f() {} }; class IY : virtual public IX { virtual void g() = 0; }; class Y : public X, public IY { void g() {} }; int main() { Y y; // 警告('Y' : 2 つ以上のメンバが同じ名前を持っています。'X::f' から継承します。) return 0; }
- 248 名前:デフォルトの名無しさん mailto:sage [2008/03/24(月) 18:50:40 ]
- Y::f では X::f と IY::f のどっちの実装を使えばいいのか分からないというもの。
まあ、今回の場合は IY::f に実装がないから X::f を使いますよという警告だけど、 Y に void f() { X::f(); } と書いておくのが無難。
- 249 名前:デフォルトの名無しさん mailto:sage [2008/03/24(月) 19:06:35 ]
- class T
{ T( int ); } を T *T_array = new T [100]; は出来ないじゃん? #placement new使えってのはなしで。 std::vectorはどうやってこういうコンストラクタが引数を持ってるクラスを受け入れてるの?
- 250 名前:デフォルトの名無しさん mailto:sage [2008/03/24(月) 19:07:20 ]
- placement newで
- 251 名前:デフォルトの名無しさん mailto:sage [2008/03/24(月) 19:11:33 ]
- >>248
上の例では void f() 1個だけですが、実際のIXは純粋仮想関数を 22個もっています。Yに22個の関数をわざわざ定義するのはなんだか 無駄な気がするのですが。。。
- 252 名前:デフォルトの名無しさん mailto:sage [2008/03/24(月) 19:18:29 ]
- >>251
まあ、面倒なら今のところは無視してもいいかもしれない。 コメントでも書いとこう。
- 253 名前:デフォルトの名無しさん mailto:sage [2008/03/24(月) 19:26:44 ]
- >>241
頼むから、もう少しまともな説明してくれ。
- 254 名前:デフォルトの名無しさん mailto:sage [2008/03/24(月) 19:31:33 ]
- >>252
わかりました。ありがとうございました。
- 255 名前:デフォルトの名無しさん mailto:sage [2008/03/24(月) 19:31:46 ]
- friend 使うと「一部のクラス」が増えるとManagerも弄らないと駄目だな。
- 256 名前:デフォルトの名無しさん mailto:sage [2008/03/24(月) 19:34:11 ]
- 拡張性を敢えて犠牲にするなら、個別に friend するしかない。
拡張性もある程度考慮するなら基底クラス作ってそれだけ friend 。 あとは本人がどうしたいか、だな。
- 257 名前:デフォルトの名無しさん mailto:sage [2008/03/24(月) 20:12:41 ]
- >>253
非常に初歩的な内容だし、あの説明で理解できないなら、 もうあきらめた方がいいぞ。
- 258 名前:デフォルトの名無しさん mailto:sage [2008/03/24(月) 22:58:50 ]
- IDすら出ない板で煽り煽られ大変ですな
- 259 名前:180 mailto:sage [2008/03/24(月) 23:04:33 ]
- 私の為に喧嘩しないで><。
- 260 名前:デフォルトの名無しさん mailto:sage [2008/03/24(月) 23:59:31 ]
- struct B{
struct P{ B *temp; } B( P p ){ swap( *this, *(p.temp) ); } operator P (){ P p; p.temp = this; return p; } }; B Return(){ return B(); } void Accept( B &b ){}; ------------ Accept( Return() ); //Error 俺、何間違えてるの?
- 261 名前:デフォルトの名無しさん mailto:sage [2008/03/25(火) 00:06:50 ]
- 設計?
- 262 名前:デフォルトの名無しさん [2008/03/25(火) 00:07:13 ]
- エラーメッセージはキチンと書く
- 263 名前:デフォルトの名無しさん mailto:sage [2008/03/25(火) 00:09:50 ]
- ;
- 264 名前:デフォルトの名無しさん mailto:sage [2008/03/25(火) 00:11:00 ]
- 質問の仕方
- 265 名前:デフォルトの名無しさん mailto:sage [2008/03/25(火) 00:11:54 ]
- >>263
- 266 名前:デフォルトの名無しさん mailto:sage [2008/03/25(火) 00:11:55 ]
- Bにデフォルトコンストラクタないからとか?
- 267 名前:デフォルトの名無しさん mailto:sage [2008/03/25(火) 01:12:43 ]
- Humanクラスを基底クラスとするTanakaやAsouやIshikawaクラスがあるとします
Humanは抽象クラスとして用いるつもりです このときHumanにあるstaticメソッドを一回だけ呼び出したいときってどうすればいいでしょうか? Humanのコンストラクタで呼び出したとすると、TanakaやAsouのコンストラクタでも呼び出されますよね static bool initのような変数をフラグとして使う方法は思いついたのですが、 もっとスマートな方法はないのでしょうか?
- 268 名前:デフォルトの名無しさん mailto:sage [2008/03/25(火) 01:16:38 ]
- シングルトンやそれに関わるC++の実装は非常に面倒くさくて
自分で一からやろうと思うとどうしても乱雑になる。 マルチスレッドが入ってくるともっと面倒くさくなる。
- 269 名前:デフォルトの名無しさん mailto:sage [2008/03/25(火) 01:25:21 ]
- >>260
人生、かな?
- 270 名前:デフォルトの名無しさん mailto:sage [2008/03/25(火) 01:49:26 ]
- >>267
そのメソッドを呼び出したいのは、Human派生のオブジェクトを生成したタイミングなの?
- 271 名前:267 mailto:sage [2008/03/25(火) 02:13:35 ]
- >>270
そうですね Human派生のオブジェクトを生成する前に呼び出しても構わないのですが
- 272 名前:デフォルトの名無しさん mailto:sage [2008/03/25(火) 02:30:23 ]
- >>271
であれば、全てが始まる前に自分で一度だけ呼ぶのが良いと思うな。
- 273 名前:デフォルトの名無しさん mailto:sage [2008/03/25(火) 02:31:52 ]
- >>272
それはstaticな変数をフラグにするよりダメじゃねぇかw
- 274 名前:267 mailto:sage [2008/03/25(火) 02:39:11 ]
- >>272
あぁそうか、そもそもstaticなメソッドなわけだから int main(){ Human::onlyOnceCalled() みたいなかんじで 最初の方で適当に呼んでおくってのもありかもしれませんね 一回だけしか呼ばないって保証がないような気もしますが
- 275 名前:デフォルトの名無しさん mailto:sage [2008/03/25(火) 02:49:38 ]
- >>274
必ず最初に読んでしまってよいなら、クラスにスタティックなメンバを定義して それの初期化の中で実行させてみては? // human.h class Human() { // 中略 class Initializer { Initializer() { onlyOnceCalled(); } }; static Initializer init; }; // human.cpp Human::Initializer Human::init; 文法間違ってたらすまん
- 276 名前:275 mailto:sage [2008/03/25(火) 02:51:47 ]
- Human::Initializerのコンストラクタがpublicになってないとか、いろいろダメだorz
そこは適当におぎなって
- 277 名前:267 mailto:sage [2008/03/25(火) 03:01:51 ]
- >>275
なるほど。こういう方法もあるんですね 勉強になりました ありがとうございました
- 278 名前:デフォルトの名無しさん mailto:sage [2008/03/25(火) 03:05:20 ]
- 保証が欲しかったのか。失礼。
initialization orderを気にするならこんな感じかな。 class Human() { class Initializer { Initializer() { onlyOnceCalled(); } public: static void Initialize() { static Initializer instance; } }; }; これで、Initializer::Initializeを呼んだタイミングで一度だけ初期化されるようになるよ。ただしこの場合は複数スレッドとかが動き出す前に呼んでね。
- 279 名前:260 mailto:sage [2008/03/25(火) 09:32:50 ]
- ぇ?コンパイル通る?
gccだと通らないんだけど・・・
- 280 名前:デフォルトの名無しさん mailto:sage [2008/03/25(火) 09:53:30 ]
- >>279
どこを見てそう思うんだよ・・・ 指摘してくれてるだろ >>263 >>266 あとAcceptがReturnの返す一時オブジェクトを参照してるから何とかしよう
- 281 名前:デフォルトの名無しさん mailto:sage [2008/03/25(火) 11:14:49 ]
- >>279
まずは省略や手抜きをせずに、Bの定義を全部書け。 そして何をしたいのかはっきりさせろ。
- 282 名前:260 mailto:sage [2008/03/25(火) 16:02:29 ]
- いや、やりたいことは下のやつを知りたかっただけ。
ja.wikibooks.org/wiki/More_C%2B%2B_Idioms/%E6%89%80%E6%9C%89%E6%A8%A9%E7%A7%BB%E5%8B%95%E3%82%B3%E3%83%B3%E3%82%B9%E3%83%88%E3%83%A9%E3%82%AF%E3%82%BF(Move_Constructor) に書いてあることってnon-const referenceを受けるべきとろこに一時オブジェクトを渡せるって話だと思って、 渡してみたらコンパイラ通らないどーん。な状況。
|

|