如何在转换为void *并返回

时间:2018-02-11 13:29:33

标签: c++ pointers casting delete-operator void-pointers

作为"消息" -class的一部分,我尝试通过将它们转换为void * -pointers并将它们保存在包装类中来转移不同类型的指针(" MsgData")它会记住指针的原始类型。

例如bool指针:

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指针只是一个例子,所有其他类型和类也是如此。 只有当我尝试删除指针时,程序才会崩溃。将它们恢复到原始类型并使用它们不是问题。

我研究了这个问题,并在StackOverflow上发现了类似this one的类似问题,但似乎被认为是错误的样式,将指针转换为void *然后我找不到程序崩溃的原因。

1 个答案:

答案 0 :(得分:1)

嗯,问题的更好解决方案是使用boost::variant(或std::variant)。一旦开始使用它,删除和管理类型数据的所有麻烦都将自动发生。你不是第一个面对这种问题的人;许多其他人都面临这种情况,解决方案以boost::variantstd::variant的形式提供。

无论如何,既然你是在自己开发一个解决方案,我的建议是:在构造函数本身构建一个合适的 deleter ..或者每当你知道 type 的时候数据您的课程将会成立:

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_);
   }
}

希望有所帮助。