2016-05-26 3 views
0

Я пытаюсь обернуть голову еще несколькими расширенными точками классов C++, а также, возможно, (или, по крайней мере, с GNU) компиляторами/встроенными функциями. Все это основано на концепции журнала для крупного и обширного рабочего проекта. Который подводит меня к этому псев-коду:Автоматический вызов функций базового класса

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

Это было показано как концепция; есть ли способ, чтобы простое наследование базы позволяло doA() и doB() неявно вызвать базовую функцию increment() без меня, фактически добавляя вызов функции к increment() в каждую отдельную функцию каждого отдельного класса, который наследует ее? Если не прямой ответ, существует ли конкретный термин для того, что я хочу сделать? Или это предлагается как часть Boost или других библиотек?

+0

i не думаю, что есть. –

+1

Возможно, вас заинтересует [аспектно-ориентированное программирование] (https://en.wikipedia.org/wiki/Aspect-oriented_programming). – AlexD

+0

@ DanielA.White Определенно, чего я боялся. Я знаю, что C++ по-прежнему является «растущим» языком, но не был уверен, что есть способ сделать это до или после какого-то «взломанного кода». – M4rc

ответ

0

После спотыкаясь на это совершенно случайно; решение, которое наиболее близко напоминает то, что я ищу, называется «Execute-Around pointer», как определено Here. В частности, раздел, относящийся к:

Часто необходимо выполнить функциональность до и после каждого вызова функции-члена класса.

которая представлена ​​на следующем фрагменте кода взята из указанной ссылки.

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

Одним из способов достижения аналогичного эффекта является способ переопределения и раскрытия другого общедоступного метода, который вызывает предварительные условия и постусловия.

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

Единственная проблема, которую я вижу, - это то, что мне потребуется реплицировать (или минимально копировать и вставлять) все функции из любого класса, которые наследуют 'Base', что вроде бы наоборот (но все же ожидаемый) надежду у меня было. – M4rc

+0

К сожалению, C++ недостаточно динамичен для достижения желаемого эффекта без копирования и вставки. Другим решением является использование макроса для уменьшения количества дублированного кода. В противном случае вы можете использовать генератор кода для создания дублированного кода. –

+0

Вот что я думал, грустно - макрос для всего интерфейса. Может быть, у кого-то может быть работа. – M4rc

0

Вы должны явно определить, когда вы хотите, чтобы ваш базовый метод, чтобы назвать, но это может быть сделано, абстрагируясь от вызова, чтобы увеличить - попробовать что-то вроде этого шаблона (псевдо- код, используя терминологию Java, как я не так сразу знаком с синтаксисом эквивалентным C++, но вы должны получить его суть):

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