Rig*_*iga 5 c++ inheritance design-patterns multiple-inheritance
在我的代码中,我发现使用类似mixin的继承来组合具有不同块的对象是有用的.我有:
class Name
{
public:
typedef int32_t value_type;
public:
// ctors and dtors
void set_value(value_type value) { value_ = value; }
const value_type& value() const { return value_; }
private:
value_type value_;
};
class NamedObject
{
public:
void set_name(const Name& name) { name_ = name; }
const Name& name() const { return name_; }
protected:
// ctors and dtors
private:
Name name_;
};
Run Code Online (Sandbox Code Playgroud)
我使用这种基类为对象提供具有预定义非虚拟功能的属性:
class MyObject: public NamedObject, public HasZlevel {
// functionality that is not connected with NamedObject and HasZLevel
};
Run Code Online (Sandbox Code Playgroud)
所以我决定将MyObject视为"is-a"NamedObject而不是"has-a"Name. Z-level和Name是在MyObject实例的生命周期内永远不会更改的属性.我更喜欢这种聚合,因为在为NamedObjects定义的算法中简化了使用,或者对于具有HasZLevel接口的对象,我可以通过NamedObject*或HasZLevel*传递它们,并确保它们不会因为受保护而被删除或追加dtors和ctors.
另一种选择是聚合:
class MyObject
{
public:
MyObject(const Name& name): name_(name) {}
void set_name(const Name& name) { named_->set_name(name) }
// and so on...
private:
Name name_;
};
Run Code Online (Sandbox Code Playgroud)
要使用这个,我需要模板算法,要求参数类型具有set_name成员函数.
在我的情况下,放弃我的mixin式设计和使用聚合有什么好的理由吗?也许在长期维护和修改?
因为多重继承很糟糕。
\n\n\n\n\n这就是我喜欢管道胶带程序员的原因。有时,您\xe2\x80\x99 在一个\n 团队中,\xe2\x80\x99 正忙着编写\n 代码,\n 有人来到您的办公桌前,\n 手里拿着咖啡杯,然后开始\n喋喋不休地谈论如果您使用多线程 COM 公寓,您的应用程序将会更加闪亮 34%,而且它\xe2\x80\x99s\n 甚至没有那么难,因为他\xe2\x80\x99s\n写了一堆模板,而你所要做的就是从他的 17 个模板中乘法继承,每个模板平均有 4 个参数,而你甚至不需要写主体功能。它\xe2\x80\x99 只是来自\n 不同类的多重继承的巨大\n 列表,嘿,很快,\n 多单元线程COM。你的眼睛在游动,你根本不知道这个家伙在说什么,但他就是不肯走开,即使他确实消失了,\n他\xe2\x80\x99s只是回到他的办公室\n编写更多他的聪明类\n完全由模板的多个\n继承构建,根本没有\n单个实现主体, \n 它\xe2\x80\x99s 会疯狂地崩溃,\n 你\xe2\x80\x99 会在晚上被传呼\n 进来并尝试弄清楚\n 因为他\xe2\x80 \x99 将参加一些该死的\n \xe2\x80\x9cDesign Patterns\xe2\x80\x9d 聚会。
\n\n管道胶带程序员并不害怕说,\xe2\x80\x9c多重继承很糟糕。停下来。停下来吧。\xe2\x80\x9d
\n
简而言之:这真的会帮助您更快地交付代码吗?或者,当某些重写的成员函数阻塞继承树上的其他成员时,您将在调试器中调试多重继承的类并单步执行超类的棘手问题,因此会花费比其价值更多的时间吗?
\n\n是的,我确实写了“让会员窒息”。多重继承确实有那么糟糕。
\n