中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++11中std::addressof的用法

發布時間:2021-06-18 13:44:09 來源:億速云 閱讀:352 作者:chen 欄目:開發技術

本篇內容主要講解“C++11中std::addressof的用法”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“C++11中std::addressof的用法”吧!

目錄
  • 1、源碼準備

  • 2、std::addressof簡介

  • 3、std::addressof源碼解析

  • 4、總結

1、源碼準備

本文是基于gcc-4.9.0的源代碼進行分析,std::addressof是C++11才加入標準的,所以低版本的gcc源碼是沒有這個的,建議選擇4.9.0或更新的版本去學習,不同版本的gcc源碼差異應該不小,但是原理和設計思想的一樣的,下面給出源碼下載地址
http://ftp.gnu.org/gnu/gcc

2、std::addressof簡介

std::addressof的作用是獲取一個對象的實際地址,即使這個對象的&操作符已被重載。它接受一個參數,該參數為要獲得地址的那個對象的引用。下面通過一個極其簡單的例子了解一下std::addressof的使用方法

#include <iostream>
#include <string>
#include <functional>

class Test
{
public:
    int* operator&()
    {
        return &b;
    }

    int* a_addr()
    {
        return &a;
    }

    int* b_addr()
    {
        return &b;
    }

private:
    int a;
    int b;
};

int main(int argc, char* argv[])
{
    Test t;
    std::cout << "&t.a:" << t.a_addr() << std::endl;
    std::cout << "&t.b:" << t.b_addr() << std::endl;
    std::cout << "&t:" << &t << std::endl;
    std::cout << "addressof(t):" << std::addressof(t) << std::endl;
}

上面的代碼輸出結果為:

&t.a:0x7ffefcb48eb0
&t.b:0x7ffefcb48eb4
&t:0x7ffefcb48eb4
addressof(t):0x7ffefcb48eb0

在這里正常來說使用&t應該取到的是t.a的地址值才對,但是由于我們重載了&運算符,所以這里取到了t.b的地址值,但是如果使用了std::addressof,就可以取到正確的值了。

3、std::addressof源碼解析

std::addressof位于libstdc++-v3\include\bits\move.h中

template<typename _Tp>
inline _Tp* __addressof(_Tp& __r) _GLIBCXX_NOEXCEPT
{
    return reinterpret_cast<_Tp*>(&const_cast<char&>(reinterpret_cast<const volatile char&>(__r)));
}

template<typename _Tp>
inline _Tp* addressof(_Tp& __r) noexcept
{ return std::__addressof(__r); }

從代碼中可以看出std::addressof里面調用了std::__addressof,所以真正起作用的是std::__addressof。__addressof的處理過程可以分為以下四步:

  • 將__r由類型_Tp&強制轉換為const volatile char&,這樣做有兩個作用:一是防止后面使用&操作符獲取地址時觸發原類型(即_Tp)的重載操作(operator&),就像上面那個例子那樣;二是reinterpret_cast操作符總是可以合法的在原類型的基礎上加const或volatile, 但是如果_Tp原來就帶有const或volatile的話, 通過reinterpret_cast去掉是不允許的, 因此需要加上const volatile來避免編譯器報錯, 也就是此時不用再管_Tp是否本來就帶有const或volatile屬性了。

  • 將前面轉換得到的結果強制轉換為char&類型,此時如果轉換成其它類型有可能會觸發強制地址對齊的操作,這樣的話真實地址就有可能會被改變了,最終造成程序錯誤。需要注意的是這個轉換過程使用的是const_cast,可以順便將前面留下的const和volatile屬性給去掉了。

  • 使用&符號將前面的結果的地址給取出來(此時已經不會觸發重載了)

  • 最后一步使用reinterpret_cast將前面獲取到的地址轉換回_Tp*類型,并且此時也會保留_Tp的const或volatile屬性(如果有的話)

4、總結

本文通過一個簡單的例子和源碼介紹了C++11新引入的模板函數std::addressof,內容雖然比較簡單,但是考慮到std::addressof在標準庫中使用頻率是比較高的,所以我們還是應該掌握其原理和用法。

最后需要注意的一點就是std::addressof并不保證轉換的正確性和合理性,這個是需要程序員自己把控的,雖然標準庫使用std::addressof的頻率比較高,但是我們平時在編程中還是得謹慎一點使用它。

到此,相信大家對“C++11中std::addressof的用法”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

通化县| 营山县| 梅州市| 什邡市| 开鲁县| 荆州市| 湖口县| 巴彦县| 会东县| 朝阳市| 随州市| 嘉鱼县| 常德市| 阜新| 东乌珠穆沁旗| 鄂伦春自治旗| 明水县| 武陟县| 美姑县| 伊通| 虎林市| 磴口县| 扎鲁特旗| 民乐县| 洛川县| 通化市| 原阳县| 曲阳县| 邹平县| 汾阳市| 迭部县| 洪雅县| 湖南省| 嵊州市| 青海省| 宁明县| 屯留县| 麻江县| 涿州市| 宣汉县| 板桥市|