公共および民間のアドレスとパスワードを設定したメンバーで機能を

StackOverflow https://stackoverflow.com/questions/504257

  •  21-08-2019
  •  | 
  •  

質問

私はクラス(クラスがありますが、ここでは引き継がれるその他のクラス記述すことはできない。また別のクラスのクラスの、そのものを継承A.

して使用された東京オリンピックへのアクセスの会員機能なアクセスを継承します。

なので、これらの会員機能をすべき公共Bが、民間です。

なぜで使用しないで"友'ディレクティブ?

お願い致します。

編集:例ではなぜ必要なのです。

class A
{
public:
  void PublicFunc()
  {
    PrivateFunc();
    // and other code
  }
private:
  virtual void PrivateFunc();
};

class B : public class A
{
private:
  virtual void PrivateFunc()
  {
    //do something and call A's PrivateFunc
    A::PrivateFunc(); // Can't, it's private!
  }
};
役に立ちましたか?

解決

あなたが言うどのようなものです:Aのサブクラスの2セットは1セットのアクセス権を持っている必要があり、他のセットはいけない存在。これは、サブクラスの唯一のブランド(すなわちB)を有することが間違っていると感じAのメンバーを「見る」。

何を意味している場合のみ:の私たちがを私たちのクライアントは、他のリゾートがあることはできませんが、

、機能ののこのの部分を使用することができます。

(問題のこの種の継承により、機能の再利用は、多くの場合、コーナーあなたを。あなたが凝集して再利用に向けて行く場合は、それを回避することがあります。)

提案ます:

// separate the 'invisible' from the 'visible'.
class A_private_part {
protected: 
  int inherited_content();
public:
  int public_interface();          
};

class B_internal : public A_private_part {
};

class A_export : private A_private_part {
public:
    int public_interface() { A_private_part::public_interface(); }
};

// client code
class ClientClass : public A_export {
};

しかし、より良い集約道を行くことであろうと、目に見えるものと見えない部分に現在の「A」を分割します:

class InvisibleFunctionality {
};

class VisibleFunctionality {
};

class B {
    InvisibleFunctionality m_Invisible;
    VisibleFunctionality m_Visible;
};

// client code uses VisibleFunctionality only
class ClientClass {
    VisibleFunctionality m_Visible;
};

他のヒント

あなたがすることはできません。それは友人が何のためにあるのかだ。

の代替は、あなたのプログラムの設計/アーキテクチャを変更することです。しかし、この上のヒントのために、私はいくつかのより多くのコンテキストが必要と思います。

というんだ、そして 友人 が最善の選択です。毎符号化の標準を推奨しない使用 友人 ながのデザインはさらに複雑なもの-それだけの値打ちはあるのです。

問題なく友達し、それぞれ異なった建築

Oneソリューションが利用形態の pImplム が"B"からの内部実装はオブジェクト、その他お客様から外クラスです。

別のある場所でキャリーの継承と"A"及び"その他クライアント".のようなもの:

class A {
public:
  void foo ();
  void bar ();
};

class B : public A {  // OK access to both 'foo' and 'bar'
};

class ARestricted : private A {
public:
  inline void foo () { A::foo (); };    // Forwards 'foo' only
};

しかし、このソリューションがでます。'ARestricted'変換できないため、'A'ことが必要となる場合がある解決その他の"ゲッターは"'A'.しかし、名称はこの機能なども呼び出すことはできません偶然:

  inline A & get_base_type_A_for_interface_usage_only () { return *this; }

後もうその他のソリューション、仮にこの階層に必要とについて説明していただけましょう 友人!

編集: なので xtofl ことを示唆したい"は'A'-'AInternal"と"ARestricted'を'A'.

この作品を除き、気がつくと"B"が無くなる'A'.しかし、AInternalき受け継ぎなし、'B'導かれたことから'AInternal'および'A'!

class AInternal {
public:
  void foo ();
  void bar ();
};

class A : private virtual AInternal {
public:
  inline void foo () { A::foo (); };    // Forwards 'foo' only
};

// OK access to both 'foo' and 'bar' via AInternal
class B : public virtual AInternal, public A {
public:
  void useMembers ()
  {
    AInternal::foo ();
    AInternal::bar ();
  }
};

void func (A const &);

int main ()
{
  A a;
  func (a);

  B b;
  func (b);
}

もちろん今回も実施しました。仮想基盤、複数の遺!音....現在は、良きにつけ悪しきにつけもっともより一 友人 宣言は?

私はあなたがここに大きな問題があると思います。あなたのデザインは、音がいないようです。

1)私は「友人の構築物は、

