例えば、
学校クラス--学年クラス--学級クラス--班クラス
というクラスがあった場合、それぞれのクラスには集約といわれる関連があると思いますが、この場合の実装は一般的にどのようにされているのでしょうか。
自分の考えでは、
class Gakko
{
vector<Gakunen> GakunenObj;
};
class Gakunen
{
vector<Gakkyu> GakkuObj;
};
class Gakku
{
vector<Han> HanObj;
}
class Han
{
void ShowName();
}
このように学校クラスが消えれば内包される学年クラス・学級クラス・班クラスも消える必要があるので、オブジェクトの寿命を親のクラスと同じにするため、各クラスに子クラスのインスタンスを持たせています。
この方法だと班の名前を表示したい場合、
Gakko Obj;
Obj.GakunenObj[a].GakkuObj[b].HanObj[c].ShowName();
といった感じでアクセスすることになると思います。
ただ、こんな長たらしいプログラムコードを見たこともありませんし、実際は通常の関連としてクラスのポインタを持たせた方がいいでしょうか。
突っ込みどころ満載ですが、よろしくお願い致します。
No.1
- 回答日時:
>クラスのポインタを持たせた方がいいでしょうか。
int array[20][20][30][10][30];
array[a + 1][b][c1 * 3 + c2][d][e1 + e2] = 13 - array[a + 1][b][c1 * 3 + c2][d][e1 + e2];
n = array[a + 1][b][c1 * 3 + c2][d][e1 + e2] + 22;
array[a + 1][b][c1 * 3 + c2][d][e1 + e2] = n + array[a + 1][b][c1 * 3 + c2][d][e1 + e2 + 1];
と
int array[20][20][30][10][30];
int *p = &array[a + 1][b][c1 * 3 + c2][d][e1 + e2];
*p = 13 - *p;
n = *p + 22;
*p = n + *(p + 1);
と、どっちの方が良いと思いますか?
答え、聞くまでもありませんよね。
No.2
- 回答日時:
いきなり
Obj.GakunenObj[a].GakkuObj[b].HanObj[c].ShowName();
なんてアクセスをするのかなぁ? 参照で逃げられることも多いような気がするけど....
ところで, 「クラスのポインタを持たせる」として, どのような実装を考えていますか?
No.3ベストアンサー
- 回答日時:
>この方法だと班の名前を表示したい場合、
>Gakko Obj;
>Obj.GakunenObj[a].GakkuObj[b].HanObj[c].ShowName();
>といった感じでアクセスすることになると思います。
上記の例の場合、直接Hanに対してアクセスするのではなく、
Gakko Obj;
... Gakko の中身生成 ...
const Gakunen& GakunenObj = Obj.Gakunen[a];
const Gakku& GakkuObj = GakuenObj.GakkuObj[b];
const Han& HanObj = GakkuObj.HanObj[c];
HanObj.ShowName();
のような流れになると思います。
また、個人的にはGakkoオブジェクトから直接班の名前を参照する、という状況自体が間違っているのだと思います。
大概「どこのクラスのどこの班の名前だけを表示する」という状況は余りなく、学年単位、クラス単位で処理を行うことが多いと思います(そのためにクラスが別になっているわけですし)。
なので、オブジェクト指向的には、「班の名前を表示する」というのが実は「その学校に所属している班の一覧を表示する」という処理の一部だとしたら、Gakkoクラスに所属している班の一覧を表示するというメソッドを実装するのがより正しいと思います。
お返事ありがとうございます。
参照を利用してアクセスできるんですね。
あとご指摘の通り、Gakkoクラスに適切な操作としては「所属している班の名前を一覧表示する」が適切ですね。
集約の実装としては、親クラスに子クラスのインスタンスを持たせ、参照を利用して子クラスの目的の操作にアクセスする。
という事でよろしいでしょうか。
あと、
Obj.GakunenObj[a].GakkuObj[b].HanObj[c].ShowName();
で直接アクセスすることに比べ、
const Gakunen& GakunenObj = Obj.Gakunen[a];
const Gakku& GakkuObj = GakuenObj.GakkuObj[b];
const Han& HanObj = GakkuObj.HanObj[c];
HanObj.ShowName();
で参照を使ってアクセスすることの方がよいメリットというのがいまいち分かりません。(前者の方がオーバーヘッドが大きいとか、コードが読みにくくなるとかでしょうか?)
No.4
- 回答日時:
>const Gakunen& GakunenObj = Obj.Gakunen[a];
>const Gakku& GakkuObj = GakuenObj.GakkuObj[b];
>const Han& HanObj = GakkuObj.HanObj[c];
>HanObj.ShowName();
>で参照を使ってアクセスすることの方がよいメリットというのがいまいち分かりません。(前者の方がオーバーヘッドが大きいとか、コードが読みにくくなるとかでしょうか?)
この場合はHanObj.ShowName();単体ですからメリットが見えませんが、オブジェクト指向プログラムで組んでいると、大概において「同じオブジェクト群に対して複数の操作を行う」ということが良くあります。
例えば、あるクラスの班員全員の名前を表示して着席させる、という場合、
const Gakunen& GakunenObj = Obj.Gakunen[a];
const Gakku& GakkuObj = GakuenObj.GakkuObj[b];
cont int n = GakkuObj.length();
for( int i=0; i<n; ++i)
{
const Han& HanObj = GakkuObj.HanObj[c];
HanObj.ShowName();
HanObj.SitDown();
}
というコーディングになります。
HanObjのオブジェクトを取り出すのにアドレスの計算は
・ObjからGakunenObjを取り出すのが1回
・GakunenObjからGakkuObjを取り出すのが1回
・GakkuObjからHanObjを取り出すのがn回(=Hanの数)
となり、合計n+2回です。
これを
cont int n = Obj.GakunenObj[a].GakkuObj[b].length();
for( int i=0; i<n; ++i)
Obj.GakunenObj[a].GakkuObj[b].HanObj[i].ShowName();
Obj.GakunenObj[a].GakkuObj[b].HanObj[i].SitDown();
}
とした場合、同じことをしているはずなのに、アドレスの計算は
・GakkenObj[a]
・GakkuObj[b]
・HanObj[i]
をforループのたびに計算しなおしていますから、n×3×2回(ShowNameとSitDownの分)となり、参照を利用した場合と比べ6倍近いアドレス計算量が必要となります。
最近のコンパイラですと上記のような単純な計算については最適化してくれるかもしれませんが、量が増えれば増えるほどバカにならない重さになる場合があります。
また、単純に添え字が大量にあるよりも現在どのオブジェクトを操作しているのか、パッとみで分かりやすい、というのもメリットかと思います。
あと、個人的にはちゃんとしたオブジェクト指向の本を一度読まれることをお勧めします。
お返事ありがとうございます。
分かりやすくて大変勉強になりました。
オブジェクト指向の本は1冊しかまだ読んでいませんので他にもいろいろ読んでみたいと思います。
あと、基本的な本しか読んだことがないので他の人が書いたコードもたくさん読んで、コーディングのスタンダード?を知ったほうが良さそうですね。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Java javaのクラスの分け方について質問です。 APIの内部用と外部用でクラスを分けたいのですがインター 2 2022/04/26 16:06
- Java JavaのSingletonパターンのprivateの持つ意味が分かりません。 5 2022/06/12 10:38
- 中学校 娘のクラスの学級通信に個人情報が掲載されていて、非常に不快です。 7 2022/04/22 18:02
- Excel(エクセル) 別シートに毎回異なるデータをコピーする 7 2022/06/24 09:02
- PHP アップロード画像数でCSSを分けることに成功したのですが、画像の横に文字を並べることが出来ません。 3 2023/07/28 17:16
- 高校 学校のコロナについてです。 私の学校には系列というものがあって、クラスは同じ子でも、みんなそれぞれ受 4 2022/12/14 08:33
- 学校 うちの学校では1.2.3と3つのクラスがあり数学の授業の際はAクラスとBクラスに分かれるのですがプリ 1 2022/06/23 19:19
- 学校 修学旅行 6 2022/06/29 22:28
- 学校 中2女子不登校です。中2の5月辺りからクラス替えの変化で1年の頃からのストレスによる頭痛が悪化し、体 2 2022/03/23 17:16
- いじめ・人間関係 中学2年です。 私はぼっちで大人しくクラスでいじめられていて担任から一度いじめてくるグループ4人に説 3 2022/08/15 22:52
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
FriendとPublicの違い。。。
-
VBのDLLの関数をVC++で使う
-
【ASP.NET】 独自で作成したク...
-
既定のコンストラクタがない?
-
DirextX9.0を使用した2Dゲーム...
-
継承を重ねた場合のコストはど...
-
ダイアログ表示時にチェックボ...
-
自作のクラスが参照できない
-
MFCのCListCtrlでスクロールを検出
-
DebugクラスとTraceクラスの違い
-
(UWSC) 「#32770」の意味わかり...
-
コンソールアプリでのクリップ...
-
イベントにAddHandlerされてい...
-
[MFC] CWnd::MessageBoxの警告...
-
C++ protectedにアクセス不可
-
C++ 図からソースコード自動生成
-
オーバーライド関数の呼び出し...
-
VBのシステムの設計書にUMLは適...
-
ダイアログクラスのコントロー...
-
クラスのアドレスを引数として...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
FriendとPublicの違い。。。
-
既定のコンストラクタがない?
-
イベントにAddHandlerされてい...
-
クラスのアドレスを引数として...
-
ダイアログ表示時にチェックボ...
-
(UWSC) 「#32770」の意味わかり...
-
エディットコントロールのイベ...
-
エディットコントロールでEnter...
-
WindowsAPIのリストビューの...
-
CMainFrameクラスの使い方
-
DebugクラスとTraceクラスの違い
-
MessageBoxを継承したい
-
C++ protectedにアクセス不可
-
MFCアプリのコマンドラインでパ...
-
このコンパイルエラーの意味に...
-
MFCのドラッグ&ドロップについて
-
【ASP.NET】 独自で作成したク...
-
派生クラスから基本クラスprote...
-
ダイアログクラスのコントロー...
-
C#で通常のbuttonコントロール...
おすすめ情報