Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 是否可以将所有权从空*转移到唯一的ptr?_C++_C++11 - Fatal编程技术网

C++ 是否可以将所有权从空*转移到唯一的ptr?

C++ 是否可以将所有权从空*转移到唯一的ptr?,c++,c++11,C++,C++11,我目前正在为一些插件项目使用dlopen函数。 此函数句柄返回一个void*,然后我将所有句柄保存到名为handles的映射中: void* handle = dlopen(path.c_str(), RTLD_LAZY); handles[file] = handle; 我的目标是将所有权传递给地图,我正在考虑一个独特的\u ptr,但不确定这是否可行 如果不可能,我还有其他选择吗?如果我理解正确,你可以做类似的事情 为指针类型定义关闭函数和别名: auto closeFunc = []

我目前正在为一些插件项目使用
dlopen
函数。
此函数句柄返回一个
void*
,然后我将所有句柄保存到名为
handles
的映射中:

void* handle = dlopen(path.c_str(), RTLD_LAZY);  
handles[file] = handle;
我的目标是将所有权传递给地图,我正在考虑一个
独特的\u ptr
,但不确定这是否可行


如果不可能,我还有其他选择吗?

如果我理解正确,你可以做类似的事情

为指针类型定义关闭函数和别名:

auto closeFunc = [](void* vp) {
  dlclose(vp);
};
using HandlePtr = std::unique_ptr<void, decltype(closeFunc)>;
std::map<std::string, HandlePtr> handles;
当唯一ptr超出范围时,将调用
closeFunc

可以通过组合上面的两行来防止原始指针:

HandlePtr handle(dlopen(path.c_str(), RTLD_LAZY), closeFunc );
handles[file] = std::move( handle );
这将使用指定要使用的删除程序的第二个参数


ps:代码> map < /Calp> s和<代码> UNQuijpPTR s不能按原样播放,您可能需要一些使用或使用C++标准的移动或移动。或者使用
shared\u ptr

如果我理解正确的话,你可以这样做

为指针类型定义关闭函数和别名:

auto closeFunc = [](void* vp) {
  dlclose(vp);
};
using HandlePtr = std::unique_ptr<void, decltype(closeFunc)>;
std::map<std::string, HandlePtr> handles;
当唯一ptr超出范围时,将调用
closeFunc

可以通过组合上面的两行来防止原始指针:

HandlePtr handle(dlopen(path.c_str(), RTLD_LAZY), closeFunc );
handles[file] = std::move( handle );
这将使用指定要使用的删除程序的第二个参数


ps:代码> map < /Calp> s和<代码> UNQuijpPTR s不能按原样播放,您可能需要一些使用或使用C++标准的移动或移动。或者使用
shared\u ptr

std::unique_ptr对于“包装”使用资源而不需要在完成时删除或关闭的c库特别有用。它不仅可以防止您忘记何时删除/关闭资源,还可以使使用资源异常变得安全—因为在发生异常时,资源会得到正确的清理

我可能会这样做:

// closer function to clean up the resource
struct dl_closer{ void operator()(void* dl) const { dlclose(dl); }};

// type alias so you don't forget to include the closer functor
using unique_dl_ptr = std::unique_ptr<void, dl_closer>;

// helper function that ensures you get a valid dl handle
// or an exception.    
unique_dl_ptr make_unique_dl(std::string const& file_name)
{
    auto ptr = unique_dl_ptr(dlopen(file_name.c_str(), RTLD_LAZY));

    if(!ptr)
        throw std::runtime_error(dlerror());

    return ptr;
}
// open a dl
auto dl_ptr = make_unique_dl("/path/to/my/plugin/library.so");

// now set your symbols using POSIX recommended casting gymnastics
void (*my_function_name)();
if(!(*(void**)&my_function_name = dlsym(dl_ptr.get(), "my_function_name")))
    throw std::runtime_error(dlerror());

std::unique_ptr
对于“包装”使用资源而不需要在完成时删除或关闭的c库特别有用。它不仅可以防止您忘记何时删除/关闭资源,还可以使使用资源异常变得安全—因为在发生异常时,资源会得到正确的清理

我可能会这样做:

// closer function to clean up the resource
struct dl_closer{ void operator()(void* dl) const { dlclose(dl); }};

// type alias so you don't forget to include the closer functor
using unique_dl_ptr = std::unique_ptr<void, dl_closer>;

