You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何无需memcpy实现类型双关?类成员存地址的指针转换问题

问题分析与解决方案

首先明确核心问题:你混淆了变量自身的内存地址和变量存储的内容。

你的原代码逻辑是正确的:memcpy(&adress, &(this->failed), sizeof(void*)) 是把failed变量占用的字节(因为alignas(void*)保证它的大小和对齐都匹配void*)里存储的内容,复制到adress变量中,这个内容才是指向BaseA对象的地址。

而你尝试的错误写法:((BaseA*)&(this->failed))->failed,这里的&(this->failed)取的是failed这个bool变量自己的内存地址,把这个地址强制转换成BaseA*后访问failed成员,相当于去failed变量所在的内存位置找BaseA对象的failed成员,这和你实际想要的(读取failed变量里存的地址指向的BaseA对象)完全不是一回事,自然无法正常工作。

简洁的替代方案

方案1:使用reinterpret_cast直接解析变量内容

可以通过两次类型转换,直接读取failed变量存储的内容作为指针:

auto getFailed() {
    return reinterpret_cast<BaseA*>(*reinterpret_cast<void**>(&this->failed))->failed;
}
  • 第一步reinterpret_cast<void**>(&this->failed):把bool*类型的指针转换成void**,解引用后就能得到failed变量存储的void*地址值。
  • 第二步再把这个地址值转换成BaseA*,最后访问目标对象的failed成员。

方案2:C++20及以上使用std::bit_cast(更安全)

如果项目支持C++20,推荐用std::bit_cast做类型转换,它能保证按字节复制,避免未定义行为:

#include <bit>

auto getFailed() {
    void* target_addr = std::bit_cast<void*>(this->failed);
    return reinterpret_cast<BaseA*>(target_addr)->failed;
}

std::bit_cast会直接把failed变量的字节内容转换成void*类型,效果和原代码的memcpy完全一致,但写法更简洁。

方案3:使用union(兼容旧标准)

如果需要兼容C++20之前的版本,也可以用union实现类型转换:

union BoolToPtr {
    bool b;
    void* ptr;
};

auto getFailed() {
    BoolToPtr converter;
    converter.b = this->failed;
    return reinterpret_cast<BaseA*>(converter.ptr)->failed;
}

利用union的特性,同一个内存区域可以用不同类型访问,同样能读取failed变量存储的地址值。

内容的提问来源于stack exchange,提问作者Paul Gigel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 00:45:02