【问题标题】:Automatic calling of base class functions自动调用基类函数
【发布时间】:2016-09-23 19:24:44
【问题描述】:

我试图尽可能地(或至少使用 GNU)编译器/内置函数来围绕 C++ 类的一些更高级的点。所有这些都基于(大型和广泛的)工作项目的记录器概念。这让我想到了这个伪代码:

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 或其他库的一部分提供?

【问题讨论】:

  • 我认为不存在。
  • 你可能对aspect-oriented programming感兴趣。
  • @DanielA.White 绝对是我害怕的。我知道 C++ 仍然是一种“成长中”的语言,但不确定是否有办法通过一些“hacky 代码”来做到这一点或之前
  • 我们需要描述您想要完成的工作以获得合理的答案。
  • @sleeptightpupper 正如我在底部所说,虽然我会添加更多内容:我希望多个(数十个)类继承Base,因此他们的所有他们自动调用(在这种情况下)Increment() 的函数。除了必须复制和粘贴Increment() 9000 次并将代码弄乱之外。逐渐地,它将成为堆栈跟踪或记录器的一部分。

标签: c++ class polymorphism multiple-inheritance


【解决方案1】:

在纯属意外偶然发现之后;与我正在寻找的最相似的解决方案称为“Execute-Around 指针”,定义为Here。特别是与以下内容相关的部分:

通常需要在类的每个成员函数调用之前和之后执行一个功能。

这在以下代码 sn-p 中表示,取自上述链接。

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

【讨论】:

    【解决方案2】:

    您必须明确定义何时调用您的基本方法,但可以通过抽象出对增量的调用来完成 - 尝试类似这种模式(伪代码,使用 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
               }
    };
    

    【讨论】:

      【解决方案3】:

      实现类似效果的一种方法是提供一种方法来覆盖和公开调用前置条件和后置条件的不同公共方法。

      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

      【讨论】:

      • 我看到的唯一问题是,这需要我复制(或最少复制和粘贴)任何继承 Base 的类中的所有函数,这有点相反(但仍是预期的) ) 希望我有。
      • 不幸的是,C++ 不够动态,无法在不复制和粘贴的情况下达到您想要的效果。另一种解决方案是使用宏来减少重复代码的数量。否则,您可以使用代码生成器生成重复代码。
      • 这就是我的想法,很遗憾——整个界面的宏。也许有人可以解决。
      猜你喜欢
      • 2012-10-21
      • 1970-01-01
      • 2015-03-15
      • 2012-03-30
      • 2011-05-22
      • 2013-08-05
      • 1970-01-01
      • 2014-01-01
      • 2011-03-07
      相关资源
      最近更新 更多