Curiously recurring template pattern
Posted on Thu 09 June 2022 in Journal
CRTP (Curiously Recurring Template Pattern) 即奇异重复模板模式, 它其实很早就出现了,看起来有点奇怪,用起来却很爽, 其最主要的用途就是静态多态
它有两个特点:
- 子类继承自模板类。
- 派生类将自身作为参数传给模板类。
#include <string>
#include <memory>
#include <sstream>
#include <iostream>
template <typename T>
class Entity {
public:
Entity(uint32_t id, const std::string& name): m_id(id), m_name(name) {
}
std::string& getName() const { return m_name; }
uint32_t getId() const { return m_id; }
std::string toString() const {
return static_cast<T*>(this)->toString();
}
static std::shared_ptr<T> createInstance(uint32_t id, const std::string& name)
{
return T::createInstance(id, name);
}
protected:
uint32_t m_id;
std::string m_name;
};
class User : Entity<User>
{
public:
User(uint32_t id, const std::string& name):Entity<User>(id, name) { }
std::string toString() const {
std::ostringstream out;
out << "user: id=" << m_id;
out << ", name=" << m_name;
return out.str();
}
static std::shared_ptr<User> createInstance(uint32_t id, const std::string& name) {
return std::make_shared<User>(id, name);
}
};
class Room : Entity<Room>
{
public:
Room(uint32_t id, const std::string& name):Entity<Room>(id, name) { }
std::string toString() const {
std::ostringstream out;
out << "room: id=" << m_id;
out << ", name=" << m_name;
return out.str();
}
static std::shared_ptr<Room> createInstance(uint32_t id, const std::string& name) {
return std::make_shared<Room>(id, name);
}
};
int main(int argc, char** argv)
{
auto user = User::createInstance(1, "Alice");
std::cout<< user->toString()<<std::endl;
auto room = Room::createInstance(2, "House");
std::cout<< room->toString()<<std::endl;
return 0;
}
output:
user: id=1, name=Alice
room: id=2, name=House
本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。