C++获取对象真实地址的方法

 更新时间:2025年10月15日 09:44:41   作者:liulilittle  
文章讨论了在C++中通过重载`operator&`后如何正确获取对象的内存地址,比较了两种方法:使用`std::addressof`和类型转换技巧,本文通过代码示例介绍的非常详细,需要的朋友可以参考下

问题背景

在 C++ 中,当类重载了 operator& 时,直接使用 & 运算符无法获取对象的真实内存地址,而是调用重载函数返回自定义值。

class TrickyClass {
public:
    int data;
    
    // 重载的 operator& 返回假地址
    TrickyClass* operator&() { 
        return reinterpret_cast<TrickyClass*>(0xDEADBEEF); 
    }
};

int main() {
    TrickyClass obj;
    TrickyClass* addr = &obj;  // 返回 0xDEADBEEF,不是真实地址!
}

解决方案对比

方法对比表

方法适用标准可靠性可读性推荐度
std::addressofC++11+⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
类型转换技巧C++98+⭐⭐⭐⭐⭐⭐⭐⭐⭐

技术原理剖析

1. std::addressof 实现原理

标准库实现通常如下:

template<typename T>
T* addressof(T& arg) noexcept {
    return reinterpret_cast<T*>(
        &const_cast<char&>(
            reinterpret_cast<const volatile char&>(arg)
        )
    );
}

2. 类型转换技巧解析

内存布局可视化

对象内存布局与地址获取

决策流程图

完整示例代码

#include <iostream>
#include <memory>  // 用于 std::addressof

// 重载了 operator& 的示例类
class TrickyClass {
public:
    int data{42};
    
    // 重载的 operator& 返回假地址
    TrickyClass* operator&() { 
        std::cout << "重载的 operator& 被调用\n";
        return reinterpret_cast<TrickyClass*>(0xDEADBEEF); 
    }
    
    // const 版本的重载
    const TrickyClass* operator&() const { 
        std::cout << "const 重载的 operator& 被调用\n";
        return reinterpret_cast<const TrickyClass*>(0xDEADBEEF); 
    }
};

// 获取真实地址的通用函数 (C++98 兼容)
template <typename T>
T* get_real_address(T& obj) {
    return reinterpret_cast<T*>(
        &const_cast<char&>(
            reinterpret_cast<const volatile char&>(obj)
        )
    );
}

int main() {
    TrickyClass obj;
    const TrickyClass const_obj;
    
    std::cout << "=== 错误方法 ===\n";
    std::cout << "&obj: " << &obj << " (错误地址!)\n";
    std::cout << "&const_obj: " << &const_obj << " (错误地址!)\n\n";
    
    std::cout << "=== 正确方法 ===\n";
    // 使用 std::addressof (C++11)
    std::cout << "std::addressof(obj): " << std::addressof(obj) << " (真实地址)\n";
    std::cout << "std::addressof(const_obj): " << std::addressof(const_obj) << " (真实地址)\n\n";
    
    // 使用类型转换技巧 (C++98 兼容)
    std::cout << "get_real_address(obj): " << get_real_address(obj) << " (真实地址)\n";
    std::cout << "get_real_address(const_obj): " << get_real_address(const_obj) << " (真实地址)\n";
    
    // 验证地址真实性
    std::cout << "\n=== 验证 ===\n";
    std::cout << "obj.data: " << obj.data << " (通过真实地址访问: ";
    std::cout << std::addressof(obj)->data << ")\n";
    
    return 0;
}

编译与运行

# 编译 (需要支持 C++11)
g++ -std=c++11 -o example example.cpp

# 运行
./example

预期输出

=== 错误方法 ===
重载的 operator& 被调用
&obj: 0xdeadbeef (错误地址!)
const 重载的 operator& 被调用
&const_obj: 0xdeadbeef (错误地址!)

=== 正确方法 ===
std::addressof(obj): 0x7ffd108a1b5c (真实地址)
std::addressof(const_obj): 0x7ffd108a1b60 (真实地址)

get_real_address(obj): 0x7ffd108a1b5c (真实地址)
get_real_address(const_obj): 0x7ffd108a1b60 (真实地址)

=== 验证 ===
obj.data: 42 (通过真实地址访问: 42)

关键总结

  1. 问题本质operator& 重载改变了 & 运算符的默认行为
  2. 解决方案
    • ✅ C++11+:优先使用 std::addressof
    • ✅ C++98:使用类型转换技巧
  3. 适用场景
    • 底层内存操作和调试
    • 与 C 语言库交互
    • 序列化和反序列化操作
  4. 注意事项
    • 类型转换技巧在极端情况下可能受对齐影响
    • std::addressof 是标准库实现,更加可靠

建议:在新项目中始终使用 std::addressof,在维护旧代码时根据需要选择合适方法。

以上就是C++获取对象真实地址的方法的详细内容,更多关于C++获取对象真实地址的资料请关注脚本之家其它相关文章!

相关文章

  • Opencv提取连通区域轮廓的方法

    Opencv提取连通区域轮廓的方法

    这篇文章主要为大家详细介绍了Opencv提取连通区域轮廓的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-01-01
  • 深入解析C++中的引用类型

    深入解析C++中的引用类型

    引用指的是对一个对象的引用。那么什么是对象?在c++中狭义的对象指的是用类,结构,联合等复杂数据类型来声明的变量,如 MyClass myclass,CDialog mydlg,等等
    2013-09-09
  • 详解C++的String类的字符串分割实现

    详解C++的String类的字符串分割实现

    这篇文章主要介绍了详解C++的String类的字符串分割实现的相关资料,需要的朋友可以参考下
    2017-07-07
  • C语言简明分析选择结构和循环结构的使用

    C语言简明分析选择结构和循环结构的使用

    C语言条件控制语句选择结构,是属于计算机的语言编辑,有在C语言条件控制中的语句选择结构的存在,即是C语言条件控制语句选择结构,循环控制语句是一个基于C语言的编程语句,该语句主要有while循环语句、do-while循环语句和for循环语句来实现循环结构
    2022-04-04
  • C/C++ memset方法的误区

    C/C++ memset方法的误区

    memset 作为对内存初始化的函数,还是有不少坑和误区的,今天就来对这个函数作一个总结。避免后期使用不当踩入坑,需要的朋友可以参考下
    2021-04-04
  • 详解C语言之操作符

    详解C语言之操作符

    这篇文章主要以图文结合的方式为大家详细介绍了C语言的操作符知识,感兴趣的小伙伴们可以参考一下,希望能给你带来帮助
    2021-11-11
  • C++实现学生管理系统示例解析

    C++实现学生管理系统示例解析

    这篇文章主要介绍了C++实现学生管理系统示例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • C语言实现数组栈的代码示例

    C语言实现数组栈的代码示例

    栈是一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作,进行数据插入和删除操作的一端称为栈顶,另一端称为栈底,本文给大家介绍了C语言实现数组栈的代码示例,需要的朋友可以参考下
    2024-07-07
  • C语言十进制转二进制代码实例

    C语言十进制转二进制代码实例

    这篇文章主要介绍了C语言十进制转二进制代码实例,并且转换后会统计二进制1的个数,实例简单明了,需要的朋友可以参考下
    2014-06-06
  • C++实现堆排序示例

    C++实现堆排序示例

    这篇文章主要介绍了C++实现堆排序示例,全文运用大量代码完成堆排序,需要了解的朋友可以参考一下这篇文章
    2021-08-08

最新评论