[英]How to delete a pointer after cast to void* and back
作为“消息”类的一部分,我尝试通过将它们转换为 void* 指针并将它们保存在记住指针原始类型的包装类(“MsgData”)中来传输不同类型的指针。
例如一个布尔指针:
bool* data = new bool;
event.wheel.y < 0 ? *data = false : *data = true;
send("all", this, MSG_MOUSE_SCROLL, MsgData(data));
调用 MsgData 的兼容构造函数并将变量保存为我的消息类的成员:
MsgData(): type_(NULLPTR), data_(nullptr) {} // Null
MsgData(const bool* data): type_(BOOL), data_((void*)data) {} // Bool
MsgData(const std::string* data): type_(STRING_STD), data_((void*)data) {} // std::string
// ... etc.
我可以将指针转换回来并使用它们而不会出现任何错误,但是当我尝试删除它们时,程序崩溃了:
~MsgData() {
switch (type_) {
case (BOOL):
if ((bool*)data_)
delete (bool*)data_;
break;
// ... etc.
}
}
bool 指针只是一个示例,所有其他类型和类也是如此。 只有当我尝试删除指针时程序才会崩溃。 将它们转换回原始类型并使用它们不是问题。
我研究这个问题,并发现像类似的问题这一个在计算器上,但同时,它似乎被认为是不好的风格蒙上了指针无效*和背部我找不到原因,程序崩溃。
好吧,该问题的更好解决方案是使用boost::variant
(或std::variant
)。 一旦你开始使用它,删除和管理类型和数据的所有麻烦都会自动消失。 您不是第一个遇到此类问题的人; 许多其他人都面临过这个问题,解决方案可以通过boost::variant
或std::variant
的形式获得。
无论如何,由于您自己正在开发解决方案,因此我的建议是:在构造函数本身中构造一个适当的删除器......或者每当您知道您的类将保存什么类型的数据时:
MsgData()
: type_(NULLPTR), data_(nullptr) {}
MsgData(const bool* data)
: type_(BOOL), data_((void*)data), deleter_(&deleter<BOOL>) {}
MsgData(const std::string* data)
: type_(STRING_STD), data_((void*)data), deleter_(&deleter<std::string>) {}
其中deleter_
是成员:
std::function<void(void const*)> deleter_;
并且deleter
被定义为函数模板:
template<typename T>
void deleter(void const * data) {
delete static_cast<T const *>(data);
}
一旦你有了这些,你的析构函数看起来像这样:
~MsgData() {
if (deleter_) {
deleter_(data_);
}
}
希望有帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.