문제

클래스 B에서만 작동 해야하는 클래스 A를 올바르게 캡슐화하려고합니다.

그러나 나는 클래스 B에서 물려 받고 싶다.

친구 B를 갖는 것은 효과가 없습니다. 우정은 상속되지 않습니다.

내가 원하는 것을 성취하는 일반적으로 받아 들여지는 방법은 무엇입니까, 아니면 실수를하고 있습니까?

조금 더 색상을 제공하기 위해 클래스 A는 복잡한 시스템의 상태를 나타냅니다. 클래스 A 상태를 변경하기 위해 적용 할 수있는 조치 인 B에 의해서만 수정되어야합니다.

도움이 되었습니까?

해결책

B의 후손이 A에 직접 액세스하도록 허용하고 싶다고 생각하십니까? A와 B가 단단히 결합되면 독립적 인 정의가 아닌 B 자체 내에서 보호 된 클래스 정의를 만들 수 있습니다. 예를 들어

class B
{
protected:
    class A
    {
    };
};

또 다른 아이디어

class A
{
friend class B;
private:
    void DoSomething();
};

class B
{
protected:
    void DoSomething(A& a) { a.DoSomething(); }
};

다른 팁

재 설계해야 할 것 같습니다. 클래스 A는 상태를 나타내지 만 클래스 B는 일련의 행동을 나타냅니다. 거기에는 관계가 있지만 상속 관계는 아닙니다. 나는 구성을 제안한다; 당신은 내가 알 수있는 한 ISA 관계보다 더 많은 Hasa 관계를 원합니다.

내가 당신을 올바르게 이해한다면, 당신은 b를 갖고 싶습니다 그리고 그것은 파생물입니다 클래스 A의 내부 구현에 액세스하려면 예?

불행히도 C ++는 C# 및 Java와 같은 언어가 가지고있는 "내부"보호 수준이라는 개념이 없습니다.

당신은 사용을 고려할 수 있습니다 개인 구현 패러다임 (PIMPL) - 불투명 포인터라고도 알려져 있으며, A 및 B의 소비자가 보지 못하는 공공 액세스 수준을 사용하여 시스템 내에서 기능을 노출시킵니다.

모든 것을 유지하는 가장 쉬운 방법은 B에 보호 된 방법을 추가하여 필요한 A의 동등한 기능에 액세스하는 것입니다. 이것은 B의 서브 클래스로 캡슐화를 열어줍니다.

이것을하는 가장 간단한 방법은 단순히 b가 a를 포함하는 것입니다.

클래스 B {보호 : A_; };

그런 다음 B에서 상속하고 A를 조작 할 수있는 클래스 C를 작성할 수 있습니다. C가 A에게 임의의 작업을 수행 할 수 없다면 B로 개인을 만들고 C가 할 수있는 B로 보호 된 방법을 제공해야합니다. 승인 된 일을 A에게 사용하는 데 사용합니다.

클래스 B {private : a_; 보호 : void dosomethingtoa (); };

격리는 갈 길입니다 (클래스 B는 A 형의 개인 구성원이 포함되어 있음) B에서 B의 일부 가상을 무시하지 않는 한. 개인 상속 가장 가까운 것입니다.

왜 당신이 상속하고 싶은지 알 수 없습니다. 개인과 친구 B로 모든 것을 만드십시오. B B는 자유롭게 조작 할 수있는 A의 구성원을 보유하고 있습니다.

이것을 설명하는 방식은 상속보다는 구성과 비슷하게 들립니다. 예를 들어

class ComplexMachine {
  public:
    setState(int state);
};

class Operator {
   public:
   Operator(ComplexMachine & m) :_m(m) {};

   void drive() { _m->setState(1); }
   void turn() { _m->setState(2); }
   void stop() { _m->setState(0); }

   private:
   ComplexMachine _m;   
};

class SmoothOperator : public Operator { }

당신이 준 정보의 비트로 작업 :

클래스 B는 클래스 A의 불변량을 보존 할 책임이 있어야하며 클래스 B는 A를 조작하는 유일한 방법이어야합니다.

(Design POV에서는 아니요 필요 A가 존재하지만, 나는 당신에게 그것을 붙잡을 수없는 그러한 분리에 대한 충분한 실용적인 이유를 만났다;)).

이를 위해서는 많은 보일러 플레이트 코드가 작성되거나 인터페이스가있는 속임수가 필요할 수 있습니다. 예를 들어 클라이언트가 클래스 A를 사용하여 정보를 쿼리하기 위해 정보를 쿼리하지만 수정하지 않아야하는 경우 B __declSpec (속성) 또는 이와 유사한 컴파일러를 사용하여 Const & Aggregreated A에게 나눠 줄 수 있습니다. 구문 통증이 완화 될 수 있습니다.

B 만 A에서 작동하는지 확인하려면 개인의 인스턴스를 만들고 B에서 후손으로 보호 된 인터페이스를 노출하십시오.

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

class B
{
  private:
    A a;

  protected:
    void CallAFoo() { a.foo() };
};

class C : public B
{
    void goo() { CallAFoo(); }
};

내가 당신의 질문에서 이해하는 것에서 당신은 몇 가지가 필요할 것입니다 다형성. 당신은 필요합니다 요약 클래스 A와 클래스 B는 클래스 A를 상속합니다. 또한 보호 키워드를 사용하면 상속 된 클래스가 특정 정보에 액세스 할 수 있고 동시에 다른 것에 대한 액세스를 거부 할 수 있습니다. 다음은 작은 예입니다.

// dynamic allocation and polymorphism
#include <iostream>
using namespace std;

class CPolygon {
  protected:
    int width, height;
  public:
    void set_values (int a, int b)
      { width=a; height=b; }
    virtual int area (void) =0;
    void printarea (void)
      { cout << this->area() << endl; }
  };

class CRectangle: public CPolygon {
  public:
    int area (void)
      { return (width * height); }
  };

class CTriangle: public CPolygon {
  public:
    int area (void)
      { return (width * height / 2); }
  };

int main () {
  CPolygon * ppoly1 = new CRectangle;
  CPolygon * ppoly2 = new CTriangle;
  ppoly1->set_values (4,5);
  ppoly2->set_values (4,5);
  ppoly1->printarea();
  ppoly2->printarea();
  delete ppoly1;
  delete ppoly2;
  return 0;
}

가져온 코드 cplusplus.com (다형성 및 추상 클래스에 대한 정보도 포함되어 있습니다).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top