我看过一些有关此问题的帖子,但没有总结我当前情况下所有选择的内容,并且可能有我未考虑过的解决方案。
我的情况很普遍,我有几个类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
,因为那样的话我将返回一个抽象对象。
有什么可取的或创造性的方法可以解决此问题吗? :)
最佳答案
因此,您拥有彼此相关的Inf1
和Inf2
类型,其中至少有一个包含抽象方法。
您想返回Inf2
的一些子实现,但是哪个子实现在运行时确定。
这意味着您需要运行时多态。您可以通过3种不同的方法来解决此问题。
首先,您可以将一个指针(可能是智能指针,如unique_ptr
)返回到公共(public)接口(interface)。这需要免费存储(堆)分配,但要明确所有权,这是最简单的答案。
其次,您可以编写一个类型擦除对象,该对象公开virtual
接口(interface)的非Inf2
版本,并转发一些内部细节。这些内部细节最终将使用某种智能指针或第三个解决方案。这样做的好处是,您可以隐藏内存的管理方式,并且只需廉价地公开值语义即可。缺点是样板很多。
第三,您可以在一组类型上使用boost::variant
之类的union
,以防止访问错误的类型。虽然boost
可能无法直接使用,但是可以模仿设计。这个想法是,您拥有一些本地存储,您可以在其中放置新数据,但对于较大的对象除外,在较大的对象中您可以使用智能指针来代替。与第二种解决方案不同,您支持的类型集在您的类型中明确列出。这是最困难的解决方案(如果您至少没有boost
的访问权限),并且要求您具有Inf2
的固定(在编译时)实现集,所有Inf1
的用户都必须具有完整的详细信息。
如前所述,第一种解决方案是最简单的。第一个解决方案的成本仅基于性能,如果发现了真正的问题,这些性能影响将不难解决。因此,我建议解决方案1,然后进行概要分析,以了解所涉及的成本是否过高。如果成本很高,请转到解决方案3,可能在解决方案2的包装中。