C++(mixins 混入模式)

🎯 什么是 Mixins?

Mixins 是一种组合优于继承 的设计模式,通过多重继承将功能片段(而非完整的类)组合到目标类中。

🧩 Mixin vs 普通继承:

普通继承 Mixin 继承
class Dog : public Animal class MyWidget : public Draggable, public Resizable
表达"是一个"关系 表达"具有...特性"关系
单一职责(一个父类) 多重特性(多个 mixin)

🔥 C++ Mixins 核心原则

  1. 只提供功能,不封装状态(可选)
  2. CRTP (Curiously Recurring Template Pattern) 优化性能
  3. 非虚函数为主(避免虚函数开销)
  4. 组合而非继承

🧪 示例 1:基础 Mixin(无状态)

复制代码
   // mixable.hpp
   template<typename T>
   struct Draggable {
       void drag(int dx, int dy) {
           auto* self = static_cast<T*>(this);
           self->x += dx;  // 假设 T 有 x, y 成员
           self->y += dy;
           std::cout << "Dragged to (" << self->x << ", " << self->y << ")\n";
       }
   };

   template<typename T>
   struct Loggable {
       void log(const std::string& msg) {
           auto* self = static_cast<T*>(this);
           std::cout << "[" << typeid(*self).name() << "] " << msg << std::endl;
       }
   };

   // 使用 mixins
   class Widget {
   public:
       int x = 0, y = 0;
       std::string name = "Widget";
   };

   class EnhancedWidget : public Widget,
                          public Draggable<EnhancedWidget>,
                          public Loggable<EnhancedWidget> {
   public:
       void click() {
           log("Clicked!");
           drag(10, 10);
       }
   };

   // 使用
   EnhancedWidget w;
   w.click();  // [class EnhancedWidget] Clicked!
               // Dragged to (10, 10)

🧪 示例 2:带状态的 Mixin(实用)

复制代码
   // mixins_with_state.hpp
   template<typename T>
   struct TimestampMixin {
   protected:
       time_t created_at = time(nullptr);
       
   public:
       time_t get_creation_time() const { return created_at; }
       std::string get_formatted_time() const {
           char buffer[100];
           strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S",
                   localtime(&created_at));
           return buffer;
       }
   };

   template<typename T>
   struct IdMixin {
   private:
       static inline int next_id = 0;
       int id;

   protected:
       IdMixin() : id(++next_id) {}
       
   public:
       int get_id() const { return id; }
   };

   // 组合使用
   class DataProcessor : public TimestampMixin<DataProcessor>,
                         public IdMixin<DataProcessor> {
   public:
       void process() {
           std::cout << "Processing ID: " << get_id() 
                     << " at " << get_formatted_time() << std::endl;
       }
   };

   DataProcessor p1, p2;
   p1.process(); // Processing ID: 1 at 2026-04-25 15:42:xx
   p2.process(); // Processing ID: 2 at 2026-04-25 15:42:xx

🧪 示例 3:CRTP + Mixins(高性能)

复制代码
   // crtp_mixins.hpp
   template<typename Derived>
   struct ArithmeticMixin {
       // 返回派生类型,支持链式调用
       Derived operator+(const Derived& other) const {
           auto result = static_cast<const Derived&>(*this);
           result.value += other.value;  // 假设派生类有 value 成员
           return result;
       }
       
       Derived& operator+=(const Derived& other) {
           static_cast<Derived&>(*this).value += other.value;
           return static_cast<Derived&>(*this);
       }
   };

   template<typename Derived>
   struct PrintableMixin {
       void print() const {
           const auto& self = static_cast<const Derived&>(*this);
           std::cout << "Value: " << self.value << std::endl;
       }
   };

   // 使用 CRTP Mixins
   class Number : public ArithmeticMixin<Number>,
                  public PrintableMixin<Number> {
   public:
       int value;
       Number(int v = 0) : value(v) {}
   };

   Number a(5), b(3);
   auto c = a + b;  // 使用 ArithmeticMixin
   c.print();       // 使用 PrintableMixin

📌 Mixins 的优势

代码复用 :功能模块化,可重复使用

灵活组合 :按需选择特性

编译期多态 :无虚函数性能损失(CRTP)

类型安全:模板保证编译期检查

缺点
6. 继承层次复杂(调试困难)
7. 模板代码膨胀
8. 学习曲线陡峭

相关推荐
伞伞悦读17 分钟前
【第36期】Python 目录与路径详解:pathlib、文件遍历、创建、复制、移动和删除风险
开发语言·python
智者知已应修善业2 小时前
【4060BD_5V应用电路图】2022-12-24
驱动开发·经验分享·笔记·硬件架构·硬件工程
qq_199886873 小时前
第6板块·第4节:构建系统与多文件项目
c++·人工智能·gpu算力
2601_966949653 小时前
只拿到股票代码还不够:量化程序到底还需要哪些标的信息?——从数据建模开始理解股票元数据
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
m0_734571763 小时前
深入理解5g <十八>传输块tbsize的计算
开发语言·5g
汉克老师4 小时前
GESP2026年9月认证C++三级( 第三部分编程题(2、分割字符串))精讲
c++·gesp·小学生·学c++编程
估值探索者5 小时前
【Python量化系统工程化 #08】关了 SSH 就停?systemd 让脚本开机自启 + 异常自动拉起
java·c++·人工智能·分类·数据挖掘
小李不想当小白5 小时前
DMA直接存储器存取(STM32标准库学习笔记)
笔记·stm32·单片机·嵌入式硬件·学习·分享
RAN11426760085 小时前
1.3第一个程序的介绍
开发语言·qt
天若有情6735 小时前
C++花式魔改!手写头文件复刻Java语法,彻底打破编码思维定式
java·c++·语言做语言·jac++