如何使用 C 指针的自定义删除器创建unique_ptr?

How I can create unique_ptr with custom deleter for C pointer?

本文关键字:unique 创建 ptr 删除 何使用 指针 自定义      更新时间:2023-10-16

原始 C 样式代码

Environment* env = Environment::createEnvironment(Environment::Mode::DEFAULT);
Connection* conn = env->createConnection(db_user_name, db_password, db_conn_str);
...
env->terminateConnection(conn);
Environment::terminateEnvironment(env);

我尝试像这样使用 RAII 代码C++

std::unique_ptr<Environment, decltype(&Environment::terminateEnvironment)>env (Environment::createEnvironment(Environment::Mode::DEFAULT), &Environment::terminateEnvironment);
std::unique_ptr<Connection, decltype(&Environment::terminateConnection))>con(env->createConnection(db_user_name, db_password, db_conn_str), &(env->terminateConnection));

这是第一行的工作,但我在第二行出错。我是智能指针的新手。如何获取连接指针unique_ptr???

不能将非静态成员函数用作删除程序。而是编写一个 lambda 捕获所需的env指针并将其传递给std::unique_ptr

auto connectionDeleter = [env=env.get()](auto ptr){
env->terminateConnection(ptr);
};
std::unique_ptr<Connection, decltype(connectionDeleter)> con(env->createConnection(db_user_name, db_password, db_conn_str), connectionDeleter);

请注意,这不会阻止您在关闭打开的连接之前意外释放env。如果要获得该保证,则需要将env作为shared_ptr传递给删除程序:

std::shared_ptr<Environment> env(Environment::createEnvironment(Environment::Mode::DEFAULT), &Environment::terminateEnvironment);
auto connectionDeleter = [env](auto ptr){
env->terminateConnection(ptr);
};
std::unique_ptr<Connection, decltype(connectionDeleter)> con(env->createConnection(db_user_name, db_password, db_conn_str), connectionDeleter);