我有一个指向对象的指针列表。这些对象没有任何共同之处(即没有共同的基类);为了更好地理解:它是GUI中鼠标光标下的对象列表。
现在我想知道它是什么类型的物体。节点,节点句柄,线段,标记等。但是我无法使用typeid(*ptr)
,因为ptr是const void*
。
任何解决方案?我可以强制使用typeid,因为我知道指针始终指向对象而不仅仅是值?或者没有办法添加一些假的公共基类?
(编辑:目前我这样做是因为我在列表中存储了一个结构,它另外存储了对象的类型(作为枚举)。也许我应该更改它来存储type_info
对象。 ..)
答案 0 :(得分:10)
对于技术解决方案,不考虑设计级别,使用std::map
或哈希表(无论如何)将无类型指针与类型描述符或类型指针相关联,当然在用户开始使用鼠标之前。
在更高的级别,void *指针只是不好的。
最好修改设计,而不是像std::map
那样使用kludge。
干杯&第h
答案 1 :(得分:4)
你肯定应该引入一个多态的虚拟基类或这个目的。否则,您需要首先对另一个可能不相关的指针类型执行reinterpret_cast/static_cast
,以便能够调用dynamic_cast
。由于在C ++中未定义访问具有错误类型的对象,因此使用dynamic_cast
会触发未定义的行为。
从技术上讲,RTTI信息通常存储在对象vtable的字段中,因此劫持二进制表示可能只是工作并为您提供每类型唯一指针。请不要这样做。
答案 2 :(得分:2)
您应该考虑使用boost::variant类型来保存原始指针( 之前将它们转换为void *),然后将它们存储在列表中。
然后,您可以尝试使用Get成员函数直接检索指针,或者更好的是,如果您有多种可能的类型,可以使用访问者语法在同一点处理。
答案 3 :(得分:0)
Declare and define a new class named "Object":
class Object
{
private: const void *pointer
const char *type;
public: template <class T> Object(const T *t)
{
this->pointer = t;
this->type = typeid(*t).name();
//NOTE that you must #include <typeinfo.h> in order to use the "typeid" keyword of course!
}
const void* GetPointer()
{
return this->pointer;
}
const char* GetType()
{
return this->type;
}
template <class T> const T* GetPointer()
{
return (T*)this->pointer;
}
template <class T> T& GetReference()
{
return *(T*)this->pointer;
}
template <class T> T GetValue()
{
return *(T*)this->pointer;
}
//You also can add some explicit and/or implicit conversions operators if you want by using template class in each
};
Then replace your void*
with Object
in your list.
Each time you iterate this list, first call the GetType
function of the Object
class to know the type of the object that the void pointer of this Object
points at. GetType
returns the name of this type as const char*
string.
You can use the strcmp
function to help you compare const char*
strings.
Then after that you called GetType
function, now you know to which type to convert or cast the void pointer of the Object
and then do whatever you want with the current iterated object!
Call one of the two overloads of the GetPointer
function to retrieve the void pointer of the Object
converted / casted or not.
If you just want the reference to the object that the void pointer of the Object
points at, then just call the GetReference
function instead GetPointer
.
Hope if you like my answer!