三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

C++CRTP奇异递归模板

C++CRTP奇异递归模板

C++CRTP奇异递归模板

奇异递归模板模式(CRTP)是派生类将自己作为模板参数传递给基类的技术。CRTP实现静态多态,避免了虚函数的运行时开销。

CRTP的基本形式:基类模板接受派生类作为参数。

#include
#include

template
class Base {
public:
void interface() {
static_cast(this)->implementation();
}

static void static_interface() {
Derived::static_implementation();
}

Derived& derived() {
return static_cast(*this);
}

const Derived& derived() const {
return static_cast(*this);
}
};

class DerivedA : public Base {
public:
void implementation() {
std::cout << "DerivedA implementation\n";
}

static void static_implementation() {
std::cout << "DerivedA static\n";
}
};

class DerivedB : public Base {
public:
void implementation() {
std::cout << "DerivedB implementation\n";
}

static void static_implementation() {
std::cout << "DerivedB static\n";
}
};

void crtp_basic() {
DerivedA a;
DerivedB b;

a.interface();
b.interface();

Base::static_interface();
Base::static_interface();
}

CRTP实现对象计数。

template
class ObjectCounter {
static inline int count_ = 0;
static inline int alive_ = 0;

protected:
ObjectCounter() {
++count_;
++alive_;
}

~ObjectCounter() {
--alive_;
}

public:
static int total_created() { return count_; }
static int currently_alive() { return alive_; }
};

class Widget : public ObjectCounter {
int id_;
public:
Widget(int id) : id_(id) {}
int id() const { return id_; }
};

void object_counter_demo() {
std::cout << "Initial: " << Widget::currently_alive() << "\n";

{
Widget w1(1);
Widget w2(2);
std::cout << "Two created: " << Widget::currently_alive() << "\n";
std::cout << "Total created: " << Widget::total_created() << "\n";
}

std::cout << "After scope: " << Widget::currently_alive() << "\n";
}

CRTP实现比较运算符。

template
class EqualComparable {
public:
friend bool operator==(const Derived& a, const Derived& b) {
return a.equal_to(b);
}

friend bool operator!=(const Derived& a, const Derived& b) {
return !a.equal_to(b);
}
};

template
class Comparable : public EqualComparable {
public:
friend bool operator<(const Derived& a, const Derived& b) {
return a.less_than(b);
}

friend bool operator>(const Derived& a, const Derived& b) {
return b.less_than(a);
}

friend bool operator<=(const Derived& a, const Derived& b) {
return !b.less_than(a);
}

friend bool operator>=(const Derived& a, const Derived& b) {
return !a.less_than(b);
}
};

class Point : public Comparable {
int x_, y_;
public:
Point(int x, int y) : x_(x), y_(y) {}

bool equal_to(const Point& other) const {
return x_ == other.x_ && y_ == other.y_;
}

bool less_than(const Point& other) const {
if (x_ != other.x_) return x_ < other.x_;
return y_ < other.y_;
}

friend std::ostream& operator<<(std::ostream& os, const Point& p) {
os << "(" << p.x_ << "," << p.y_ << ")";
return os;
}
};

void comparable_demo() {
Point p1(1, 2), p2(1, 2), p3(3, 4);

std::cout << p1 << " == " << p2 << ": " << (p1 == p2) << "\n";
std::cout << p1 << " != " << p3 << ": " << (p1 != p3) << "\n";
std::cout << p1 << " < " << p3 << ": " << (p1 < p3) << "\n";
std::cout << p3 << " > " << p1 << ": " << (p3 > p1) << "\n";
std::cout << p3 << " >= " << p1 << ": " << (p3 >= p1) << "\n";
}

CRTP实现单例。

template
class Singleton {
public:
static T& instance() {
static T instance_;
return instance_;
}

Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;

protected:
Singleton() = default;
~Singleton() = default;
};

class Logger : public Singleton {
friend class Singleton;
int log_count_ = 0;
Logger() = default;

public:
void log(const std::string& msg) {
std::cout << "[LOG " << ++log_count_ << "] " << msg << "\n";
}
};

void singleton_crtp() {
auto& logger = Logger::instance();
logger.log("First message");
logger.log("Second message");

auto& logger2 = Logger::instance();
std::cout << "Same instance: " << (&logger == &logger2) << "\n";
}

CRTP实现克隆。

template
class Cloneable {
public:
std::unique_ptr clone() const {
return std::unique_ptr(
static_cast(this->clone_impl())
);
}

private:
virtual Cloneable* clone_impl() const = 0;
};

class ConcreteCloneable : public Cloneable {
int value_;
public:
explicit ConcreteCloneable(int v) : value_(v) {}

ConcreteCloneable* clone_impl() const override {
return new ConcreteCloneable(value_);
}

int value() const { return value_; }
};

void clone_demo() {
ConcreteCloneable original(42);
auto copy = original.clone();
std::cout << "Cloned value: " << copy->value() << "\n";
}

CRTP在C++中广泛应用,结合了模板的编译期效率和面向对象的表达力。

← 返回列表