• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:クラス間でのクラスの共有?)

クラス間でのクラスの共有

このQ&Aのポイント
  • クラスAとクラスBの間で情報の共有方法について
  • クラスAとクラスBでの情報共有の最適な方法は何か
  • クラスAがクラスBに情報を渡す方法について

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

ポインタや参照として、引数として渡すのはスタンダードな方法ですが その場合でも、渡す回数や関数呼び出し回数等は最小限で済むように、カプセル化を十分強めておくことが 大変有効です。 それを踏まえたうえで、別の方法も色々とあります。 方法1. B clsB("c:\\aaa.txt") A clsA; この順番で確実に作るのでしたら、こういうのも考えられます。 class B; //前方宣言 class A { const B* const b; //ポインタ(や参照)を持たせる public: A( const B* b_ ) : b(b_) {} void fnc() const; }; //ソース void A::fnc() const { b->output(); } 方法2. もしAとBが意味的に十分強い関係性を持ち、セットに出来るようなケースでは、方法1のように別々に作ってからポインタを受け渡したりせずに、AがBの生成と破棄を管理してもいいでしょう。 方法3. Bがログ出力専用のようなクラスで、一つだけなど、特定の個数あれば十分な場合 自分自身にstaticな方法でインスタンスを管理させて、どこからでもstatic関数で呼び出せるようにする といった方法も考えられます。 class B { static B* b; //生成されるインスタンス格納用 char path[256]; B( const char* ); //コンストラクタを始め、staticでないメンバはすべてprivateでもOK void output() const; public: static void Init( const char* c ){ b = new B(c); } static void Cleanup(){ delete b; b = NULL; } static void output_S(){ if (b) b->output(); } }; あとはソースに B* B::b( NULL ); とでも書いておきます。 これで、最初の方に B clsB("c:\\aaa.txt") のかわりに B::Init( "c:\\aaa.txt" ); としておき 後は引数として渡さなくてもどこからでも B::output_S(); だけで呼び出せます。 そして終了前に解放します。 B::Cleanup(); 方法4. とりあえず、引数でやるけど クラス数がB,C,D…と増えるといった場合 別に構造体等を作っておいて、それだけいじれば済んでしまう、という形にしてしまうのもいいでしょう。 例 class B; class C; class A { public: void ABC( const B&, const C& ); void ABC2( const B&, const C& ); void ABC3( const B&, const C& ); }; ここにDを単純に加える場合 class B; class C; class D; class A { public: void ABC( const B&, const C&, const D& ); void ABC2( const B&, const C&, const D& ); void ABC3( const B&, const C&, const D& ); }; こうなってしまう、というのであれば stuct DATA { const B* b; const C* c; }; とかを別途作っといて struct DATA; class A { public: void ABC( const DATA& ); void ABC2( const DATA& ); void ABC3( const DATA& ); }; などとしておくことで、このDATA構造体を書き変えるだけで stuct DATA { const B* b; const C* c; }; ↓ stuct DATA { const B* b; const C* c; const D* d; }; 同様の効果が得られます。

その他の回答 (2)

回答No.3

おそらくは、クラスを使うべきではないところで無理やりクラスを使おうとしています。 クラスというのは、たんなる関数の寄せ集めではなくて、ある程度の自律性を持った機能の集合です。 で、一番自然な使い方は、複数のインスタンスを生成して、それぞれのインスタンスごとの振る舞いを行わせるということです。 だから、ログをとるというクラスがあれば、いろいろなログを独立してとる(それぞれに独立したインスタンスが存在する)のであれば、有効です。 一方で、一連のログ(早い話が、ログファイルファイっこしかない)をあちこちで収集するなら、「一連のログをとる」関数郡をひとまとめにすれば言いいのです。 C++には、namespace という機能があって、そういう用途にも使えますから、 logFiles::init(char *filePathName); で最初にログファイルを設定して、 logFiles::appendNormal(char *message); で、正常なログを追記して、 logFiles::appendError(char *message); でエラーログを追記して のようなこともできます。 また、本当に、処理のあちこちで、いろいろなログをとりたいのなら、「このログファイルへの追記」というのがそれぞれ明確でしょうから、「このログファイル」を指定するために、クラスのインスタンスを渡すべきです(というか、インスタンスを渡すのではなくて、「該当するログを担当しているインスタンスに、ログをとるようにメッセージを送信する」という考え方が、正解)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

普通は「クラス (のインスタンス) を引数として渡す」ものなんだけど.... むしろ, どうして「その方法は使いたくありません」と思ったのでしょうか?

C_S_C
質問者

補足

Tacosanさん回答ありがとうございます。 >どうして「その方法は使いたくありません」と思ったのでしょうか? あくまで予定ではあるのですが 例えばクラスAの複数の関数で呼ぶなどとなった場合や クラスCが追加になった場合など、すべてに引数として渡すのは どうかなと思ったので、ほかの方法があるならそっちの方がいいのかな と考えたからです。 (そもそもコンストラクタなどでファイルパスを指定するのが正しいのか よくわかっていないこともありますが・・・)