Frage

Wie zu einer privaten Basisklasse in C ++ implementieren Gießen? Ich will nicht, Hacks verwenden, wie ein Freund usw. Hinzufügen definieren öffentlichen Casting-Operator funktioniert nicht.

EDIT:

Zum Beispiel habe ich:

class A {
//base class
}

class AX : private A {
//a child
}

class AY : private A {
//another specialized child
}

class B {
//base class
void do (A a) {//do
    }
}

class BX : private B {
//a child
void do (AX a) {
     B::do( static_cast <A> (a) );
    }
}

class BY : private B {
//another specialized child
void do (AY a) {
    B::do( static_cast <A> (a) );
    }
}

EDIT2

Warum ich das tun?

Angenommen, ich habe eine Eigenschaft zu definieren, die ganz Schwergewicht ist und von mehreren ähnlichen Typen sein kann (wie VelocityX VelocityY usw.). Dann möchte ich in der Lage sein, Klassen zu haben, die eine beliebige Menge von diesen Eigenschaften haben kann. Wenn ich diese Eigenschaften bearbeiten will, ist es offensichtlich, dass ich sie lieber Typen zu ihrer Basis geworfen würde als eine Implementierung für jede Variation hinzuzufügen. Ich benutze keine öffentliche Vererbung, weil es besser ist, explizit werfen, wo nötig, als die private Schnittstelle implizit sichtbar zu haben. Kein wirkliches Problem, aber ich möchte eine Lösung haben:)

War es hilfreich?

Lösung

Einen öffentlichen Casting-Operators Wenn die Definition nicht funktioniert, können Sie mit einer regulären Funktion versuchen:

class D: private B {
    public:
        B& asB() { return static_cast<B&>(*this); }
};
...
D d;
d.asB().methodInB();
...

Wie auch immer, was ist der Punkt? Wenn D herleitet privat von B, dann soll man keine D als B von außen verwenden.

Andere Tipps

Sie können nur einen C-Casts verwenden. Keine Notwendigkeit für jegliche „Hacks“ oder „Implementierungen“. es in eine explizite Funktion dient die „C-Casts sind schlecht“ Menschen

Verpackung
template<typename Targ, typename Src>
typename boost::enable_if<boost::is_base_of<Targ, Src>, Targ>::type &
private_cast(Src &src) { return (Targ&)src; }

Um den Guss sicher zu haben, müssen Sie die Targ, um sicherzustellen, ist eigentlich eine private oder öffentliche Basis. Dies wird durch boost::is_base_of getan.


Natürlich sollten Sie Member-Funktionen in der jeweiligen abgeleiteten Klasse bevorzugen, die den Basiszeiger zurückzukehren, anstatt eine solche Besetzung zu tun. .


öffentlichen Casting-Operator definiert funktioniert nicht.

Das macht keinen Sinn für mich ... Warum die Basisklasse überhaupt dann privat machen? Machen Sie es öffentlich. Der Grund, Ihre Conversion-Funktionen nicht funktionieren, weil der Standard verlangt, dass implizite Konvertierungen nie Konvertierungsfunktionen auf eine Basisklasse, die Klasse selbst oder void betrachten.

habe ich einen Anwendungsfall für diese; Ich bin von einer großen und volatilen Basisklasse erben, die Funktionen die ganze Zeit ist das Hinzufügen und fast nie die Funktion Basisklasse Arbeit richtig in meine Unterklasse gehen, so dass ich privat erben.

Ich denke, es ist einfachste nur eine Funktion, kehrt die Basisklasse zu machen. Im Folgenden werde ich führen eine vollständig korrigierte Programm; bitte Ihren Code versuchen kompiliert, bevor Sie eine Frage einreichen, da Bezeichner wie „do“ als Funktionsname ist wahrscheinlich jeden Compiler unglücklich machen .. :-(: - (

class A {
  //base class                                                                                                                                                          
};

class AX : private A {
  //a child                                                                                                                                                             
 public:
  A *ToA() { return this; }
};

class AY : private A {
  //another specialized child                                                                                                                                           
 public:
  A *ToA() { return this; }
};

class B {
  //base class                                                                                                                                                          
 protected:
  void do_it (A a) {};
};

class BX : private B {
  //a child                                                                                                                                                             
  void do_it (AX a) {
    B::do_it( *a.ToA() );
  }
};

class BY : private B {
  //another specialized child                                                                                                                                           
  void do_it (AX a) {
    B::do_it( *a.ToA() );
  }
};

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