以下のような相互参照は、
感覚的には、なるべくならしない方が良いと感じるのですが、
どのようなメリット・デメリットがあるでしょうか?
class A
B* m_b
class B
A* m_a
■少なくとも、多くのクラスによって構成された巨大なDLLが、
相互参照ばかりで作られると、
(1)クラスAのポインタ型のメンバーが、クラスB内で値が変わりうる、
また、クラスBを、クラスCで参照していたら、そこでも値が変わりうる。
さらにクラスCを、クラスDで参照していたら、(略)となり、
処理・メンバー値の変更の影響の把握が困難になる。
(2)lib/objの作成順のミスや管理、
(3)いずれかのクラスのリコンパイルが発生した時、
リリース物のリコンパイルが発生しまくる。
ということがあり、良くないと考えています。
- - - - - - - - - - - - - - -
相互にインタフェースし合う項目を、メンバーとして宣言しつつ、
そのGetter、Setterを用意すれば、強結合にせずに作れるという認識ですが合っていますか?
class A
B* m_b
int x1、y1、z1
x1、y1、z1のGetter、Setter
class B
Privateなメンバーx、y、z
int x2、y2、z2
x2、y2、z2のGetter、Setter
.
No.1
- 回答日時:
人によって意見が分かれるところかもしれませんが、
相互参照自体は若干注意が必要ではあるが特に問題がある設計ではないと思います。
たとえば、
・フォルダは自分が持っているファイル、フォルダを知っている
・ファイルは自分が保存されているフォルダを知っている
とか
・学校は所属する学生を知っている
・学生は通学している学校を知っている
という感じで現実に相互参照があリますので、それをコードにしたときに相互参照する
のは自然だと思います。
質問に書かれている問題点というのは、要するに相互参照ではなく、結合度の問題です。
各モジュールの結合度が高いとまさに質問に書かれているような問題が発生するので良くありませんが、
それは相互参照でなくとも発生する一般的な問題です。
ちゃんと設計をして、低結合、工凝集なモデルを作る、というのが教科書的ではありますが一般的対策です。
これらの問題にgetter,setterは関係ありません。
オブジェクト指向言語であれば、抽象クラスやインタフェースを使って
依存度を下げるというのが定石です。
たとえば、
// 乗り物(公共交通機関的なもので)
class Vehicle
{
// 今乗っている乗客
vector<Passenger*> passengers;
// 運賃
virtual int price();
};
// 乗客
class Passenger
{
// 今乗っている乗り物
Vehicle* vehicle;
};
となっていると相互参照ですが、これをベースに
class Bus : public Vehicle
class Taxi : public Vehicle
という風に実装すると、乗客から見ると乗り物の詳細を知らなくても一般的な
交通機関のインタフェースを知っていれば、あらゆる乗り物に大体同じ方法で乗れる
というような実装ができます。
この回答への補足
なるほどです。
結合度・凝集度が大事ですね。
確かに
学生が学校を知っていて、
学校も学生を知っている例のときのなど、
(学生側からは、「授業に出る」のメソッドで、「知識」のメンバー変数が更新され、
学校側こらは、「教える」ことで、「資金」のメンバーが更新される
といったことは自然に感じます)
ただ、そういうとき、それぞれのメンバー変数に、
お互いのポインタを持ち合う必要があるかというと、
それぞれのクラスが、メソッドを「static」かつ「public」として提供すれば良いと思うのです。
No.2ベストアンサー
- 回答日時:
必然性が無い場合でも相互参照にしたほうが便利になる、ということがよくあります。
たとえば先ほどの大学と学生の話で、
大学の所属学生一覧は必要なのでとりあえず次のように大学を作ったとします。
class College
{
public:
vector<Student*> students;
};
それで、各学生の所属大学内での何かの順位を取得する機能が必要だったとして、たとえば
A:student->GetRankInCollege();
のような設計にするにはstudentの所属大学の情報を得るために Student内にCollegeクラスへの参照が必要です。
ですが、相互参照が嫌という判断で、これを
B:college->GetRank(student);
のように実装したり、
C:GetRankOfStudent(college, student);
のように実装したりすることもできます。
ですが、B,Cの場合、これらの機能を利用するプログラマからすれば、
たとえば、「現在のユーザのランクをログインページに表示する」
といったことをしたい場合にいちいち
・現在ログインしている学生
・その学生が所属している大学
の2つを管理しなければならないという手間が発生します。
上記例の場合、単純にあらゆる箇所でcollege, studentのペアをちゃんと管理する、という労力が
あまり大きくないと判断すれば無駄に相互参照にする必要はありません。
ですが、そのあたりの管理を単純にしたいと思った場合に、「相互参照になるからこのような設計にはしない」
のように考えるほどのリスクは無いと思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Java 複数TBLのオブジェクトを1つの変数(オブジェクト)でまとめて管理したい 1 2022/12/17 00:12
- その他(社会・学校・職場) 年下に対しての不快感、どう切り替えていけばいいでしょうか 6 2022/04/18 10:18
- Java JavaのSingletonパターンのprivateの持つ意味が分かりません。 5 2022/06/12 10:38
- 友達・仲間 今年の春から通い始めた専門学生生活の人間関係でとても悩んでる日々です…。少しでもアドバイス頂けたら有 2 2022/06/17 13:45
- テニス スクールで私は中級クラスで隣のコートで初級クラスがあります。 レッスンが終わったあと後は両方のクラス 1 2022/05/29 18:58
- 友達・仲間 コミュ障や人見知りにも限度があると思っていて、本気で悩んでるので少しでもアドバイス頂けたら有り難いで 2 2022/05/28 20:38
- Visual Basic(VBA) EXCEL VBAにて動的にCheckBOXを複数作成し、同BOXにイベントを追加したい 1 2023/03/16 07:05
- その他(恋愛相談) 情けないというか悔しすぎる話があるのですが、クラスでとても気になってた子が他クラスのイケイケのメンバ 2 2022/12/17 00:06
- いじめ・人間関係 中学2年です。 私はぼっちで大人しくクラスでいじめられていて担任から一度いじめてくるグループ4人に説 3 2022/08/15 22:52
- いじめ・人間関係 高2。今度クラス会があります。 行ってみたいけど、クラスではぼっちだし、楽しめるか不安なので参加する 6 2023/03/24 21:15
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
FriendとPublicの違い。。。
-
既定のコンストラクタがない?
-
名前空間について
-
クラスの作成方法を教えてください
-
(UWSC) 「#32770」の意味わかり...
-
MFCアプリのコマンドラインでパ...
-
DLLからEXEのクラスを呼び出す...
-
DataGridViewのセルに斜線を引...
-
VBのシステムの設計書にUMLは適...
-
ダイアログクラスのコントロー...
-
オーバーライド関数の呼び出し...
-
C#で通常のbuttonコントロール...
-
C++ protectedにアクセス不可
-
ダイアログ表示時にチェックボ...
-
コンソールアプリでのクリップ...
-
DateAdd関数について質問があり...
-
CMainFrameクラスの使い方
-
[MFC] CWnd::MessageBoxの警告...
-
MFCでのシリアル(232C)通信方法
-
ボタンのオーナードローについて
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
FriendとPublicの違い。。。
-
既定のコンストラクタがない?
-
イベントにAddHandlerされてい...
-
クラスのアドレスを引数として...
-
ダイアログ表示時にチェックボ...
-
(UWSC) 「#32770」の意味わかり...
-
エディットコントロールのイベ...
-
エディットコントロールでEnter...
-
WindowsAPIのリストビューの...
-
CMainFrameクラスの使い方
-
DebugクラスとTraceクラスの違い
-
MessageBoxを継承したい
-
C++ protectedにアクセス不可
-
MFCアプリのコマンドラインでパ...
-
このコンパイルエラーの意味に...
-
MFCのドラッグ&ドロップについて
-
【ASP.NET】 独自で作成したク...
-
派生クラスから基本クラスprote...
-
ダイアログクラスのコントロー...
-
C#で通常のbuttonコントロール...
おすすめ情報