C++ 在C+中使用#include宏实现mixin模式好吗+;
正如我们所知,mixin是一种将某些行为“插入”到另一个类的设计模式。例如,在Ruby中,我们可以编写如下代码C++ 在C+中使用#include宏实现mixin模式好吗+;,c++,design-patterns,mixins,C++,Design Patterns,Mixins,正如我们所知,mixin是一种将某些行为“插入”到另一个类的设计模式。例如,在Ruby中,我们可以编写如下代码 module Flyable def fly puts "I'm flying"; end end class Bird include Flyable end C++不支持语言级别的mixin,但我们可以使用多重继承将代码插入派生类。但该解决方案仍然存在自身的问题,如菱形继承、无法覆盖接口中的虚拟方法、无法从“同级”模块访问成员等 后来我发现我可以使用#inc
module Flyable
def fly
puts "I'm flying";
end
end
class Bird
include Flyable
end
C++不支持语言级别的mixin,但我们可以使用多重继承将代码插入派生类。但该解决方案仍然存在自身的问题,如菱形继承、无法覆盖接口中的虚拟方法、无法从“同级”模块访问成员等
后来我发现我可以使用#include宏将代码段插入到类定义中,以实现mixin:
// in Flyable.h
public:
void fly() {
// do something ...
}
float flySpeed;
在另一个文件中
// in Bird.h
class Bird {
#include "Flyable.h"
};
所以所有的成员变量和函数都被插入到Bird类中
这种解决方案似乎没有明显的缺点。代码被很好地组织到不同的文件中。精心设计的模块可以避免可能的名称冲突,而无需重叠的功能/规则
但我仍然担心有些问题我还没有看到。这种混音有什么问题吗
编辑 我知道使用#include inside类定义很奇怪。但它确实解决了问题。如果它真的在项目中使用,程序员可以习惯它。所以我想知道,我们应该避免这样的代码,有什么实际的原因吗?不仅仅是它丑陋、怪异或者没有人这样写
编辑 我忘了解释代码的用途。简单地说,这是为了解决钻石问题而没有虚拟继承。据我所知,钻石问题的根本原因是OOP的滥用。“鸟”是“可飞的动物,可飞的动物”是“动物,鸟”是“食肉动物,食肉动物”是“动物”。这种滥用的实际意图是代码重用,因此与“is-a”关系相比,“-able”更好。而mixin可以带来“有能力”的关系 在C++中,MIXIN可以通过多重继承来实现。这很好,但它将禁用多态性。例如,我们有纯虚拟功能的动物接口,我们希望Bird实现它们。然后我们不能使用多重继承将实现注入Bird类。还有其他一些技巧可以实现这一点,比如构图。但我还没有看到任何解决方案像真正的混合一样简单。这就是我考虑加入的原因 这种解决方案似乎没有明显的缺点 缺点:
- 稍后加入您的项目的开发人员在成为项目中的有效开发人员之前,将有更多需要学习的内容。只有在您不得不在其他项目中维护其他人的非标准黑客行为一段时间后,这一点才明显
- 这是出乎意料的;这将引入bug,导致开发过程中的大量延迟(“嘿,我写了这个,但它没有编译。”/“是的,这些文件中有一个奇怪的include,你需要像这样编写代码”)
- 一个域中的所有内容,在单个API中(无论是指单个类还是单个自由函数集合),通常最多在两个文件中:一个用于声明,一个用于定义
- 在可行的情况下,只保留标题
- 如果不可能,请在.impl或_impl类中编写实现,并将其包含在头中(这不是事实上的标准,但您可以看到它与模板化代码一起使用)
- 在项目的整个生命周期中,您必须一次又一次地做出相同的决定
- 在项目的整个生命周期中(包括当你不再是项目的一部分时,你自己),你必须让你的同事做出同样的决定。这很难,用标准溶液,更不用说非标准溶液了
- 在项目期间,您将需要不断增加维护工作
- 这对任何新员工来说都是违反直觉的,并且会增加其他人加入您的项目的成本
- 任何遵循直觉/经验的开发人员都希望在项目中看到其他东西(代码中增加WTF/sloc)
- 这将在你的团队中造成摩擦,在未来;如果您的团队中有关心代码质量和易用性的开发人员,至少会这样
MAKE_FLYABLE()
宏在WTF/秒方面会好得多。@Someprogrammerdude是的,使用继承来混合不会以菱形模式结束,但仍然有其他问题。我知道使用include似乎很糟糕,但我说不出原因。你能解释一下吗?事实上你和我合作了吗