【发布时间】:2017-09-13 17:59:58
【问题描述】:
我对我在 VC++ 2015 中看到的结果感到惊讶,需要帮助来了解它的工作原理。
struct MyType
{
MyType(int x_) : x(x_) { }
int x;
};
auto u = std::make_unique<MyType>(10);
void* pv = &u;
这显然失败了,因为u 的地址不是指向MyType 的指针:
MyType *pM = (MyType*)pv;
但这行得通,pM2 获取存储在u 中的MyType 对象的地址:
MyType** ppM = (MyType**)pv;
MyType* pM2 = *ppM;
标准中是否有任何内容表明这应该有效?还是仅由于我的编译器的不可移植实现细节而起作用?有什么东西可以让我将unique_ptr 视为一个循环的指针?
在您说“这很愚蠢,不要使用 void* 或 C 样式转换”之前,请理解我正在使用通过 void 指针和结构成员偏移处理结构序列化的遗留代码。我现在不能改变那部分。但我想为结构成员使用unique_ptr 来简化内存所有权和清理。而且我想知道我的unique_ptr 在这个遗留环境中是多么脆弱。
【问题讨论】:
-
你为什么不直接做
MyType* pv = u.get();? en.cppreference.com/w/cpp/memory/unique_ptr/get -
以上各项的有效/无效是什么意思?在每种情况下,您是否都试图获取指向
unique_ptr拥有的对象的指针?如果是,MyType**演员表是什么?只需使用void *pv = u.get();unique_ptr,它有一个无状态删除器,你的删除器通常只包含一个指向托管对象的指针,这就是你的类型双关语似乎起作用的原因。 -
你很幸运,因为
std::unique_ptr很可能是一个具有单个指针属性的结构,并且碰巧std::unique_ptr类型的对象的地址与第一个属性的地址相同这个对象,也就是指针。 -
抛弃不安全的 C 风格转换。如果您必须强制转换(总是尝试不),请使用C++强制转换。但甚至不清楚你真正想要的是演员表。
-
我正在编写的代码没有进行这种转换/类型双关语。它是执行 C 风格转换的通用序列化代码。它不是为智能指针制作的,它是在不久的将来不会改变的遗留代码。我刚刚尝试在通过序列化的结构中使用 unique_ptr 。从目前的答案来看,听起来我应该坚持使用原始指针和析构函数。
标签: c++ c++11 visual-c++ unique-ptr