作者网站:http://shanwq.com/
C++静态多态与Mixin
静态多态
定义与实现原理
静态多态又叫做CRTP,全程是Curiously recurring template pattern,是基于C++模板实现的。其方法是:一个继承类 Derived
,它继承自一个以 Derived
为模板参数的基类 Base
。原理基础是:
- 模板参数的二次查找
#include <functional>
#include <iostream>
template <typename Derived, typename ValueType> class Base {
public:
using and_then_callback = std::function<void(ValueType &)>;
/// 函数是公共接口函数,所有继承类通过该接口实现多态
/// 接口的实现在基类, 与虚函数相反,虚函数多态的实现在继承类
/// 中间有两次接口的约定:
/// 1. 因为在基类中调用继承类的方法,所以所有继承类必须实现相关方法
/// 2. 基类的方法暴露给用户,为提供给用户的接口
Derived &and_then(const and_then_callback &callback) {
/// 将指针cast成继承类的指针
auto derived = static_cast<Derived *>(this);
if (derived->has_data()) {
callback(derived->get_data());
// 可以在基类中调用继承类的成员,这也是这个设计模式的核心,因为按照正常逻辑,
// 此处这个函数基类并不知道(先声明,后使用),但是因为是模板类,
// 所以该类的实例化其实是在derived->other_implementation()之后进行的,
// 所以编译可以通过
derived->other_implementation();
}
return *derived;
}
};
template <typename ValueType>
class Derived_A : public Base<Derived_A<ValueType>, ValueType>
{
public:
template <typename... Argu> void set_data(const Argu &...args) {
data = ValueType(args...);
flag = true;
}
ValueType &get_data() {
return data; }
void other_implementation() {
std::cout << "Derived_A implementation is called\n";
}
bool has_data() {
return flag; }
private:
ValueType data;
bool flag = false;
};
template <typename ValueType>
class Derived_B : public Base<Derived_B<ValueType>, ValueType> {
public:
template <typename.