文章目录
- 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
}
在上面的代码中,p1
和 p2
都指向 s.x
的地址,但是 p3
无法取得 s 的地址,因为 S
重载了取地址运算符。而 p4
使用 std::addressof
可以正确地返回指向 s
的地址的指针。