我认为本网站上的大多数人都同意可以通过两种方式外包实施:
继承最常被滥用。值得注意的是,当另一种形式或继承可能更好时,通常会使用公共继承,并且通常应该使用组合而不是私有继承。
当然通常需要注意,但我无法想到任何时候我真的需要继承来解决实现问题。
然而,对于Boost Parameter library,您会注意到他们为构造函数的实现选择了继承而不是组合(对于构造函数)。
我只能想到经典的EBO(空基优化)解释,因为我在这里找不到虚拟方法。
有谁知道更好或者可以将我重定向到讨论中?
谢谢, 马修。
答案 0 :(得分:2)
编辑: Ooopss!我在下面发布了答案因为我误读了你的帖子。我以为你说Boost库使用的是组合而不是继承,而不是相反。不过,如果它对任何人都有用......(请参阅EDIT2,我认为这可能是你问题的答案。)
我不知道Boost参数库的具体答案。但是,我可以说这通常是一个更好的选择。原因是因为无论何时您都可以选择以多种方式实现关系,您应该选择最弱的一种(低耦合/高内聚)。由于遗传比作文更强......
请注意,有时使用私有不一致可能会使实现异常安全的代码变得更加困难。以operator==
为例。使用组合,您可以创建临时文件并使用提交/回滚逻辑进行赋值(假设对象的结构正确)。但是如果你使用继承,你可能会在派生类的Base::operator==(obj)
内执行operator==
之类的操作。如果那个Base::operator==(obj)
电话会被抛出,那么您将面临担保。
编辑2: 现在,试着回答你真正的问题。这是我从您提供的链接中可以理解的。由于我不知道图书馆的所有细节,如果我错了,请纠正我。
当您使用“按”实现“组合”时,您需要一个级别的委托间接。
struct AImpl
{
//Dummy code, just for the example.
int get_int() const { return 10; }
};
struct A
{
AImpl * impl_;
int get_int() const { return impl->get_int(); }
/* ... */
};
对于启用参数的构造函数,您需要创建一个实现类,但您仍然应该能够以透明的方式使用“wrapper”类。这意味着在example from the link you mentioned中,您希望操纵myclass
就像操纵myclass_impl
一样。这只能通过继承来完成。 (请注意,在示例中,继承是公共的,因为它是struct的默认值。)
我认为myclass_impl
应该是“真正的”类,具有数据,行为等的类。然后,如果你有一个类似get_int()
的方法,如果你没有'使用继承,您将被迫在get_int()
中编写myclass
包装器,就像我上面那样。
答案 1 :(得分:0)
这不是我曾经使用的库,所以只需浏览一下你链接到的文档就是我唯一的答案。我完全有可能出错,但是......
他们提到构造函数委派是使用公共基类的原因。你是对的,组合也可以解决这个特定的问题。然而,将它全部放在一个类型中是行不通的。他们希望将多个构造函数签名分解为单个用户编写的初始化函数,而不需要构造函数委托,这需要第二个数据类型。我怀疑这个图书馆的大部分内容都是从将所有内容都放入课堂本身的角度编写的。当他们遇到构造函数委托问题时,他们就妥协了。将它放入基类可能更接近于他们使用之前的功能,他们知道您正在使用的类可以访问该功能的接口和实现方面。
我不会以任何方式抨击图书馆。我非常怀疑我可以在任何合理的时间内组建像这样的图书馆。我只是在线间阅读。你知道,从无知中说出,但假装我真的知道一些事情。 : - )