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. 学习曲线陡峭

相关推荐
Sarvartha8 小时前
final 关键字
java·开发语言
fpcc8 小时前
c++编程实践—堆和栈越界调试
c++
yi0118 小时前
LeetCode 219:存在重复元素 II——哈希表记录“最近一次出现的位置”
数据结构·人工智能·笔记·python·算法·leetcode·哈希表
程序员Sunday8 小时前
JavaScript 事件循环面试题,宏任务与微任务怎么执行|Sunday面试指南
开发语言·javascript·面试·校招·事件循环·程序员sunday
志尊宝9 小时前
Vue3 零基础每日笔记(073):keep-alive 页面缓存实战——列表页返回不丢状态
vue.js·笔记·缓存·#vue #前端 #前端开发·#javascript·#vue.js
zhangzeyuaaa9 小时前
Ruby 多线程、GVL(GIL)与 Mutex 完全指南
开发语言·前端·ruby
weiabc9 小时前
MSYS2 UCRT64 + g++ C++ 中文输出乱码 完整全过程
c++
谢亮_vipxieliang10 小时前
用 PHP 构建轻量级 REST API:从路由到鉴权的完整实践
开发语言·后端·php
思无邪6610 小时前
用 AI 做 JS 逆向:从抓包到复现的完整方法论
开发语言·javascript·人工智能
灯澜忆梦11 小时前
【面向对象编程C++】| 基础语法
java·c++·算法