为什么 C 库和框架从不使用智能指针?

新手上路,请多包涵

我在几篇文章中读到几乎不应该使用原始指针。相反,它们应该始终包装在智能指针中,无论是作用域指针还是共享指针。

然而,我注意到像 Qt、wxWidgets 这样的框架和像 Boost 这样的库永远不会返回也不期望智能指针,就好像它们根本没有使用它们一样。相反,它们返回或期望原始指针。有什么理由吗?在编写公共 API 时是否应该远离智能指针,为什么?

只是想知道为什么在许多主要项目似乎避免使用智能指针时推荐使用智能指针。

原文由 laurent 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1k
2 个回答

除了许多库是在标准智能指针出现之前编写的之外,最大的原因可能是缺乏标准的 C++ 应用程序二进制接口 (ABI)。

如果您正在编写仅包含标头的库,则可以将智能指针和标准容器传递给您的核心内容。它们的源代码在编译时可供您的库使用,因此您仅依赖于它们接口的稳定性,而不是它们的实现。

但由于缺乏标准 ABI,您通常 无法 安全地跨模块边界传递这些对象。 GCC shared_ptr 可能不同于 MSVC shared_ptr ,后者也可能不同于英特尔 shared_ptr 。即使使用 相同 的编译器,也不能保证这些类在版本之间是二进制兼容的。

底线是,如果您想分发库的 预构建 版本,您需要一个可以依赖的标准 ABI。 C 没有,但编译器供应商非常擅长针对给定平台的 C 库之间的互操作性——存在事实上的标准。

这种情况对于 C++ 来说不是那么好。各个编译器可以处理它们自己的二进制文件之间的互操作,因此您可以选择为每个受支持的编译器(通常是 GCC 和 MSVC)分发一个版本。但鉴于此,大多数库只导出一个 C 接口——这意味着原始指针。

然而,非库代码通常更喜欢智能指针而不是原始代码。

原文由 Jon Purdy 发布,翻译遵循 CC BY-SA 3.0 许可协议

可能有很多原因。列出其中的几个:

  1. 智能指针最近才成为标准的一部分。在那之前,它们是其他图书馆的一部分
  2. 它们的主要用途是避免内存泄漏;许多库没有自己的内存管理;通常,它们提供实用程序和 API
  3. 它们被实现为包装器,因为它们实际上是对象而不是指针。与原始指针相比,它具有额外的时间/空间成本;图书馆的用户可能不希望有这样的开销

编辑:使用智能指针完全是开发人员的选择。这取决于各种因素。

  1. 在性能关键系统中,您可能不想使用会产生开销的智能指针

  2. 需要向后兼容的项目,您可能不想使用具有 C++11 特定功能的智能指针

Edit2 由于以下段落,在 24 小时内有一连串的反对票。我不明白为什么答案被否决,即使下面只是一个附加建议而不是答案。

但是,C++ 总是帮助您打开选项。 :) 例如

template<typename T>
struct Pointer {
#ifdef <Cpp11>
  typedef std::unique_ptr<T> type;
#else
  typedef T* type;
#endif
};

并在您的代码中将其用作:

 Pointer<int>::type p;

对于那些说智能指针和原始指针不同的人,我同意这一点。上面的代码只是一个 _想法_,人们可以编写一个可以与 #define 互换的代码,这不是 强制 的;

例如, T* 必须显式删除,但智能指针不需要。我们可以有一个模板 Destroy() 来处理它。

 template<typename T>
void Destroy (T* p)
{
  delete p;
}
template<typename T>
void Destroy (std::unique_ptr<T> p)
{
  // do nothing
}

并将其用作:

 Destroy(p);

同样,对于原始指针,我们可以直接复制它,对于智能指针,我们可以使用特殊操作。

 Pointer<X>::type p = new X;
Pointer<X>::type p2(Assign(p));

其中 Assign() 为:

 template<typename T>
T* Assign (T *p)
{
  return p;
}
template<typename T>
... Assign (SmartPointer<T> &p)
{
  // use move sematics or whateve appropriate
}

原文由 iammilind 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