簡體   English   中英

強制轉換為 void* 並返回后如何刪除指針

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM