c – 为什么Boost参数选择继承而不是组合?

我想本网站上的大多数人都同意可以通过两种方式外包实施:

>私人继承
>组成

继承最常被滥用.值得注意的是,当另一种形式或继承可能更好时,通常使用公共继承,并且通常应该使用组合而不是私有继承.

当然通常的警告适用,但我想不出任何时候我真正需要继承实现问题.

然而,对于Boost Parameter library,您会注意到它们已经选择了继承而不是用于实现命名参数idiom的构造(对于构造函数).

我只能想到经典的EBO(空基优化)解释,因为我在这里找不到虚拟方法.

有谁知道更好或者可以将我重定向到讨论?

谢谢,
马修.

最佳答案 编辑:Ooopss!我在下面发布了答案因为我误读了你的帖子.我以为你说Boost库使用的是组合而不是继承,而不是相反.不过,如果它对任何人都有用……(请参阅EDIT2,我认为这可能是你问题的答案.)

我不知道Boost参数库的具体答案.但是,我可以说这通常是一个更好的选择.原因是因为无论何时您都可以选择以多种方式实现关系,您应该选择最弱的一种(低耦合/高内聚).由于继承比组成强…

请注意,有时使用私有的inhertiance也会使实现异常安全的代码变得更加困难.以操作符==为例.使用组合,您可以创建临时文件并使用提交/回滚逻辑进行赋值(假设对象的结构正确).但是如果你使用继承,你可能会在派生类的operator ==里面做类似Base :: operator ==(obj)的事情.如果该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(); } /* ... */ };

对于启用参数的构造函数,您需要创建一个实现类,但您仍然应该能够以透明的方式使用“包装器”类.这意味着在example from the link you mentioned中,你可以像操纵myclass_impl一样操纵myclass.这只能通过继承来完成. (请注意,在示例中,继承是公共的,因为它是struct的默认值.)

我假设myclass_impl应该是“真正的”类,具有数据,行为等的类.然后,如果你有一个像get_int()的方法,如果你没有使用继承,你将被迫写myclass中的get_int()包装器就像我上面一样.

点赞