C++11 addressof()函数(模板函数)(在对象重载了取地址运算符时,获取对象真实地址)

news/2025/2/7 14:15:51/

文章目录

    • addressof模板函数
    • 在对象重载了取地址运算符,addressof函数模板就能发挥作用

addressof模板函数

C++中的addressof函数是一个模板函数,定义在头文件<memory>中。它的作用是获取一个对象的地址,与C++中的取地址符&类似,但是addressof函数可以获取一些特殊类型的对象的地址,比如重载了取地址符的类对象、位域、临时对象等。

addressof函数的定义如下:

template <typename T>
T* addressof(T& arg) noexcept;

其中,arg是要获取地址的对象的引用,noexcept表示该函数不会抛出异常。

addressof函数的实现原理是通过指针运算来获取对象的地址,而不是通过取地址符&来获取。这样做的好处是可以避免一些编译器的优化,比如将取地址符&优化为不需要取地址的操作。

需要注意的是,addressof函数只能获取可寻址的对象的地址,即不能获取无法取地址的对象的地址,比如字面量、字符串常量等。

下面是一个使用addressof函数的例子:

#include <iostream>
#include <memory>struct A
{int x;
};int main()
{A a{10};A *p = std::addressof(a);A *pp = &a;std::cout << p << std::endl;  // 0x7fffffffdf24std::cout << pp << std::endl; // 0x7fffffffdf24std::cout << p->x << std::endl;  // 10std::cout << pp->x << std::endl; // 10return 0;
}

在上面的例子中,我们定义了一个结构体A,并创建了一个A类型的对象a,然后使用addressof函数获取了a的地址,并将其赋值给指针p,最后输出了p所指向的对象的成员变量x的值。

在对象重载了取地址运算符,addressof函数模板就能发挥作用

std::addressof 是一个函数模板,它返回一个指向其参数的地址的指针。与取地址符号 & 不同的是,std::addressof 保证返回的指针是真正的指向其参数的地址,即使其参数是一个重载了取地址运算符的类类型对象。

例如,考虑以下代码:

#include <iostream>
#include <memory>
using namespace std;struct S
{int x;int *operator&(){return nullptr;}
};int main()
{S s;int *p1 = &s.x;                // 取地址符号int *p2 = std::addressof(s.x); // std::addressofint *p3 = &s;                  // 无法取得 s 的地址,因为 S 重载了取地址运算符S *p4 = std::addressof(s);     // 正确,返回指向 s 的地址的指针cout << p1 << endl; // 0x7fffffffdf14cout << p2 << endl; // 0x7fffffffdf14cout << p3 << endl; // 0cout << p4 << endl; // 0x7fffffffdf14
}

在上面的代码中,p1p2 都指向 s.x 的地址,但是 p3 无法取得 s 的地址,因为 S 重载了取地址运算符。而 p4 使用 std::addressof 可以正确地返回指向 s 的地址的指针。


http://www.ppmy.cn/news/100404.html

相关文章

PAT A1160 Forever

1160 Forever 分数 20 作者 陈越 单位 浙江大学 "Forever number" is a positive integer A with K digits, satisfying the following constrains: the sum of all the digits of A is m;the sum of all the digits of A1 is n; andthe greatest common diviso…

ISP:接口隔离原则

系列文章目录 C高性能优化编程系列 深入理解设计原则系列 深入理解设计模式系列 高级C并发线程编程 LSP&#xff1a;接口隔离原则 系列文章目录1、接口隔离原则的定义和解读如何判断一个接口是否符合接口隔离原则&#xff1f;小结 1、接口隔离原则的定义和解读 Robert Marti…

【Python】Python中列表的操作方法

Python中列表的操作 Python中的列表是用来存储一系列元素的有序集合。列表是可变的&#xff0c;这意味着我们可以添加、删除或修改列表中的元素。本文将介绍Python中列表的基本操作&#xff0c;包括创建列表、访问列表元素、添加元素、删除元素和列表切片, 反转等。 访问列表…

queue的模拟实现

前言 queue作为STL中的容器适配器&#xff0c;在底层是通过一系列的成员函数来调用其他容器的接口实现的 &#xff0c;它其实就是将其他模板容器进行封装从而实现它&#xff0c;先进先出的特性的。 目录 1.queue的接口说明 2.queue的模拟实现 2.1模拟实现代码 2.1测试代码 …

MATLAB算法实战应用案例精讲-【数模应用】残差检验(附Java、python和MATLAB代码)

目录 几个高频面试题目 线性回归残差是否一定满足正态分布? 一般情况 特殊情况

(c语言)将一句话的单词进行倒置,标点不倒置(i like beijing.)

目录 例子&#xff1a; 思路方法&#xff1a; ​编辑 &#xff08;分板块&#xff09;代码的实现&#xff1a; 一.字符串的获取&#xff08;3种简单的方法&#xff09; 1.用gets&#xff08;&#xff09;函数&#xff0c;即使中间有空格也会读取 2.用fgets&#xff08;&am…

Java轻量级全文检索引擎Lucene使用及优化

Java轻量级全文检索引擎Lucene使用及优化 一、简介1. Lucene 简介2. Lucene 应用领域和使用场景3. Lucene 到底是一个什么样的工具 二、Lucene快速入门1. Lucene 的基本原理和架构2. Lucene 常用 API3. 创建索引并执行检索操作创建索引执行搜索 三、Lucene 使用详解1. 数据类型…

第 2 章:Vue 组件化编程

目录 模块与组件、模块化与组件化 模块 组件 模块化 组件化 非单文件组件 小结 组件的几个注意点 组件的嵌套 VueComponent构造函数 小结 一个重要的内置关系 小结 单文件组件 一个.vue 文件的组成(3 个部分) 1. 模板页面 2. JS 模块对象 3. 样式 基本使用 模…