2016-05-28 15 views
2

私は以下のような2つのクラスを持っています。C++の別のクラスのクラスの複数のオブジェクトをカプセル化

class Hand 
{ 
public: 
    func1(); 
    func2(); 
    ... 
    func20(); 
private: 
    Hand(); 
    ~Hand(); 
    Hand(const Hand& that); 
    void operator=(Hand const&); 
    friend class Body; 
}; 

class Body 
{ 
public: 
    Body(); 
    ~Body(); 
    Hand * const &left_hand; 
    Hand * const &right_hand; 
private: 
    Hand * _left_hand; 
    Hand * _right_hand; 
}; 

Body::Body() 
:left_hand(_left_hand) 
:right_hand(_right_hand) 
{ 
    _left_hand = new Hand(); 
    _right_hand = new Hand(); 
}; 

これはハンド/ボディの関係に従います。手は体に属します。 -

  1. ユーザーはHandオブジェクトを作成/削除できません。
  2. Bodyに属するHandオブジェクトのコピーを作成することはできません。
  3. ユーザーはBodyオブジェクトの左手と右手のポインタを変更できません。

しかし、私の同僚は、ユーザーがメンバーオブジェクトのメソッド(この場合はbody->left_hand->func1())を直接呼び出すことができないと言っています。

getter funtion(例:getLeftHand())を使用して、読み取り専用のパブリック変数left_handの代わりにHand * constを返すことを提案しました。あなたが見ることができるように

もう一つは

class Body 
{ 
    Body(); 
    ~Body(); 
    leftHandfunc1(); 
    rightHandfunc1(); 
    leftHandfunc2(); 
    rightHandfunc2(); 
    ... 
    leftHandfunc20(); 
    rightHandfunc20(); 
private: 
    Hand * _left_hand; 
    Hand * _right_hand; 
}; 

そして

Body::leftHandfunc1() 
{ 
    _left_hand->func1(); 
} 

などの各手の機能のためのラッパー関数を作成することでしたが、手の20個の方法は、体内の40のラッパー関数に等しいです。そして、このリストは成長すると予想されます。私はこのアプローチをとるべきでしょうか?

もっと良い選択肢はありますか?

+0

抽象基底クラス(インタフェース)を導入して、 'Hand'の別個の作成とインタフェースはどうでしょうか? –

+0

あなたの 'class body'は' private' memebrしか持っておらず、 'public'はそれが誤字ですか? – user463035818

+2

体のインターフェイスを通して手のすべての機能を公開したい場合は、手だけを公開してください。 –

答えて

1

私は(のみ読み取りアクセス用)公に利用可能な機能を公開Handするためのインタフェースを作成します:あなたは安全のためconst参照ゲッターを配ることができますBodyクラスで

struct IHand 
{ 
public: 
    virtual void func1() const = 0; 
    virtual void func2() const = 0; 
    ... 
    virtual void func20() const = 0; 
    virtual ~IHand() {} 
}; 

class Hand : public IHand 
{ 
public: 
    void func1() const; 
    void func2() const; 
    ... 
    void func20() const; 
private: 
    Hand(); 
    ~Hand(); 
    Hand(const Hand& that); 
    void operator=(Hand const&); 
    friend class Body; 
}; 

_left_handおよび_right_handは、以下のとおり:

class Body 
{ 
public: 
    Body(); 
    ~Body(); 
    const IHand& left_hand() const { return _left_hand; } 
    const IHand& right_hand() const { return _right_hand; } 
private: 
    Hand _left_hand; 
    Hand _right_hand; 
}; 

クライアントは次のようにインターフェースにアクセスすることができます。

Body body; 

body.left_hand().func1(); 
body.right_hand().func20(); 

このデザインは、すべての制約のために一致します

  1. ユーザーは、手オブジェクトを作成/削除することはできません。
  2. Bodyに属するHandオブジェクトのコピーを作成することはできません。
  3. ユーザーはBodyオブジェクトの左手と右手のポインタを変更できません。

私はを変更すると何を意味するか、あなたの最後の点について確認されませんでした。だから私は予防策としてすべてのインターフェイスをconstにしました。

+0

ポイント3では、私はbody.left_hand = body.right_handが可能ではないことを意味しました。以前の改訂が私のために働いた。 'Hand'のコンストラクタは' Body'のコンストラクタの最後で呼び出される必要があるため、ポインタを使用しました。 'Body'コンストラクタで計算される特定の変数を' Hand'コンストラクタに渡します。同様に、 'Body'デストラクタが始まる前に' Hand'を破壊する必要があります。現在のソリューションでこれが可能なら、それは素晴らしいことです。 –

+0

@ShaunakGupte _ "同様に、Bodyデストラクタが始まる前にHandを破壊する必要があります。" _これは私のコード例ではすでにそうです。 –

関連する問題