我正在使用 LPARAM
(本质上是 long
,除非我们在 64 位系统上,在这种情况下它是 long long
) LVITEM
的成员(称为 lParam
)存储指向与 ListView
中的条目一致的对象的指针.
当我想编辑那个项目时,我想转换那个 LPARAM
到 MyClass*
,只要 lParam
就可以正常工作正确设置为等于 MyClass*
首先,但我想做一些检查以确保它实际上是一个MyClass
这个数字指向。
目前我有这个:
LVITEM lv;
// lv is filled in by LVM_GETITEM
classPtr = static_cast<MyClass*>((void*)lv.lParam);
if ( !classPtr )
return false;
现在,我不是很清楚:static_cast
返回 NULL
如果参数不是有效指针?我想不会,因为那是 dynamic_cast
是为了,但我不完全确定。而且,如果我的这个假设是正确的,有没有办法检查 classPtr
在我尝试访问其成员并导致崩溃之前有效...
最佳答案
static_cast<>
不执行类型的运行时检查,因此您所拥有的将无法工作,至少不会像您认为的那样工作。全部static_cast<>
做的是基于编译时已知信息的指针运算。
dynamic_cast<>
可能 可以工作,但它要求该类至少有一个虚函数(用于 RTTI),如果 LPARAM
,它肯定会严重失败。甚至不是指向类类型的指针。
没有通用的方法来确定,给定任意指针或整数值,如 LPARAM
, 它实际上指向 MyClass
的一个实例.
在您的特定情况下,我会做的是将 ListView 包装在它自己的类中,并公开与 MyClass
一起使用的方法。只要。可能是这样的:
class MyListView
{
public:
MyListView() { /* create the list view HWND */ }
~MyListView() { /* destroy the list view HWND */ }
void Add(MyClass* listItem) // Only way to add items to list view
{
// Add to list view
}
MyClass* Get() const
{
LVITEM lv;
// lv is filled in by LVM_GETITEM
// Assume that this will work, since the only way to add
// list view items is through Add(), and Add() only accepts
// an instance of MyClass. Therefore the list view will only
// have pointers to instances of MyClass.
return static_cast<MyClass*>((void*)lv.lParam);
}
// ...
private:
// Set to private so users can't modify
// the list view without our consent.
HWND listView;
};
这种方法的优点是现在您可以完全控制 ListView 控件及其界面,因此这将始终有效(尽管存在错误和邪恶/无能的程序员)。您甚至可以将其设为模板,以便它可以与 MyClass
以外的类一起使用。 .
关于c++ - 从未知指针转换为类;如何检查有效性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6565838/