通信プログラムは組んだことがないので、わかりませんが。
( そのため、用語はわからん。 )
場合( ユーザ入力とか, 使用するプロトコルとか )によって生成するクラスを決定するなら、
デザインパターンのFactoryパターン系 ( Factory, FactoryMethod etc. ) を適用すればいいかと。
単純に考えると、
1. 生成するためのインターフェースクラスを定義する
2. 1を継承&実装したクラスを定義する
3. インターフェース型として生成する
でしょうか。
例えば、IProductインターフェースがあり、それを継承して Product1, Product2クラスを生成する。
UML風に書くと
<< IProduct >>
+ func1( void ) : bool
[ Product1 ] -> IProduct
+ CONSTRUCTOR
+ DESUTRUCTOR
...
[ Product2 ] -> IProduct
同上
みたいになります。
で、引数によってProduct1, Product2のどれかを生成し、IProduct型として返す関数を定義する。
( クラスでもいいが。 )
C++
1IProduct* CreateInstance( int sw ){
2 if( sw == 1 ){
3 return new Product1();
4 }else{
5 return new Product2();
6 }
7}
こうすれば、
IProduct* で引き受けても実体は sw が 1なら Product1, それ以外なら Product2 のになっている。
といっても、まったく関係のないもの ( ファイルの入出力系クラスと メッセージボックスを表示するクラス とか ) だと無理ですが、
ウィンドウ1 と ウィンドウ2 クラスそれぞれ微妙に違うとかなら可能かも。
[追記]
独自のメソッドが呼べないということで(思いつく)解決策を提示しますね。
方法1 : インターフェース側にそのメソッドの概要 ( C言語だとプロトタイプ宣言ってやつ )を記述する
メリット: 簡単に作れる
デメリット: 実装先も必ず実装する羽目になる
方法2: asmさんが提示されたサンプルコード内のようにキャストで行う
メリット: 独自メソッドを使うことができる
デメリット: どのクラスから生成したかわからないと厳しい
※ Javaなら instanceof でしたっけ? あれでどのクラスから生成したかわかるようになっているようですが、C++は私が知る限りでは、instanceofにそうとうするのが無いので、別の解決策が必要?
( Qtっていうライブラリ内にはあるようですが、それをするためだけに使うのはアレなので... )
方法3: 独自メソッドは直接いじらずに、そのクラスがやる ( サンプルあり )
メリット: publicだけを見た場合、インターフェースを実装してそれ以外 (独自のメソッド) は存在しないような感じに見える?
デメリット: 場合によっては不採用
[方法3を用いた場合]
C++
1class IProduct{
2 public:
3 virtual bool calc( void ) = 0;
4};
5
6class CProduct1 : public IProduct{
7 public:
8 CProduct1(){ /* メンバの初期化等 */ }
9 // デストラクタもあり
10 bool calc(void){ // このメソッド内で独自のメソッドを呼び出す
11 if( privateMethod1() ){
12 return this->privateMethod();
13 }else{
14 return false;
15 }
16 }
17 protected:
18 bool privateMethod1(){ /* 何らかの処理 */ }
19 bool privateMethod2(){ /* 何らかの処理 */ }
20 private:
21 // もちろんメンバ変数も持っている。
22};
( 簡単に言えば間接的呼び出しか。 )
方法4: IProduct, CProduct1, CProduct2 とは別に Product系を管理し間接的に使うようなクラスを定義してソイツで間接的に扱う ( 生成時は 新しく追加したクラスのほうで。 )
メリット: やろうと思えば独自メソッドでも使える
デメリット: めんどくさい。クラスが多くなる。場合によっては不採用
[方法4でやった場合]
C++
1class IProduct{
2 public:
3 virtual bool calc( void ) = 0;
4};
5
6class CProduct1 : public IProduct{
7 public:
8 CProduct1(){ /* メンバの初期化等 */ }
9 // デストラクタもあり
10 bool method1(){ /* 何らかの処理 */ }
11 bool method2(){ /* 何らかの処理 */ }
12 bool calc( void ){ /* 何らかの処理 */ }
13 private:
14 // もちろんメンバ変数も持っている。
15};
16
17class IProductEx{
18 Public:
19 virtual bool calcEx( void ) = 0;
20 virtual bool clac( void ) = 0;
21};
22
23class CProductEx : public IProductEx{
24 public:
25 CProductEx(){
26 p = new CProduct1(); // 生成 & コンポジション
27 }
28 // デストラクタで p を破棄
29
30
31 bool calc( void ){
32 return p->calc();
33 }
34
35 bool calcEx( void ){
36 if( p->method1() ){
37 return p->method2();
38 }
39 return false;
40 }
41 private:
42 CProduct1* p;
43};
方法5: すべてインターフェースに詰め込む
メリット: すべて使える
デメリット: あるクラスでは使わないメソッドでも実装しないといけない。またクラスの肥大化。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/12/08 09:43
2017/12/08 09:53
2017/12/08 10:02