で始めることは問題だと思います 「友人が」ではない、あなたが望むものである場合は、

2)、あなたのデザインを再検討する必要があります。

私はあなたのどちらかだけの仕事を取得し、何か、使用して「友人」を行うか、より堅牢なアーキテクチャを開発する必要があると思います。 一部の<のhref = "http://www.tml.tkk.fiを見てみましょう/~pnr/Tik-76.278/gof/html/」のrel = 『nofollowをnoreferrer』>デザインパターンはを、私はあなたが有益な何かを見つけることができます確信しています。

EDITます:

あなたのサンプルコードを見た後、あなたは間違いなく再アーチをする必要があります。クラスAは、それは少しトリッキーですので、あなたのコントロール下であってもよいが、多分あなたは、クラスBがあることを再やりたくたくないかもしれません「は、」代わりのクラス「で、」クラスます。

public Class B
{
    B() 
    {

    }

    void someFunc()
    {
       A a; //the private functions is now called and a will be deleted when it goes out of scope
    }

};

私はこれに興味深い課題を見つけます。ここで私はこの問題を解決する方法です。

class AProtectedInterface
{
public:
    int m_pi1;
};

class B;
class A : private AProtectedInterface
{
public:
    void GetAProtectedInterface(B& b_class);

    int m_p1;
};

class B : public A
{
public:
    B();
    void SetAProtectedInterface(::AProtectedInterface& interface);

private:
    ::AProtectedInterface* m_AProtectedInterface;
};

class C : public A
{
public:
    C();
};

C::C()
{
    m_p1 = 0;
//    m_pi1 = 0; // not accessible error
}

B::B()
{
    GetAProtectedInterface(*this);

    // use m_AProtectedInterface to get to restricted areas of A
    m_p1 = 0;
    m_AProtectedInterface->m_pi1 = 0;
}

void A::GetAProtectedInterface(B& b_class)
{
    b_class.SetAProtectedInterface(*this);
}

void B::SetAProtectedInterface(::AProtectedInterface& interface)
{
    m_AProtectedInterface = &interface;
}
あなたはどこパターンのこの種のすべての時間を使用しようとしている場合、

は、テンプレートを使用してコードを減らすことができます。

template<class T, class I>
class ProtectedInterfaceAccess : public I
{
public:
    void SetProtectedInterface(T& protected_interface)
    {
        m_ProtectedInterface = &protected_interface;
    }

protected:
    T& GetProtectedInterface()
    {
        return *m_ProtectedInterface;
    }

private:
    T* m_ProtectedInterface;
};

template<class T, class I>
class ProtectedInterface : private T
{
public:
    void SetupProtectedInterface(I& access_class)
    {
        access_class.SetProtectedInterface(*this);
    }
};

class Bt;
class At : public ProtectedInterface <::AProtectedInterface, Bt>
{
public:
    int m_p1;
};

class Bt : public ProtectedInterfaceAccess<::AProtectedInterface, At>
{
public:
    Bt();
};

class Ct : public At
{
public:
    Ct();
};

Ct::Ct()
{
    m_p1 = 0;
    // m_pi1 = 0; // not accessible error
}

Bt::Bt()
{
    SetupProtectedInterface(*this);

    m_p1 = 0;
    GetProtectedInterface().m_pi1 = 0;
}

理解してい:

  • とするサブクラス化によるその他の開発者向けです。
  • Bするサブクラス化による外部の開発を継承A.
  • はいくつかの手法によってお使いに外部の開発を通じてB.

とは思わないこなします。あん作のスーパークラスのみを直接inheritors.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top