【问题标题】:Why use XXXX_new and XXXX_free over new and delete?为什么使用 XXXX_new 和 XXXX_free 而不是 new 和 delete?
【发布时间】:2016-04-26 05:13:34
【问题描述】:

在阅读libssh library时,我看到他们特别说

libssh 遵循 allocate-it-deallocate-it 模式。使用 xxxxx_new() 分配的每个对象都必须使用 xxxxx_free() 释放

这是因为它是一个 C 库而不是一个 C++ 库,其中 new 和 delete 不存在,还是忘记 new 和 delete 并使用 xxxx_new 和 xxxx_free 手动创建和删除对象是一种常见的做法图案?如果这是一种常见做法,那么它与 new 和 delete 以及被调用的构造函数和析构函数相比有什么好处?

[编辑] 将链接添加到我在“libssh 库”上将其作为<a> 标记阅读的位置,供那些询问的人使用。

【问题讨论】:

  • 你有链接到你读到的地方吗?
  • 除了它是一个 C 接口之外,主要区别在于它改变了控制对象创建的人——消费者与库。有了这个接口,库控制更多,这赋予了它更多的权力(例如日志记录、断点、全局配置、避免来自不同 DLL 的不匹配的newdelete 调用等)
  • ssh_new 与 ssh_free 配对,ssh_scp_new 与 ssh_scp_free 配对,ssh_string_new 与 ssh_string_free 配对,ssh_event_new 与 ssh_event_free 配对。分别针对 session、scp、string 和 event 对象的 allocate 和 free 函数,它隔离了分配器和对象的实现细节。 C++ 的 new 和 delete 运算符在 C 库中没有用。
  • 因此,如果有人要编写这个库的 C++ 版本(或至少一个环绕它的库),那么坚持函数调用约定或使用传统的 C++ new 和 delete 是否有意义?合适的构造函数和析构函数?

标签: c++ libssh


【解决方案1】:

乍一看您提供的链接表明libssh 使用xxxx_new() 函数作为组合的分配器/构造器调用。它实际上只是工厂函数的标准命名。同样,xxxx_free() 充当析构器/释放器组合。

每当库想要为其用户代码提供类型安全的不透明指针时,将分配和构造组合到一个函数调用中是一个好主意:要编译用户代码,编译器只需要知道类型存在并且它是不同的从任何其他类型。不需要在公共标头中包含完整的 class/struct 声明。

这种方法在 C++ 库中不是很流行,因为它们通常希望他们的对象表现得像任何普通的 C++ 对象(这意味着指针/引用不能对编译器不透明)。但是如果一个库提供了一个 C 接口,这样的工厂函数就不太可能因为用户传入指向未初始化对象的指针(忘记构造函数调用)或搞砸对象的分配而出现奇怪的错误。

【讨论】:

    【解决方案2】:

    这是因为它是一个 C 库,而不是一个不存在 new 和 delete 的 C++ 库

    很可能是的。与 c 代码中的 malloc() 一样,通常需要完成比普通内存分配更多的初始化。类似于new 调用class/struct 创建实例的构造函数。

    或者忘记 new 和 delete 并使用 xxxx_new 和 xxxx_free 模式手动创建和删除对象是一种常见的做法?

    不,这在 c++ 中并不常见。

    处理动态分配的实例和所有权的方法是使用标准 c++ Dynamic memory management 实用程序中的函数和智能指针类。

    【讨论】:

      猜你喜欢
      • 2019-02-25
      • 2014-12-12
      • 1970-01-01
      • 1970-01-01
      • 2010-10-28
      • 1970-01-01
      • 2013-03-30
      • 1970-01-01
      • 2010-10-14
      相关资源
      最近更新 更多