2017-12-24 20 views
1

オブジェクトAには、タイプBのオブジェクトの配列があります。クラスBにはメソッドB1、B2、...があります。型Bのオブジェクトへのポインタですが、メソッドB9〜B10のみが公開されます。呼び出し元はメソッドについて知ってはいけません呼び出し元に返されたインスタンスのメソッドを隠す

タイプBのオブジェクトへのポインタを返すときに、メソッドB1〜B8を隠す方法を教えてください。私が使用していますC++

UPDATE:

オブジェクトAがBのすべてのメソッドにアクセスする必要があるが、唯一のAの外に方法にB9-B10を公開しますが

+0

あなたはどの言語を使用していますか? – APerson

+0

プライベートにするには? –

+0

これを行うにはいくつかの方法があります:継承を公開し、プライベートスコープで 'Base :: B9'を使用し、プライベート継承を使用し、' B1-B8'を公開スコープで公開するか、クラスB 'プライベートメンバーになり、' B1-B8'の周りにインラインラッパーを書く。最後のものは空の基底の最適化を防ぎ、パブリック継承は基底クラスへのキャストを許可することに注意してください。 –

答えて

1

これはProxy Pattern.のための場所のように思えますProxyBクラスは、B9 - B10のみを公開します。

しかし、私の意見では、メソッドB9とB10で十分であれば、独自のインターフェイスを作ることになります。これらの2つのメソッドは、独自のクラスインタフェースでなければなりません。 BがメソッドB1〜B8とメソッドB9〜B10を持つBAで構成されていれば、単にBBへのポインタを返すことができます。私は考えることができる

+0

メンバー関数を隠すことが基本的に重要な場合は、プロキシパターンを使用する場合は私的継承を強くお勧めします。しかし、それは公共の範囲で 'B :: B1'を使うことと非常に簡単です。おそらく最高のソリューション。 –

+0

これは私が望むものに近いと思うが、コンセプトに少し難しかった。 AがBのすべてのメソッドにアクセスする必要がある場合、Bproxyオブジェクトを作成することはできません。 AだけがBproxyを作成し公開する場合、Bのすべてのメソッドにどのようにアクセスできますか? AはBのすべてのメソッドにアクセスでき、Bproxyオブジェクトのみを返すように、Aは2つのリストを作成する必要があります(BオブジェクトのリストとBproxyオブジェクトの2番目のリスト(Bへのポインタを含み、Bメソッドを呼び出すメソッドのサブセットを提供します)。発信者ですか?あなたは小さな事例を作れますか? – TSG

+0

B_1_to_8とB_9_to_10から派生したオブジェクトBを作成しますか?両方の基本オブジェクトは同じメンバ変数にアクセスする必要があります。私はどのようにこれを実装するか分からない。私はこれが本当に私が望むものに近いと思う。 – TSG

0

一つのアプローチは、コンストラクタクラスBのオブジェクトを使用して唯一の方法B9B10を提供Cという名前の別のクラスを持つことです。

class C 
{ 
    private: 
     B B_object; 
    public: 
     C(B i_obj){ 
      B_object = i_obj; 
     } 
     void B9_wrapper(){ 
      B_object.B9(); 
     }   
     void B10_wrapper(){ 
      B_object.B10(); 
     } 
} 

して、ポインタ(のはそれa_method名前を付けてみましょう)を返しますAのあなたの方法、Cの対象にBのオブジェクトを変換して、後者のオブジェクトへのポインタを返すことがあります。

class A{ 
    private: 
     B arr[10]; // array of objects of B 
    public: 
     void method_a(){ 
      // let arr[3] be the object you want to return a pointer of 
      C result {arr[3]}; 
      return &result; 
     } 

あなたのお役に立てば幸いです。

0

ここではさまざまなオプションがあります。プロキシパターンを使用する必要がありますが、そのうちの1つを除いた落とし穴があります。

基本クラスは、ここでは、4つのメンバ関数と理論的な、些細な、空の基本クラスを持っています。我々はそれらの2つを公開したい。

class Base 
{ 
public: 
    void b1() {}; 
    void b2() {}; 
    void b3() {}; 
    void b4() {}; 
}; 

公共の継承、私たちは公共にしたいメソッドの多くを持っていますが、わずか数は、我々は非表示にしたい場合は、公共の継承を使用するように誘惑することができる方法に

を隠します派生クラスのいくつかのメソッドを非表示にします。例えば:それは効果的に派生クラスに弱い提案をレンダリングする、誰もが安全に基本クラスとしてクラスを扱うことができますベースクラスにstatic_castを可能にするので

class Derived1: public Base 
{ 
public: 
    char* x() { return x_; } 

private: 
    using Base::b3; 
    using Base::b4; 

    char x_[2]; 
}; 

私は、ありませんが、これを行うことをお勧めします、最高でも。

プライベート継承は、それが基底クラスへのアクセスstatic_castを防ぐため、これは、たくさんの私のお気に入りです方法

を公開し、暗黙的に依存しているだろう、reinterpret_castを、またはアクセスにCスタイルのキャストしてみてください基本クラス(それはまだ標準によって保証されていますが、はるかに強力な提案です)。

class Derived2: private Base 
{ 
public: 
    using Base::b1; 
    using Base::b2; 
    char* x() { return x_; } 

private: 
    char x_[2]; 
}; 

ラッパー/アダプタ

この最後の試みはベースのみ場合(基底クラスへのすべてのアクセスを防止するため、最強の保証を提供しますが、増加したクラスのサイズの潜在的なコストでそうクラス)が空である:

class Wrapper1 
{ 
public: 
    void b1() { b_.b1(); } 
    void b2() { b_.b2(); } 
    char* x() { return x_; } 

private: 
    Base b_; 
    char x_[2]; 
}; 

概要

上記のすべてに利点があり、すべてに落とし穴があります。 2番目または3番目のオプションを使用することをお勧めします。既存のクラスをラップし、理由の中で必要なインターフェイスでのみ使用できるパブリックインターフェイスを提示します。

+0

私はベースから派生するという考え方が好きでしたが、AはBのすべてのメソッドにアクセスする必要があります(Bオブジェクトから派生したインスタンス化はできません)。 Aは各Bのメソッドのうちのいくつかを公開する必要がありますが、残りは隠す必要があります。 – TSG

関連する問題