// helper function that ensures you get a valid dl handle
// or an exception.    
unique_dl_ptr make_unique_dl(std::string const& file_name)
{
    auto ptr = unique_dl_ptr(dlopen(file_name.c_str(), RTLD_LAZY));

    if(!ptr)
        throw std::runtime_error(dlerror());

    return ptr;
}
// open a dl
auto dl_ptr = make_unique_dl("/path/to/my/plugin/library.so");

// now set your symbols using POSIX recommended casting gymnastics
void (*my_function_name)();
if(!(*(void**)&my_function_name = dlsym(dl_ptr.get(), "my_function_name")))
    throw std::runtime_error(dlerror());

即使獾的答案是最好的遵循。请记住,C++中没有所有权概念,C++提供了类比来模拟并充分利用RAII,但是实际上,您没有从语言中保证任何一个源的所有权,即使是使用UNQuyQuPTR,例如:

{
  auto p_i = new int{5};
  auto up_i = std::unique_ptr<int>{p_i};
  *p_i = 6; //nothing in the language prevent something like this
  assert(*up_i == 6); //the unique_ptr ownership is not assured as you can see here
  delete p_i; //still not illegal
} //at run time, RAII mechanism strikes, destroy unique_ptr, try to free an already freed memory, ending up to a core dumped
{
自动p_i=新整数{5};
auto-up_i=std::unique_ptr{p_i};
*p_i=6;//语言中没有任何东西可以阻止这样的事情
assert(*up_i==6);//正如您在这里看到的那样,无法确保唯一的\u ptr所有权
删除p_i;//仍然不是非法的
}//在运行时,RAII机制攻击,销毁unique_ptr,尝试释放已释放的内存,最终导致内核转储
您甚至在unique_ptr类中有一个get member函数,它让您有机会像处理原始指针一样扰乱内存

在C++中,没有一种机制可以在编译时检测到“所有权”违反,也许你可以找到一些工具去检查它,但是它不是标准的,但是这只是推荐的实践。
因此,在C++中讨论“托管”内存,而不是“所有权”更为贴切和精确。

< P>即使BADGER应答是最好的。请记住,C++中没有所有权概念,C++提供了类比来模拟并充分利用RAII,但是实际上,您没有从语言中保证任何一个源的所有权,即使是使用UNQuyQuPTR,例如:

{
  auto p_i = new int{5};
  auto up_i = std::unique_ptr<int>{p_i};
  *p_i = 6; //nothing in the language prevent something like this
  assert(*up_i == 6); //the unique_ptr ownership is not assured as you can see here
  delete p_i; //still not illegal
} //at run time, RAII mechanism strikes, destroy unique_ptr, try to free an already freed memory, ending up to a core dumped
{
自动p_i=新整数{5};
auto-up_i=std::unique_ptr{p_i};
*p_i=6;//语言中没有任何东西可以阻止这样的事情
assert(*up_i==6);//正如您在这里看到的那样,无法确保唯一的\u ptr所有权
删除p_i;//仍然不是非法的
}//在运行时,RAII机制攻击,销毁unique_ptr,尝试释放已释放的内存,最终导致内核转储
您甚至在unique_ptr类中有一个get member函数,它让您有机会像处理原始指针一样扰乱内存

在C++中,没有一种机制可以在编译时检测到“所有权”违反,也许你可以找到一些工具去检查它,但是它不是标准的,但是这只是推荐的实践。

这样,在C++中讨论“托管”内存而不是“所有权”更为贴切和精确。

<代码> VUL> */COD>本身没有所有权概念,原始指针所知道的唯一“所有权”是您应该删除它。如果你没有,那么指针不拥有任何可能的复制品,所有权在这里的确切含义是什么?看,当你完成手柄(如果有的话)时,你应该做什么清理?手柄需要关闭。因此,在清除映射时,我希望自动关闭所有句柄(比如在唯一的\u ptr deleter中)。目前,我必须手动调用“close”并进行擦除,因此有两个操作。我不确定,但这可能是一种简化的实现方法。从来没用过。其他人可以回答。
void*
本身没有所有权的概念,原始指针知道的唯一“所有权”是你应该删除它,如果你不知道,那么指针就不拥有任何可能的副本,所有权在这里到底意味着什么?看,当你完成手柄(如果有的话)时,你应该做什么清理?手柄需要关闭。因此,在清除映射时,我希望自动关闭所有句柄(比如在唯一的\u ptr deleter中)。现在我得打电话给“亲密”人