You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从库返回的原始指针创建unique_ptr并通过引用传递?是否有更优方案?

关于用unique_ptr接管库返回原始指针的问题解答

现有代码的有效性

你当前的实现是有效的:通过std::unique_ptr::reset()方法,成功将库返回的原始指针(假设由new分配)的所有权转移给了unique_ptr,代码能正常输出42也验证了这一点。结合MariaDB C++ Connector的示例代码(直接用driver->connect()的返回值初始化unique_ptr),可以确认该库确实用new创建Connection对象,因此默认的unique_ptr删除器(调用delete)是安全的。

更优的实现方案

虽然现有代码可行,但有两种更贴合C++最佳实践的写法:

方案1:直接返回unique_ptr(推荐,若可调整接口)

如果允许打破“返回bool表示成功状态”的惯例,直接返回unique_ptr是最清晰的写法——它明确传递了对象所有权转移的语义,无需额外的输出参数:

#include <memory>
#include <iostream>

class A {
public:
    int b;
    A() : b(42) {}
};

std::unique_ptr<A> create() {
    // 直接将库返回的原始指针包装为unique_ptr返回
    return std::unique_ptr<A>(new A); 
    // 实际场景替换为:return std::unique_ptr<A>(库函数调用);
}

int main() {
    auto foo = create();
    std::cout << "foo.b is " << foo->b << '\n';
}

方案2:保持返回bool的同时优化实现

如果必须遵循现有代码的“返回bool”约定,可以保留引用传递,但补充错误处理逻辑(因为库函数可能在失败时返回nullptr或抛出异常):

#include <memory>
#include <iostream>

class A {
public:
    int b;
    A() : b(42) {}
};

bool create(std::unique_ptr<A>& p) {
    try {
        A* raw_ptr = new A; // 替换为实际的库函数调用,比如driver->connect(...)
        if (!raw_ptr) {
            return false;
        }
        p.reset(raw_ptr);
        return true;
    } catch (const std::exception& e) {
        // 处理库可能抛出的异常,比如MariaDB的sql::SQLException
        p.reset();
        return false;
    }
}

int main() {
    std::unique_ptr<A> foo;
    if (create(foo)) {
        std::cout << "foo.b is " << foo->b << '\n';
    } else {
        std::cout << "对象创建失败\n";
    }
}

这种写法既保持了和现有代码的一致性,又增加了鲁棒性,能处理库函数可能出现的错误情况。


内容的提问来源于stack exchange,提问作者QF0

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 18:01:29