我一直在阅读StackOverflow,并开始怀疑我写过的所有代码,我一直在想“这是不确定的行为?”即使在已经工作了很长时间的代码中也是如此。
所以我的问题 - 将指向对象(在本例中为抽象接口类)的指针强制转换为void *然后将它们转换回原始类并使用它们调用方法是否安全且定义良好?
我完全清楚执行此操作的代码可能很糟糕。我现在甚至不考虑这样编写它(这是我不想改变的旧代码),所以我不打算讨论更好的方法来做到这一点。如果我再次这样做,我已经知道如何更好地写它。但是如果在C ++中实际上已经破坏了它,那么我将不得不考虑更改代码,如果它只是糟糕的代码,那么更改代码将不是优先考虑的事情。
我对一年或两年前这么简单的事情毫无疑问但随着我对C ++的理解增加,我发现我越来越担心代码在标准下是安全的,即使它运行得非常好。也许阅读过多的堆栈溢出有时会对生产力造成不利影响:P
答案 0 :(得分:16)
你很安全。
来自C ++(0x)草稿,
§5.2.9/ 13(static_cast
):
指向对象的类型指针的值转换为“指向 cv
void
的指针”并返回,可能具有不同的cv资格,应具有其原始值。
§5.2.10/ 7(reinterpret_cast
):
将“指向
T1
的指针”类型的右值转换为“指向T2
”的类型(其中T1
和T2
是对象类型以及对齐要求的位置T2
的{{1}}并不比T1
更严格,并且返回原始类型会产生原始指针值。
(当然,转换为不相关的类是未定义的行为。)
答案 1 :(得分:8)
所以我的问题 - 将指向对象(在本例中为抽象接口类)的指针强制转换为void *然后将它们转换回原始类并使用它们调用方法是否安全且定义良好?
是 - 只要您回放到完全相同的类型。否则,基类指针调整可能会破坏指针的值。
实际上,这可能(仅)在使用多重继承时才有意义:派生类的指针在物理地址上可能与指向基类的指针不同。
答案 2 :(得分:1)
我们通常使用这种技术来避免根据您使用的环境(基于Web,Windows,Linux等)在每个类中使用switch语句
使用void **
作为参考。
void ** detailObject;
创建一个函数来返回引用的对象:
TheObject *TheClass::GetObject(){
TheObject *object = (TheObject*)object;
return object;
}
从现在开始,只需将该功能用作对象即可。例如GetObject()->Go()
;