[英]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.