美文网首页
addressof函数

addressof函数

作者: hades2013 | 来源:发表于2018-10-22 14:42 被阅读0次

addressof()的实现原理,实际是一个cast trick,c++标准中有如下的规定:

An lvalue expression of type T1 can be cast to the type “reference to T2” if an expression of type “pointer
to T1” can be explicitly converted to the type “pointer to T2” using a reinterpret_cast. That is, a
reference cast reinterpret_cast<T&>(x) has the same effect as the conversion
reinterpret_cast<T>(&x) with the built-in & and * operators. The result is an lvalue that refers
to the same object as the source lvalue, but with a different type. No temporary is created, no copy is made,
and constructors (12.1) or conversion functions (12.3) are not called.67) (ISO/IEC 14882:2003(E) 5.2.10 Reinterpret cast)

大体意思就是如果一个指向T1类型的指针可以通过reinterpret_cast明确的转换成一个指向T2类型的指针,那么类型为T1的左值表达式就可以强制转化成一个T2类型的引用,也就是说cast reinterpret_cast<T&>(x)和reinterpret_cast<T>(&x)是等价的,前提是在内建&和语意下。c++
标准还强调,上述的转换结果是一个左值,和被转换的源左值引用着同一个对象,只是类型不同而已,也就是说c++标准保证,如果一个T1类型的对象x,被强制转换成了一个T2类型引用,那么T2引用是引用着T1对象,想当于
reinterpret_cast<T2*>(&x) 。
所以说addressof()函数的实现是基于上述规定的。

#include "addressof.hpp"
#include <iostream>
#include <memory> // std::addressof

// Blog: http://blog.csdn.net/fengbingchun/article/details/70406274

////////////////////////////////////////////////////////////////
// reference: http://en.cppreference.com/w/cpp/memory/addressof
template<class T>
struct Ptr {
    T* pad; // add pad to show difference between 'this' and 'data'
    T* data;
    Ptr(T* arg) : pad(nullptr), data(arg)
    {
        std::cout << "Ctor this = " << this << std::endl;
    }

    ~Ptr() { delete data; }
    T** operator&() { return &data; }
};

template<class T>
void f(Ptr<T>* p)
{
    std::cout << "Ptr   overload called with p = " << p << '\n';
}

void f(int** p)
{
    std::cout << "int** overload called with p = " << p << '\n';
}

int test_addressof_1()
{
    Ptr<int> p(new int(42));
    f(&p);                 // calls int** overload
    f(std::addressof(p));  // calls Ptr<int>* overload, (= this)

    return 0;
}

////////////////////////////////////////////////////////////
// reference: http://www.cplusplus.com/reference/memory/addressof/
struct unreferenceable {
    int x;
    unreferenceable* operator&() { return nullptr; }
};

void print(unreferenceable* m) {
    if (m) std::cout << m->x << '\n';
    else std::cout << "[null pointer]\n";
}

int test_addressof_2()
{
    void(*pfn)(unreferenceable*) = &print; // void(*pfn)(unreferenceable*); pfn = &print;

    unreferenceable val{ 10 };
    unreferenceable* foo = &val;
    unreferenceable* bar = std::addressof(val);

    (*pfn)(foo);   // prints [null pointer]
    (*pfn)(bar);   // prints 10

    return 0;
}

/////////////////////////////////////////////////////////
// reference: http://cppisland.com/?p=414
class Buffer
{
private:
    static const size_t buffer_size = 256;
    int bufferId;
    char buffer[buffer_size];

public:
    Buffer(int bufferId_) : bufferId(bufferId_) {}
    Buffer* operator&() { return reinterpret_cast<Buffer*> (&buffer); }  //BAD practice, only for illustration!
};

template<typename T>
void getAddress(T t)
{
    std::cout << "Address returned by & operator: " << std::ios::hex << &t << "\n";
    std::cout << "Address returned by addressof: " << std::ios::hex << std::addressof(t) << "\n";
}

int test_addressof_3()
{
    int a = 3;
    fprintf(stderr, "a &: %p, address of: %p\n", &a, std::addressof(a));

    Buffer b(1);
    std::cout << "Getting the address of a Buffer type: \n";
    getAddress(b);

    return 0;
}

/////////////////////////////////////////////////////////
// reference: https://wizardforcel.gitbooks.io/beyond-stl/content/38.html
class codebreaker {
public:
    int operator&() const {
        return 13;
    }
};

int test_addressof_4()
{
    codebreaker c;

    std::cout << "&c: " << (&c) << '\n';
    std::cout << "addressof(t): " << std::addressof(c) << '\n';

    return 0;
}

相关文章

  • addressof函数

    addressof()的实现原理,实际是一个cast trick,c++标准中有如下的规定: An lvalue ...

  • Excel(三)

    AND函数 OR函数 NOT函数 IF函数 频率分析函数FREQUENCY

  • if、else if、for、while、repeat函数

    ①if函数 ②else if函数 ③for函数 ④while函数 ⑤repeat函数

  • strsplit、mapply、paste、match函数

    strsplit函数 mapply函数 strsplit函数 mapply函数 paste函数 match函数 第...

  • Oracle中常用函数(SQL)

    Oracle函授有以下几个分类:数字函数、字符函数、日期函数、转换函数、集合函数、分析函数 数字函数: 字符函数:...

  • MySQL函数

    字符函数 数字运算函数 比较运算符和函数 日期时间函数 信息函数 聚合函数 加密函数 流程函数

  • BI-SQL丨AND & OR & IN

    AND函数 & OR函数 & IN函数 AND函数、OR函数和IN函数都可以理解是WHERE函数的补充,当然也可以...

  • Python之函数

    课程大纲 函数定义 函数的参数 函数的返回值 高阶函数 函数作用域 递归函数 匿名函数 内置函数 函数式编程 将函...

  • 函数基本知识

    函数 函数的定义: def 函数名() 函数的调用:函数名() #不能将函数调用放在函数定义上方 函数的文档注...

  • 积分表——不定期更新

    基本初等函数包括: 常函数: 幂函数 指数函数 对数函数 三角函数 反三角函数 I、反函数Ⅱ、复合函数:初等函数(...

网友评论

      本文标题:addressof函数

      本文链接:https://www.haomeiwen.com/subject/vvlgzftx.html