简体   繁体   English

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

[英]Casting pointer to object to void * in C++

I've been reading StackOverflow too much and started doubting all the code I've ever written, I keep thinking "Is that undefined behavour?" 我一直在阅读StackOverflow,并开始怀疑我写过的所有代码,我一直在想“这是不确定的行为?” even in code that has been working for ages. 甚至在已经工作了很长时间的代码中。

So my question - Is it safe and well defined behavour to cast a pointer to an object (In this case abstract interface classes) to a void* and then later on cast them back to the original class and call method using them? 所以我的问题 - 将一个指向对象(在本例中为抽象接口类)的指针转换为void *然后将它们转换回原始类并使用它们调用方法是否安全且定义良好的行为?

I'm fully aware that the code that does this is probably awful. 我完全清楚这样做的代码可能很糟糕。 I wouldn't even consider writing it like this now (this is old code which I don't really want to change), so I'm not looking for a discussion of better ways to do this. 我现在甚至不考虑这样编写它(这是我不想改变的旧代码),所以我不打算讨论更好的方法来做到这一点。 I already know how to write it better if I ever did this again. 如果我再次这样做,我已经知道如何更好地写它。 But if it's actually broken to rely on this in C++ then I'll have to look at changing the code, if it's merely awful code then changing it won't be a priority. 但是,如果在C ++中实际上已经破坏依赖于此,那么我将不得不考虑更改代码,如果它只是糟糕的代码,那么更改它将不是优先级。

I would have had no doubts about something this simple a year or two ago but as my understanding of C++ increases I actually find I have more and more worries about code being safe under the standards even if it works perfectly well. 我对一年或两年前这么简单的事情毫不怀疑,但随着我对C ++的理解增加,我发现我越来越担心代码在标准下是安全的,即使它运行得非常好。 Perhaps reading too much stack overflow is a bad thing for productivity sometimes :P 也许阅读过多的堆栈溢出有时对生产力是一件坏事:P

You are safe. 你很安全。

From C++(0x) draft, 从C ++(0x)草案,

§5.2.9/13 (for static_cast ): §5.2.9/ 13(对于static_cast ):

A value of type pointer to object converted to “pointer to cv void ” and back, possibly with different cv-qualification, shall have its original value. 指向对象的类型指针的值转换为“指向cv void指针”并返回,可能具有不同的cv-qualification,应具有其原始值。

§5.2.10/7 (for reinterpret_cast ): §5.2.10/ 7(对于reinterpret_cast ):

Converting an rvalue of type “pointer to T1 ” to the type “pointer to T2 ” (where T1 and T2 are object types and where the alignment requirements of T2 are no stricter than those of T1 ) and back to its original type yields the original pointer value. 将“指向T1指针”的rvalue转换为“指向T2指针”类型(其中T1T2是对象类型, T2的对齐要求不比T1更严格)并返回其原始类型会产生原始类型指针值。

(Of course, casting to an unrelated class is undefined behavior.) (当然,转换为不相关的类是未定义的行为。)

So my question - Is it safe and well defined behavour to cast a pointer to an object (In this case abstract interface classes) to a void* and then later on cast them back to the original class and call method using them? 所以我的问题 - 将一个指向对象(在本例中为抽象接口类)的指针转换为void *然后将它们转换回原始类并使用它们调用方法是否安全且定义良好的行为?

Yes – as long as you cast back to the exact same type. 是的 - 只要你回到完全相同的类型。 Otherwise, base class pointer adjustments may destroy the value of the pointer. 否则,基类指针调整可能会破坏指针的值。

In practice, this is (probably) only relevant when using multiple inheritance: pointers to a derived class may differ in their physical address from pointers to their base class. 在实践中,这可能(仅可能)在使用多重继承时是相关的:指向派生类的指针的物理地址可能与指向其基类的指针不同。

We use this technique commonly to avoid having switch statements in every single class based on the environment you are using (web-based, Windows, Linux etc) 我们通常使用这种技术来避免根据您使用的环境(基于Web,Windows,Linux等)在每个类中使用switch语句

Use void ** for references. 使用void **作为参考。

void ** detailObject;

Create a function to return the referenced object: 创建一个函数来返回引用的对象:

TheObject *TheClass::GetObject(){
    TheObject *object   =   (TheObject*)object;
    return object;
}

Just use the function as the object from now on. 从现在开始,只需将该函数用作对象即可。 eg GetObject()->Go() ; 例如GetObject()->Go() ;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM