我看过一些有关此问题的帖子,但没有总结我当前情况下所有选择的内容,并且可能有我未考虑过的解决方案。

我的情况很普遍,我有几个类Inf1 Inf2(更像是接口(interface))都具有纯虚方法。
Inf1有一个方法
(Inf2& or Inf2* or shared_pointer) foo(/** Some info on how to build the object**/) = 0
(这是问题的一部分)。

Inf1的实现中,当实现Inf2时返回foo的各种实现。
Inf2实现相对较小,因此我不介意按值返回它们,因此将它们复制构造为结果,但是我无法声明foo仅返回Inf2,因为那样的话我将返回一个抽象对象。

有什么可取的或创造性的方法可以解决此问题吗? :)

最佳答案

因此,您拥有彼此相关的Inf1Inf2类型,其中至少有一个包含抽象方法。

您想返回Inf2的一些子实现,但是哪个子实现在运行时确定。

这意味着您需要运行时多态。您可以通过3种不同的方法来解决此问题。

首先,您可以将一个指针(可能是智能指针,如unique_ptr)返回到公共(public)接口(interface)。这需要免费存储(堆)分配,但要明确所有权,这是最简单的答案。

其次,您可以编写一个类型擦除对象,该对象公开virtual接口(interface)的非Inf2版本,并转发一些内部细节。这些内部细节最终将使用某种智能指针或第三个解决方案。这样做的好处是,您可以隐藏内存的管理方式,并且只需廉价地公开值语义即可。缺点是样板很多。

第三,您可以在一组类型上使用boost::variant之类的union,以防止访问错误的类型。虽然boost可能无法直接使用,但是可以模仿设计。这个想法是,您拥有一些本地存储,您可以在其中放置新数据,但对于较大的对象除外,在较大的对象中您可以使用智能指针来代替。与第二种解决方案不同,您支持的类型集在您的类型中明确列出。这是最困难的解决方案(如果您至少没有boost的访问权限),并且要求您具有Inf2的固定(在编译时)实现集,所有Inf1的用户都必须具有完整的详细信息。

如前所述,第一种解决方案是最简单的。第一个解决方案的成本仅基于性能,如果发现了真正的问题,这些性能影响将不难解决。因此,我建议解决方案1,然后进行概要分析,以了解所涉及的成本是否过高。如果成本很高,请转到解决方案3,可能在解决方案2的包装中。

08-16 00:59