日历

September 2020
M T W T F S S
 123456
78910111213
14151617181920
21222324252627
282930  

CRTP是怎么实现mixin的呢?

Home Forums 《冒号课堂》讨论区 CRTP是怎么实现mixin的呢?

Tagged: ,

  • This topic is empty.
Viewing 1 reply thread
  • Author
    Posts
    • #1126
      Thomson
      Member

      我看到第多态的那章这么说,可是CRTP是c++实现static polymorphism 的, 怎么又和mixin联系起来了呢?

    • #1327
      hui
      Keymaster

      CRTP(Curiously recurring template pattern)是 C++ 的一个惯用法,即一个类继承一个以该类为模板参数的实例化模板类。很拗口,用代码表示则清楚得多——

      class derived : public base<derived> (也可用struct)

      利用template的特殊性,CRTP可用来实现static polymorphism,避免虚函数的额外开销,但CRTP同时也可以用来实现mixin。看一个简单的例子:

      #include <iostream>

      using namespace std;

      template <typename T>

      class ObjectCounter

      {

      public:

      ObjectCounter()

      {

      ++objCount;

      }

      virtual ~ObjectCounter()

      {

      –objCount;

      }

      int countObjects()

      {

      return objCount;

      }

      private:

      static int objCount;

      };

      template <typename T> int ObjectCounter<T>::objCount(0);

      class X : public ObjectCounter<X> // ObjectCounter被“混入”类型X

      {

      public:

      void method1();

      int method2();

      //…

      };

      int main()

      {

      {

      X x1;

      cout << x1.countObjects() << endl;

      X x2;

      cout << x2.countObjects() << endl;

      X* x3= new X;

      cout << x3->countObjects() << endl;

      delete x3;

      cout << x1.countObjects() << endl;

      {

      X a;

      cout << a.countObjects() << endl;

      }

      cout << x1.countObjects() << endl;

      return 0;

      }

      上面采用的是class Derived : public Mixin<Derived>

      此外还有一种利用CRTP实现mixin的方式:template <typename Base> class Mixin : public Base

      例如:

      #include <iostream>

      using namespace std;

      template <typename T>

      class CallCounter : public T // CallCounter被“混入”类型T

      {

      public:

      CallCounter() : callCount(0)

      {

      }

      int countCalls()

      {

      return callCount;

      }

      void call()

      {

      ++callCount;

      T::call();

      }

      private:

      int callCount;

      };

      class Y

      {

      public:

      void call()

      {

      cout << “call…” << endl;

      }

      };

      int main()

      {

      CallCounter<Y> y;

      y.call();

      cout << “call#=” << y.countCalls() << endl;

      y.call();

      y.call();

      cout << “call#=” << y.countCalls() << endl;

      return 0;

      }

      更深入的例子可参见 Mixin-Based Programming in C++

Viewing 1 reply thread
  • You must be logged in to reply to this topic.
 请您评分1星(很差)2星(不行)3星(一般)4星(不错)5星(很棒)