我试图正确地封装一类A,它应该仅由B类操作上。

然而,我想从B类继承。

有一个朋友B不工作 - 友好不被继承

什么是完成我想要的东西,还是我犯了一个错误?普遍接受的方式。

要给你更多的色彩,类A代表一个复杂的系统的状态。它应该只由B,其是可应用到改变类A的状态的动作进行修改。

有帮助吗?

解决方案

我假设你想允许B的后裔一个直接访问?如果A和B是紧耦合的,你可以让乙本身内的一个受保护的类定义,而不是作为一个独立的定义。 E.G。

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

另一个想法是创建基于B的受保护方法即委托其行动A. E.G。

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

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

其他提示

这听起来像你可能需要做一个重新设计;你的A级所代表的国家,但你的B类代表一组动作。有一个关系的存在,但它不是一个继承关系。我建议组成;您想了解更多的比ISA关系的公会关系,据我可以告诉。

如果我理解正确的话,你想拥有B'STRONG>和它的衍生品即可访问内部实现A级的,是吧?

不幸的是,C ++没有“内部”的保护的水平,如C#和Java语言posses

概念

您可以考虑使用私有实现范式(平普尔) - 也被称为不透明指针,使用公共访问级别的系统内公开功能,A和B的消费者不会看到。

藏在心里的是,最容易做的事情是添加受保护的方法到B,让访问的等效特点那就需要。这将打开封装只是B的子类。

在最简单的方法来做到这是简单地有乙包含的A:

类B { 保护:   一个A_; };

然后,你可以写一个C类其中的B继承并能够操纵A.若C不应该是能够做到的事情任意到A,然后进行一个私人的B,提供B中受保护的方法该C可使用做批准事情到A,像这样:

类B { 私人的:   一个A_; 保护:   无效doSomethingToA(); };

遏制是去(类B包含类型A的私有成员),除非B需要重写所述的一些虚拟包,所述方法在这种情况下的私有继承的是最接近。

我看不出你为什么会想继承。使在私人和朋友B.乙一切然后具有其中一个构件可以自由地操纵。

在描述这个问题的方法它听起来更像组合物而不是继承。 E.g。

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.任何客户端的唯一途径 - 派生类或呼叫者 - 不应该需要知道A存在

(从设计POV,还有的甚至没有的需要的对于A存在,但我也遇到过够了这种分离的实际原因,我不会记仇的;))

这可能需要大量的样板代码被写入,或一些诡计与接口。例如如果客户端应被允许使用类A至查询的信息,但不修改它,B可以把手伸到一个const&于凝集A.使用一个编译器支撑__declspec(属性)或类似,句法疼痛可以得到缓解。

如果你想确保仅有B上的一个操作,使私人的实例和暴露的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