質問するログイン新規登録

回答編集履歴

1

補足の追加

2017/12/10 02:46

投稿

BeatStar
BeatStar

スコア4962

answer CHANGED
@@ -54,4 +54,116 @@
54
54
 
55
55
  といっても、まったく関係のないもの ( ファイルの入出力系クラスと メッセージボックスを表示するクラス とか ) だと無理ですが、
56
56
 
57
- ウィンドウ1 と ウィンドウ2 クラスそれぞれ微妙に違うとかなら可能かも。
57
+ ウィンドウ1 と ウィンドウ2 クラスそれぞれ微妙に違うとかなら可能かも。
58
+
59
+ -----------------------------------------------------------------
60
+ [追記]
61
+
62
+ 独自のメソッドが呼べないということで(思いつく)解決策を提示しますね。
63
+
64
+
65
+ ```ここに言語を入力
66
+ 方法1 : インターフェース側にそのメソッドの概要 ( C言語だとプロトタイプ宣言ってやつ )を記述する
67
+ メリット: 簡単に作れる
68
+ デメリット: 実装先も必ず実装する羽目になる
69
+ ```
70
+
71
+ ```ここに言語を入力
72
+ 方法2: asmさんが提示されたサンプルコード内のようにキャストで行う
73
+ メリット: 独自メソッドを使うことができる
74
+ デメリット: どのクラスから生成したかわからないと厳しい
75
+ ※ Javaなら instanceof でしたっけ? あれでどのクラスから生成したかわかるようになっているようですが、C++は私が知る限りでは、instanceofにそうとうするのが無いので、別の解決策が必要?
76
+ ( Qtっていうライブラリ内にはあるようですが、それをするためだけに使うのはアレなので... )
77
+ ```
78
+ ```ここに言語を入力
79
+ 方法3: 独自メソッドは直接いじらずに、そのクラスがやる ( サンプルあり )
80
+ メリット: publicだけを見た場合、インターフェースを実装してそれ以外 (独自のメソッド) は存在しないような感じに見える?
81
+ デメリット: 場合によっては不採用
82
+ ```
83
+
84
+ [方法3を用いた場合]
85
+ ```C++
86
+ class IProduct{
87
+ public:
88
+ virtual bool calc( void ) = 0;
89
+ };
90
+
91
+ class CProduct1 : public IProduct{
92
+ public:
93
+ CProduct1(){ /* メンバの初期化等 */ }
94
+ // デストラクタもあり
95
+ bool calc(void){ // このメソッド内で独自のメソッドを呼び出す
96
+ if( privateMethod1() ){
97
+ return this->privateMethod();
98
+ }else{
99
+ return false;
100
+ }
101
+ }
102
+ protected:
103
+ bool privateMethod1(){ /* 何らかの処理 */ }
104
+ bool privateMethod2(){ /* 何らかの処理 */ }
105
+ private:
106
+ // もちろんメンバ変数も持っている。
107
+ };
108
+ ```
109
+
110
+ ( 簡単に言えば間接的呼び出しか。 )
111
+
112
+ ```ここに言語を入力
113
+ 方法4: IProduct, CProduct1, CProduct2 とは別に Product系を管理し間接的に使うようなクラスを定義してソイツで間接的に扱う ( 生成時は 新しく追加したクラスのほうで。 )
114
+ メリット: やろうと思えば独自メソッドでも使える
115
+ デメリット: めんどくさい。クラスが多くなる。場合によっては不採用
116
+ ```
117
+
118
+ [方法4でやった場合]
119
+ ```C++
120
+ class IProduct{
121
+ public:
122
+ virtual bool calc( void ) = 0;
123
+ };
124
+
125
+ class CProduct1 : public IProduct{
126
+ public:
127
+ CProduct1(){ /* メンバの初期化等 */ }
128
+ // デストラクタもあり
129
+ bool method1(){ /* 何らかの処理 */ }
130
+ bool method2(){ /* 何らかの処理 */ }
131
+ bool calc( void ){ /* 何らかの処理 */ }
132
+ private:
133
+ // もちろんメンバ変数も持っている。
134
+ };
135
+
136
+ class IProductEx{
137
+ Public:
138
+ virtual bool calcEx( void ) = 0;
139
+ virtual bool clac( void ) = 0;
140
+ };
141
+
142
+ class CProductEx : public IProductEx{
143
+ public:
144
+ CProductEx(){
145
+ p = new CProduct1(); // 生成 & コンポジション
146
+ }
147
+ // デストラクタで p を破棄
148
+
149
+
150
+ bool calc( void ){
151
+ return p->calc();
152
+ }
153
+
154
+ bool calcEx( void ){
155
+ if( p->method1() ){
156
+ return p->method2();
157
+ }
158
+ return false;
159
+ }
160
+ private:
161
+ CProduct1* p;
162
+ };
163
+ ```
164
+
165
+ ```ここに言語を入力
166
+ 方法5: すべてインターフェースに詰め込む
167
+ メリット: すべて使える
168
+ デメリット: あるクラスでは使わないメソッドでも実装しないといけない。またクラスの肥大化。
169
+ ```