【问题标题】:What is C++ Mixin-Style?什么是 C++ Mixin 风格?
【发布时间】:2011-10-28 10:54:19
【问题描述】:

我刚刚遇到了这个关键字C++ Mixin-Style,有人知道这是什么吗?

this post 中,被回答为设计模式。是否与this document 中描述的设计模式相同?

【问题讨论】:

  • 是的,我知道这是什么 :) 你提到了简短而好的描述。另一个很好的描述可以在 Andrei Alexandrescu 的“Modern C++ desing”中找到。你能详细说明你的问题吗?

标签: c++ mixins


【解决方案1】:

Mixins 是来自 Lisp 的一个概念。来自Dr. Dobbs的一个很好的解释:

从某种意义上说,mixin 是一个类的一个片段,它旨在与其他类或 mixin 组合在一起。
[...]
常规的独立类(例如 Person)和 mixin 之间的区别在于,mixin 对一些小的功能切片(例如,打印或显示)进行建模,并且不适合独立使用。相反,它应该与需要此功能的其他类(例如 Person)组合在一起。

因此,mixin 的意义在于允许类似的多重继承,而没有通常伴随多重继承的所有 Bad Things™。

然而,这可能有点令人困惑,因为 C++ 本身并不支持 mixin。为了在 C++ 中“做”混合,你必须使用多重继承!这在实践中的最终含义是您仍然使用多重继承,但是您人为地限制了您允许自己使用它的目的。

有关实际的 mixin 实现,请参阅上面的文章。

【讨论】:

    【解决方案2】:

    如果我没记错的话,至少有两种方法可以在 C++ 中创建 mixin。这来自我看过的一些非常古老的(1995 年)教程(但它现在几乎完全从互联网上消失了)。

    首先,

    class MixinBase {
    public :
        void f() {};
    };
    
    template<class T>
    class Mixin : public T {
    public:
        void f() {
            T::f();
            T::f();
        }
    };
    
    template<class T>
    class Mixin2 : public T {
    public :
        void g() {
            T::f();
            T::f();
        }
    };
    
    int main() {
        Mixin2<Mixin<MixinBase>> mix;
        mix.g();
    }
    

    或者另一种方式使用虚拟继承和兄弟调用:

    class Base {
    public :
        virtual void f() = 0;
    };
    
    class D1 : public virtual Base {
    public :
        void g() {
            f();
        }
    };
    
    class D2 : public virtual Base {
    public :
        void f() {
        }
    };
    
    class D : public D1, public D2 {
    };
    
    int main() {
        D d;
        d.g();
    }
    

    现在这两个版本都实现了 mixin,因为 Mixin 和 Mixin2 是独立的类,但是它们仍然可以通信。您可以从此类模块创建软件,然后将这些模块绑定到一个大软件。虚拟继承中的 D1 和 D2 之间也是如此。需要注意的重要一点是,在 mixin 设计中,不同的模块存在于同一个 c++ 对象中。 (哦,CRTP 是不同的技术)

    【讨论】:

    • 不是第一个你拥有相同(或相似特征)的 mixin 案例吗?
    【解决方案3】:

    Mixin 是一个类(或其他代码组),旨在通过直接包含在另一段代码中来重用。将其视为没有子类型多态性的继承。 CRTP 是一种在 C++ 中近似 Mixin 的方法。

    【讨论】:

      【解决方案4】:

      通常,mixin 被称为小类(通常是模板化的或基于 crtp 的),您可以从中“混入”某些功能;通常通过多重继承和基于策略的设计(另见 Alexandrescu 的“Modern C++ Design”)。

      【讨论】:

      • 我不同意。 “混合”的重点是避免多重继承(通过 Scala、Ruby 和 Squeak 中的语言设计/限制或通过 C++ 中的 CRTP)——解决 90% 的共享实现问题仅 10% 的并发症(MI)。我编了这些数字,顺便说一句:-)
      • @pst,你知道 84% 的统计数据是现场制作的吗?每次我看到一个 mixin,不管是不是 CRTP,它都在使用多重继承。我想这就是mix的意思,就是要和其他基类混在一起。
      • 根据 Jim Coplien 在他的 Advanced C++ 中的说法,混合是 Flavors 语言中存在的一种动态多重继承形式,您可以在运行时组合多个基类创建一个特定的派生类。
      • @pst:mixin 的独特之处在于它旨在用于继承,而不是单独实例化。由于继承链接而避免 MI 是设计 mixin 的一种方法,但它们的关键仍然是重用代码,而不是防止 MI。
      【解决方案5】:

      C++ 中的 Mixin 使用 Curiously Recurring Template Pattern (CRTP) 表示。 This post 是他们提供的优于其他重用技术的一个很好的细分......编译时多态性。

      【讨论】:

      • Mixins 是 CRTP 的设计反转。两者是截然不同的,mixin 根本不是使用 CRTP 实现的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-11
      • 1970-01-01
      • 1970-01-01
      • 2010-10-04
      相关资源
      最近更新 更多