D语言中void*与类值的双向转换:哪种方式正确?
在D语言中void*与类值双向转换的正确方式
嘿,这个问题问到点子上了,D的类引用机制和C++那套有区别,很容易搞混。直接给结论:第一种写法才是正确的——也就是用 cast(ClassName)voidPointer 把void转回类实例,用 cast(void*)this 把类引用转成void。
为啥第二种不对?得先搞清楚D里类的本质:D的类是引用类型,你声明的ClassName类型变量,本身就是一个指向堆上类实例的指针。比如MyClass obj,obj存储的就是实例的内存地址,不是实例本身。
咱们拆解两种写法的逻辑:
- 从类到void*:
cast(void*)this是对的,因为this就是当前实例的地址(本质是指针值),直接转成void*完全没问题,相当于把指针的原始值存起来。 - 从void到类:
cast(ClassName)voidPointer会把void里存的地址,直接当作类实例的地址,还原成类引用。这正是你想要的,因为之前存的就是实例的地址。
再看第二种写法里的cast(ClassName*)voidPointer,这就错得离谱了——ClassName*代表的是指向类引用的指针,而不是类实例的指针。原来的void*存的是实例的地址,你把它转成ClassName*,相当于把实例地址当成了一个类引用变量的地址,后续如果解引用这个指针,拿到的会是一堆垃圾数据,大概率直接触发内存错误。
给你写个简单的验证代码,一看就懂:
class MyClass { int value; } void main() { auto myObj = new MyClass(); myObj.value = 100; // 正确的转换流程 void* rawPtr = cast(void*)myObj; auto restoredObj = cast(MyClass)rawPtr; assert(restoredObj.value == 100); // 完全正常 // 错误的转换方式,别这么干! auto wrongTypePtr = cast(MyClass*)rawPtr; // *wrongTypePtr 会是无效的引用,访问它的成员大概率崩掉 }
总结一下:记住D的类变量本身就是指针,转换的时候直接用类名作为cast的目标类型,别画蛇添足加个*,那样就变成指针的指针了,完全不是你要的东西。
内容的提问来源于stack exchange,提问作者porton
相关产品推荐
相关产品推荐

