日历

November 2020
M T W T F S S
 1
2345678
9101112131415
16171819202122
23242526272829
30  

Reply To: CRTP是怎么实现mixin的呢?

Home Forums 《冒号课堂》讨论区 CRTP是怎么实现mixin的呢? Reply To: CRTP是怎么实现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++

 请您评分1星(很差)2星(不行)3星(一般)4星(不错)5星(很棒)