KRy*_*yan 5 c++ windows casting
我正在使用LPARAM(基本上是一个long,除非我们在64位系统上,在这种情况下它是一个long long)一个LVITEM(被调用的)成员lParam来存储指向与该条目重合的对象的指针ListView.
当我想编辑那个项目时,我想将它转换LPARAM为a MyClass*,只要lParam正确设置为首先等于a MyClass*,它就可以正常工作,但是我想做一些检查以确保事实上,MyClass这是一个这个数字所指向的.
目前我有这个:
LVITEM lv;
// lv is filled in by LVM_GETITEM
classPtr = static_cast<MyClass*>((void*)lv.lParam);
if ( !classPtr )
return false;
Run Code Online (Sandbox Code Playgroud)
现在,我并不完全清楚:如果参数不是有效指针,它会static_cast返回NULL吗?我假设没有,因为那dynamic_cast是为了什么,但我不完全确定.并且,如果我在这个假设中classPtr是正确的,在我尝试访问其成员并导致崩溃之前,有没有办法检查它是否有效...
static_cast<>不会对类型进行运行时检查,因此您所拥有的内容将无法工作,至少不会像您认为的那样.所有这些static_cast<>都是基于编译时已知信息的指针算法.
dynamic_cast<> 可能会工作,但它要求该类至少有一个虚函数(对于RTTI),如果LPARAM甚至不是指向类类型的指针,它肯定会严重失败.
在给定任意指针或类似的整数值LPARAM的情况下,没有通用的方法来确定它实际指向的实例MyClass.
在特定情况下我要做的是将列表视图包装在自己的类中,并公开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;
};
Run Code Online (Sandbox Code Playgroud)
这种方法的优点是,现在您可以完全控制列表视图控件及其界面,因此这将始终有效(尽管存在错误和恶意/无能的程序员).你甚至可以把它变成一个模板,这样它就可以用于除了以外的类MyClass.
你根本无法用纯标准 C++ 来检查它。您只能使用 Windows API 进行概率检查。因此,在实践中,您只能通过使代码正确来保证这一点。
如果您可以检查它,您仍然不会知道它是正确的实例MyClass。
所以,唯一的好办法就是保证你的代码正确。当您限制对事物的访问时,这就更容易了。C++ 有许多功能可以帮助您限制访问,例如const;使用它们。
干杯,
| 归档时间: |
|
| 查看次数: |
4702 次 |
| 最近记录: |