sha*_*oth 6 c++ pointers static-cast visual-c++
我需要为回调函数编写代码(它将在ATL中调用,但这并不重要):
HRESULT callback( void* myObjectVoid )
{
if( myObjectVoid == 0 ) {
return E_POINTER;
}
CMyClass* myObject = static_cast<CMyClass*>( myObjectVoid );
return myObject->CallMethod();
}
Run Code Online (Sandbox Code Playgroud)
这里void*保证是指针CMyClass,所以static_cast是合法的.我担心的是代码必须尽可能是可移植的(至少对于较新版本的Visual C++).因此,为了超级偏执,我倾向于检查CMyClass*指针 - 我的意思是如果它被证明是空的?
if( myObjectVoid == 0 ) {
return E_POINTER;
}
CMyClass* myObject = static_cast<CMyClass*>( myObjectVoid );
if( myObject == 0 ) {
return E_POINTER;
}
Run Code Online (Sandbox Code Playgroud)
第二次检查合理吗?是否可以static_cast将非空指针转换为空指针?
如果在不同偏移量的对象部分之间进行转换,static_cast可以更改指针值:
class A{ int x; }; class B{ int y; };
class C : A,B {};
C *c=new C();
B *b=c;
// The B part comes after the A part in C. Pointer adjusted
C *c2=static_cast<C*>(b);
// Pointer gets adjusted back, points to the beginning of the C part
Run Code Online (Sandbox Code Playgroud)
但是,"空指针值(4.10)将转换为目标类型的空指针值." (5.2.9-8),即如果 c是NULL,那么b也是NULL(并且没有调整)因此c2被设置为NULL.整个事情意味着:如果静态转换非NULL myObjectVoid产生NULL,则myObjectVoid通过以某种方式绕过类型系统获得值.这意味着,编译器可能会抛弃你的第二张支票,因为"它无论如何都不会发生".
否.如果指针引用了有效对象,并且转换有效,则结果也将引用有效对象,因此它不会为空.如果其中一个无效,则代码不正确,结果未定义.因此,有效使用给出null结果的唯一方法是从null开始.
在对象指针和void指针之间进行转换的特定情况下,标准就是这样说的(5.2.9/10):
转换为"指向"指针
void并返回原始指针类型的"指向对象的指针"类型的值将具有其原始值.
这个(4.10/3)
将"指针指向T"转换为"指向指针"的结果指向T
void类对象所在的存储位置的开头
所以原始和最终的对象指针将是相同的,void当且仅当对象指针是指针时,指针才为空.