c++ - std::unique_ptr 用于需要免费的 C 函数

标签 c++ c++11

想想一个 C 函数,它返回必须是 freed 的东西,例如 POSIX 的 strdup()。我想在 C++11 中使用该函数并避免任何泄漏的机会,这是正确的方法吗?

#include <memory>
#include <iostream>
#include <string.h>

int main() {
    char const* t { "Hi stackoverflow!" };
    std::unique_ptr<char, void(*)(void*)>
        t_copy { strdup(t), std::free };

    std::cout << t_copy.get() << " <- this is the copy!" <<std::endl;
}

假设它是有道理的,是否可以对非指针使用类似的模式?例如对于返回 int?

的 POSIX 函数 open

最佳答案

您所拥有的东西极有可能在实践中发挥作用,但并非完全正确。您可以使其更有可能按以下方式工作:

std::unique_ptr<char, decltype(std::free) *>
    t_copy { strdup(t), std::free };

原因是std::free的函数类型不保证是void(void*)。它保证在传递 void* 时是可调用的,并且在这种情况下返回 void,但至少有两种函数类型符合该规范:一种使用 C链接,一个与 C++ 链接。大多数编译器都不会注意这一点,但为了正确起见,您应该避免对此做出假设。

但是,即使那样,这也不是完全正确的。正如@PeterSom 在评论中指出的那样,C++ 允许实现例如使 std::free 成为重载函数,在这种情况下,您和我对 std::free 的使用都将是模棱两可的。这不是授予 std::free 的特定权限,它是授予几乎所有标准库函数的权限。为了避免这个问题,需要一个自定义函数或仿函数(如他的回答)。

Assuming it makes sense, it is possible to use a similar pattern with non-pointers?

不适用于 unique_ptr,它确实特定于指针。但是您可以创建自己的类,类似于 unique_ptr,但无需对被包装的对象做出假设。

关于c++ - std::unique_ptr 用于需要免费的 C 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27440953/

相关文章:

c++ - 这个未知大小数组的列表初始化在 C++0x 中有效吗?

multithreading - 为什么我不能像这样动态创建线程向量

C++:语句 'TYPE& name(&TYPE);' 是什么意思?

C++ 声明中的两种或多种数据类型

c++ - 不完整类型的无效使用

c++ - 什么是复制省略和返回值优化?

c++ - map 中的字符串是如何存储的?

c++ - const_cast 是如何工作的?

c++ - 从工厂函数就地初始化不可复制的成员(或其他对象)

c++ - 具有多重继承的复制赋值运算符