【问题标题】:Returning C++ polymorphic objects (interfaces)返回 C++ 多态对象(接口)
【发布时间】:2011-01-20 16:46:27
【问题描述】:

我想知道当从函数返回指向多态对象的指针时,例如在使用工厂时,现在认为什么是最佳实践。如果我转让所有权,我应该返回boost::unique_ptr<Interface>吗?如果我不转让所有权(例如返回对成员的引用),我应该返回什么?是否有另一种常用的非基于提升的方法?谢谢。

编辑:它应该与 C++03 兼容,可以轻松升级到 0x

EDIT2:请注意,我明确询问常用 方法、最佳实践,而不仅仅是“一种方法”。暗示未来对代码库进行条件搜索和替换的解决方案看起来不是一个好习惯,不是吗?

EDIT3:关于 auto_ptr 的另一点是它被弃用,无论它多么整洁,所以在接口级别宣传它的使用看起来很奇怪。然后,不知情的人会将返回的指针放入 STL 容器中,以此类推。因此,如果您知道另一种常见的解决方案,非常欢迎您添加答案。

【问题讨论】:

  • 您可以尽情抱怨::std::auto_ptr 已被弃用,事实是如果没有开销或缩小界面,您将无法做得更好。如果您使用::std::tr1::shared_ptr,您会在不需要时获得引用计数。真的 ::std::auto_ptr 是 C++ 中唯一合理的解决方案。 ::boost::unique_ptr 只是从::std::auto_ptr 中删除有问题的操作。虽然有些人可能认为这更好,但它是一个第三方库,除非别无选择,否则我不能推荐使用第三方库作为“最佳实践”。
  • @Omnifarious:感谢您的回答,但我也在努力鼓励其他人分享他们的意见。
  • 有什么原因你不考虑shared_ptr吗?
  • @Zac:我不介意考虑 shared_ptr,但我想使用一个通用的解决方案。 IE。如果很多人在接口中使用 shared_ptr 并且它是合理的,我也可以使用它。不过,我怀疑它是否普遍,因为 shared_ptr 非常复杂并且有开销。
  • 在大多数情况下,我发现'shared_ptr`从工厂返回时效果很好。它允许对象拥有自己的所有权并保持执行操作的能力,例如对一组这些接口指针进行操作。在大多数系统上,引用计数的微小开销甚至都不明显(嵌入式系统除外——无论如何,您可能使用 C 而不是 C++)。

标签: c++ oop ownership


【解决方案1】:

暂时使用::std::auto_ptr,当C++0x可用时,再切换到::std::unique_ptr。至少在您将所有权交还给调用者的工厂案例中。

是的::std::auto_ptr 有问题而且很丑。是的,它在 C++0x 中已被弃用。但这是推荐的方法。我还没有检查过::boost::unique_ptr,但没有移动语义,我认为它不会比::std::auto_ptr 做得更好。

我更喜欢通过搜索和替换来升级的想法,尽管有一些不寻常的情况不会产生预期的结果。幸运的是,这些情况会产生编译器错误:

::std::auto_ptr<int> p(new int);
::std::auto_ptr<int> p2 = p; 

至少要变成这样

::std::unique_ptr<int> p(new int);
::std::unique_ptr<int> p2 = ::std::move(p);

我更喜欢搜索和替换,因为我发现使用宏和 typedef 来处理此类事情往往会使事情变得更加晦涩难懂,以后更难以理解。如果需要,可以有选择地应用您的代码库的搜索和替换(::std::auto_ptr 在 C++0x 中不会消失,它只是被弃用了)并使您的代码具有清晰和明显的意图。

至于“常见”的做法,我认为这个问题已经存在的时间不够长,以至于没有一种普遍接受的方法来处理转换。

【讨论】:

  • +1 -- std::auto_ptr 很棒,尽管人们一直在抨击它。
  • 好吧,但是我如何通过搜索和替换整个代码来切换到它?
  • @7vies:假设 boost 依赖不是问题,只需继续使用 boost,除非您必须转移所有权。否则你将不得不进行搜索和替换。
  • @7vies:将那个问题的答案添加到我的答案中。
  • 搜索和替换看起来是一种非常丑陋的做法,最初使用 typedef 甚至宏对我来说看起来更好:\ 你所建议的真正的最佳实践是什么,或者只是一个有什么方法?
猜你喜欢
  • 2021-09-29
  • 2017-05-15
  • 1970-01-01
  • 2011-08-17
  • 2018-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多