Frage

Ich versuche, richtig eine Klasse A einkapseln, die nur von der Klasse B betrieben werden sollen.

Allerdings mag ich von der Klasse B erben.

Mit Einem Freund B funktioniert nicht -. Freundschaft nicht vererbt wird

Was ist die allgemein akzeptierte Art und Weise von erreichen, was ich will, oder mache ich einen Fehler?

Um Ihnen ein bisschen mehr Farbe, steht für Klasse A ein komplexes System des Staates. Es sollte nur von B modifiziert werden, welche Aktionen, die der Klasse A des Staates angewendet werden kann geändert werden.

War es hilfreich?

Lösung

Ich nehme an, Sie wollen Nachkommen von B erlauben A direkt zugreifen? Wenn A und B fest verbunden sind, können Sie eine geschützte Klassendefinition innerhalb B machen sich, statt eine unabhängige Definition zu sein. Z.

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

Eine weitere Idee ist geschützte Methoden auf B zu schaffen, die ihre Aktionen A. z delegieren.

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

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

Andere Tipps

Es klingt wie Sie benötigen ein Redesign zu tun; Ihre Klasse A für einen Staat, aber Ihre Klasse B eine Reihe von Aktionen darstellt. Es gibt eine Beziehung gibt, aber es ist nicht eine Vererbungsbeziehung. Ich würde vorschlagen, Zusammensetzung; Sie wollen mehr von einer HASA Beziehung als eine ISA-Beziehung, soweit ich das beurteilen kann.

Wenn ich Sie richtig verstehe, wollen Sie B haben und es ist Derivaten Zugriff auf die interne Implementierung der Klasse A haben, nicht wahr?

Leider C ++ nicht über das Konzept der „interner“ Sicherheitsebenen, die Sprachen wie C # und Java besitzen.

Sie betrachten können die privaten Implementierung Paradigma (Pimpl) - auch als opaque Zeiger bekannt belichten, Funktionalität innerhalb Ihres Systems öffentlicher Zugriffsebene verwenden, dass die Verbraucher von A und B nicht sehen würden.

alles zu halten wie es ist, die einfachste Sache zu tun ist, geschütztes Verfahren B hinzuzufügen, den Zugriff auf das Äquivalent Merkmal A geben würde es brauchen. Dies eröffnet die Verkapselung nur Subklassen von B.

Der einfachste Weg, dies zu tun, ist einfach B enthält eine A zu haben:

class B { geschützt:   A a_; };

Dann können Sie eine Klasse C schreiben, die von B erbt und ist in der Lage A. zu manipulieren Wenn C nicht in der Lage sein sollte, beliebige Dinge auf den A zu tun, dann auf die A Privat in B machen und geschützte Methoden in B bieten dass C kann genehmigt Dinge auf den A zu tun verwenden, etwa so:

class B { Privatgelände:   A a_; geschützt:   nichtig doSomethingToA (); };

Containment ist der Weg zu gehen (Klasse B enthält private Mitglied des Typs A), es sei denn B einige virtuals in A außer Kraft setzen muss, wobei in diesem Fall private Vererbung ist die nächste Sache.

Ich kann nicht sehen, warum Sie erben möchte. Machen Sie alles in einem privaten und Freund B. B hat dann ein Mitglied eines dem sie frei manipulieren kann.

Die Art und Weise dies zu beschreiben, es klingt eher wie Komposition statt Vererbung. Z.

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 { }

Die Arbeit mit den Bits von Informationen, die Sie gegeben haben:

Klasse B sollte für die Erhaltung der Invarianten der Klasse A verantwortlich, und die Klasse B der einzige Weg, A. zu manipulieren jeden Client sein sollte - abgeleitete Klasse oder Anrufer -. Soll nicht wissen müssen, dass A existiert

(Vom Design POV, gibt es auch keine Notwendigkeit für A existieren, aber ich habe genug praktische Gründe für eine solche Trennung begegnet, dass ich nicht gegen Sie halten;))

Dies könnte eine Menge Standardcode erfordert mit der Schnittstelle geschrieben, oder einige Tricks werden. z.B. wenn Kunde sollte die Verwendung der Klasse A erlaubt werden, um Informationen abzufragen, aber nicht zu ändern, könnte B ein const auszuteilen und auf die aggregierte A. Mit einem Compiler unterstützt __declspec (Eigentum) oder ähnlich, die syntaktischen Schmerzen gelindert werden können.

Wenn Sie sicher sein wollen, dass nur B auf A arbeitet, stellen Sie die Instanz von einem privaten und belichten eine geschützte Schnittstelle von B auf seine Nachkommen.

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

class B
{
  private:
    A a;

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

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

Von dem, was ich aus Ihrer Frage verstehen, müssen Sie einige Polymorphismus . Sie benötigen ein abstrakt Klasse A und Klasse B erbt auch Klasse A., die geschützt Schlüsselwort die Klassen ermöglicht, die den Zugriff auf bestimmte Informationen zu haben, während zur gleichen Zeit den Zugriff verweigern erben zu irgendetwas anderes. Hier ist ein kleines Beispiel:

// 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;
}

-Code genommen von cplusplus.com (enthält Informationen über Polymorphismus und abstrakte Klassen auch).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top