Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.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++ 使用reinterpret_cast的唯一\u ptr,结构是否会正确释放?_C++_C++11_Unique Ptr_Reinterpret Cast - Fatal编程技术网

C++ 使用reinterpret_cast的唯一\u ptr,结构是否会正确释放?

C++ 使用reinterpret_cast的唯一\u ptr,结构是否会正确释放?,c++,c++11,unique-ptr,reinterpret-cast,C++,C++11,Unique Ptr,Reinterpret Cast,我的动态分配结构是否会被唯一的\u ptr正确释放 unique_ptr<sockaddr> p; switch (type) { case AF_INET: p.reset( reinterpret_cast<sockaddr *>(new sockaddr_in) ); break; case AF_INET6: p.reset( reinterpret_cast<sockaddr *>(n

我的动态分配结构是否会被唯一的\u ptr正确释放

unique_ptr<sockaddr> p;

switch (type) {
    case AF_INET:
        p.reset( reinterpret_cast<sockaddr *>(new sockaddr_in) );
        break;
    case AF_INET6:
        p.reset( reinterpret_cast<sockaddr *>(new sockaddr_in6) );
        break;
    case AF_UNIX:
        p.reset( reinterpret_cast<sockaddr *>(new sockaddr_un) );
        break;
    default:
        throw domain_error("Invalid domain");
}   
unique\u ptr p;
开关(类型){
案例分析:
p、 重置(重新解释铸造(新的sockaddr_in));
打破
案例6:
p、 重置(重新解释铸造(新的sockaddr_in6));
打破
案例AF_UNIX:
p、 重置(重新解释铸造(新sockaddr_un));
打破
违约:
抛出域_错误(“无效域”);
}   

你有更好的选择吗?这是一种好的编码风格吗?对于每个结构,最好有3个独立的unique_ptr,而不是只有1个?

unique ptr删除其参数。删除未分配为的对象类型只能在狭窄的情况下避免UB

我会保守一点,这样做

template<class T, class U>
auto cleanup_as=[](U* u){ delete reinterpret_cast<T*>(u);};

template<class T>
using my_up=std:unique_ptr<T,void(*)(T*)>;

template<class T, class U>
my_up<T> wrap_up_as(U*pu){
  return my_up<T>(pu, cleanup_as<U,T>);
}
模板
自动清理_as=[](U*U){delete reinterpret_cast(U);};
模板
使用my_up=std:unique_ptr;
模板
我的总结(U*pu){
返回我的_up(pu,cleanup_as);
}
然后你的代码就变成了

my_up<sockaddr> p;

switch (type) {
  case AF_INET:
    p = wrap_up_as<sockaddr>( new sockaddr_in );
    break;
myup p;
开关(类型){
案例分析:
p=包装为(新的sockaddr_in);
打破
等等


这里,在唯一的PTR中,额外的函数指针破坏者记得如何分配结构,在销毁时正确地清理它。然后一些帮助器胶使它易于使用。

很难说。什么是<代码> SokAdDrRoFoo< /Cord>?它们是子类吗?<代码> SokAdDrd< /C> >,只要它们有虚析构函数,C++就行了。只要做正确的事情,你就不必对base进行丑陋的强制转换。但是如果他们不是(假设他们是Linux/POSIX的东西,他们就不会是这样),那么你只需将他们交给一个需要一个
sockaddr*
的地方,就可以得到UB。即使
sockaddr\u FOO
有一个
sockaddr
作为第一个成员,使强制转换“有效”,销毁时仍会有UB。对于在任何时间只能出现一个的不相关对象类型,请参阅
std::variant
,或者如果需要,也可以使用一些C++11的后端口。因为这看起来好像唯一的ptr存在一段时间,您只需更改“引擎盖下”的值即可,并且您使用的是普通的旧C数据类型:分配一个联合,然后根据
类型
只分配一个成员。以联合中的几个备用字节为代价,节省了动态内存处理所需的大量周期。这看起来像是解释联合存在原因的教科书示例。