在C ++中将指向对象的指针转换为void *

时间:2010-04-10 12:40:26

标签: c++ pointers casting

我一直在阅读StackOverflow,并开始怀疑我写过的所有代码,我一直在想“这是不确定的行为?”即使在已经工作了很长时间的代码中也是如此。

所以我的问题 - 将指向对象(在本例中为抽象接口类)的指针强制转换为void *然后将它们转换回原始类并使用它们调用方法是否安全且定义良好?

我完全清楚执行此操作的代码可能很糟糕。我现在甚至不考虑这样编写它(这是我不想改变的旧代码),所以我不打算讨论更好的方法来做到这一点。如果我再次这样做,我已经知道如何更好地写它。但是如果在C ++中实际上已经破坏了它,那么我将不得不考虑更改代码,如果它只是糟糕的代码,那么更改代码将不是优先考虑的事情。

我对一年或两年前这么简单的事情毫无疑问但随着我对C ++的理解增加,我发现我越来越担心代码在标准下是安全的,即使它运行得非常好。也许阅读过多的堆栈溢出有时会对生产力造成不利影响:P

3 个答案:

答案 0 :(得分:16)

你很安全。

来自C ++(0x)草稿,

§5.2.9/ 13(static_cast):

  

指向对象的类型指针的值转换为“指向 cv void的指针”并返回,可能具有不同的cv资格,应具有其原始值。

§5.2.10/ 7(reinterpret_cast):

  

将“指向T1的指针”类型的右值转换为“指向T2”的类型(其中T1T2是对象类型以及对齐要求的位置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();