2016-05-26 16 views
0

Ich versuche, einige fortgeschrittenere Punkte von C++ - Klassen so gut wie möglich (oder zumindest mit GNU) Compiler/eingebaute Funktionen einzubinden. Alles basierend auf einem Logger-Konzept für ein (großes und umfangreiches) Arbeitsprojekt. Was bringt mich zu diesem Pseudo-Code:Automatischer Aufruf von Basisklassenfunktionen

class Base { 
    public: 
      void increment(){ 
       ++m_Val; 
      } 
    private: 
      static int m_Val; 
}; 
class Above : private Base{ 
    public: 
      void doA(){ 
       //Foo 
      } 
      void doB(){ 
       //Bar 
      } 
}; 

Das wurde als ein Konzept gezeigt; gibt es einen Weg, so dass die bloße Vererbung der Basis doA() und doB() implizit die Basisfunktion increment() aufrufen kann, ohne dass ich den Funktionsaufruf zu increment() in jeder einzelnen Funktion jeder einzelnen Klasse, die erbt? Wenn nicht eine direkte Antwort, gibt es eine bestimmte Bezeichnung für das, was ich tun möchte? Oder wird es als Teil von Boost oder anderen Bibliotheken angeboten?

+0

ich glaube nicht, dass es existiert. –

+1

Sie könnten sich für [aspektorientierte Programmierung] interessieren (https://en.wikipedia.org/wiki/Aspekt- orientierte_Programmierung). – AlexD

+0

@ DanielA.White Definitiv, wovor ich Angst hatte. Ich weiß, C++ ist immer noch eine "wachsende" Sprache, aber war nicht sicher, ob es eine Möglichkeit gab, dies noch vorher mit einem 'Hacky-Code' zu tun – M4rc

Antwort

0

nach stolpern auf diese rein zufällig; Die Lösung, die am ehesten dem entspricht, nach dem ich suche, heißt "Execute-Around Pointer" wie definiert Here. Insbesondere der Abschnitt bezogen auf:

Oft ist es notwendig, eine Funktionalität vor und nach jedem Member Funktionsaufruf einer Klasse auszuführen.

Dies ist im folgenden Code-Snippet enthalten, das von einem zuvor genannten Link stammt.

class VisualizableVector { 
    public: 
    class proxy { 
     public: 
     proxy (vector<int> *v) : vect (v) { 
      std::cout << "Before size is: " << vect->size(); 
     } 
     vector<int> * operator ->() { 
      return vect; 
     } 
     ~proxy() { 
      std::cout << "After size is: " << vect->size(); 
     } 
     private: 
     vector <int> * vect; 
    }; 
    VisualizableVector (vector<int> *v) : vect(v) {}  
    proxy operator ->() { 
     return proxy (vect); 
    } 
    private: 
    vector <int> * vect; 
}; 
int main() 
{ 
    VisualizableVector vecc (new vector<int>); 
    //... 
    vecc->push_back (10); // Note use of -> operator instead of . operator 
    vecc->push_back (20); 
} 
0

Eine Möglichkeit, einen ähnlichen Effekt zu erzielen, ist das Bereitstellen einer Methode zum Überschreiben und Freigeben einer anderen öffentlichen Methode, die Vorbedingungen und Nachbedingungen aufruft.

class Base { 
    public: 
      void increment(){ 
       ++m_Val; 
       std::cout << m_Val << '\n'; 
      } 
      void doA(){ 
       increment(); 
       implA(); 
      } 
      void doB(){ 
       increment(); 
       implB(); 
      } 
    protected: 
     virtual void implA() = 0; 
     virtual void implB() = 0; 

    private: 
      int m_Val; 
}; 
class Above : private Base{ 
    public: 
    using Base::doA; 
    using Base::doB; 
    protected: 
     virtual void implA() override { 
      std::cout << "a\n"; 
     } 
     virtual void implB() override { 
      std::cout << "b\n"; 
     } 
}; 

int main() 
{ 
    Above a; 
    a.doA(); 
    a.doB(); 
} 

Demo

+0

Nur Problem, das ich sehe, ist, dass ich alle Funktionen von jeder Klasse replizieren würde (oder minimal kopieren und einfügen), die "Base" erben würde, was ist ein bisschen die gegenteilige (aber immer noch erwartete) Hoffnung, die ich hatte. – M4rc

+0

Leider ist C++ nicht dynamisch genug, um den gewünschten Effekt ohne Copy & Paste zu erzielen. Eine andere Lösung ist die Verwendung eines Makros, um die Menge an dupliziertem Code zu reduzieren. Andernfalls können Sie den Code-Generator verwenden, um doppelten Code zu generieren. –

+0

Das dachte ich leider - Ein Makro für die ganze Schnittstelle. Vielleicht könnte jemand eine Arbeit haben. – M4rc

0

Sie müssen explizit definieren, wenn Sie Ihre Basis-Methode aufgerufen werden soll, aber es kann durch Abstrahieren entfernt, den Anruf zu erhöhen getan werden - versuchen, so etwas wie dieses Muster (pseudo- Code, mit Hilfe von Java-Terminologie, wie ich mit der äquivalenten C++ Syntax nicht sofort vertraut bin, aber Sie sollten den Kern von ihm) erhalten:

abstract class Base { 
    public: 
      void increment(){ 
       ++m_Val; 
      } 
      void doA(){ 
       increment(); 
       doAInternal(); 
      } 
      void doB(){ 
       increment(); 
       doBInternal(); 
      } 
    protected: 
      abstract void doBInternal(); 
      abstract void doAInternal(); 
    private: 
      static int m_Val; 
}; 
class Above : private Base{ 
    public: 
      void doAInternal(){ 
       //Foo 
      } 
      void doBInternal(){ 
       //Bar 
      } 
};