欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一文讓你徹底明白C++中的const

 更新時(shí)間:2020年11月17日 14:53:54   作者:focuscode  
這篇文章主要給大家介紹了關(guān)于C++中const的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

在抽象的最高層次上,const做兩件事:

* 一種保護(hù)你自己的方式(類似于private)

* 對(duì)編譯器的一種指示,表明標(biāo)記為const的對(duì)象適合于程序的數(shù)據(jù)段。換句話說,屬于只讀數(shù)據(jù)(ROM-able)。

可以通過例子來看下const的應(yīng)用。第一個(gè)例子中,使用const覆蓋了整個(gè)例子:

void fun(int i, std::string const & str)
{
 i = 0;     //ok.
 str = "";    //error!
 int const n = 42;
 n = 2;     //error!
}

第二種情況只適用于靜態(tài)初始化的名稱空間-作用域變量(又稱全局變量):

int const pi = 3; //ROM-able
std::vector<int> const ivec = {/* ... */}; //Not ROM-able, might allocate.

對(duì)聲明為const的變量的任何寫操作都被顯示為未定義行為。這支持const全局變量在ROM中的位置。

如果一個(gè)變量定義在ROM中,對(duì)它的寫操作很可能會(huì)使程序崩潰,這取決于平臺(tái)。如果一個(gè)變量不在ROM中,對(duì)它的寫操作只會(huì)改變它的值。這兩種情況的結(jié)合就是為什么對(duì)const變量執(zhí)行寫操作的行為是未定義行為而不是錯(cuò)誤。

如果真的需要改寫一個(gè)const變量的值,可以通過`const_cast`來改寫:

void fun(int i, std::string const & str)
{
 i = 0; //ok.
 const_cast<std::string &>(str) = ""; //Also ok (maybe).
}

然而,const_cast并不能避免你在嘗試寫入聲明為const的變量時(shí)永遠(yuǎn)不會(huì)遭遇未定義行為的陷阱。

std::string str = "";
fun(0, str); // Ok.
std::string const const_str = "";
fun(0, const_str); // Undefined Behavior!!

因此,只有在確實(shí)需要時(shí)才使用const_cast,并且只有在知道要寫入的底層變量是如何聲明的情況下才使用。

**那么,究竟在什么時(shí)候什么地方使用const?**

答案就是**Everywhere**。將每個(gè)變量聲明為const,除非您知道它將被寫入。更一般地,在編譯器接受的任何地方添加const。

int foo(int arg)
{
 int const x = compute_intermediate_result(arg);
 int const y = compute_other_intermediate_result(x);
 return something_computed_from(x, y);
}

優(yōu)化器視角下的const

為了優(yōu)化目的,編譯器通常不能使用一致性進(jìn)行優(yōu)化。

int get_value(some_class const & x, int const at)
{
 int offset = compute_offset(at);
 return x[offset];
}

此時(shí),在這些函數(shù)參數(shù)中使用const對(duì)優(yōu)化器沒有幫助。x上的const不起作用,因?yàn)閤已經(jīng)通過引用傳遞了。沒有x的副本,編譯器不知道x是否聲明為const。在參數(shù)at上的const不能幫助我們,因?yàn)閍t是一個(gè)拷貝,它可以以任何方式裝入寄存器。
如果編譯器可以看到const對(duì)象的聲明,它有時(shí)可以使用其一致性進(jìn)行優(yōu)化。

std::vector<int> const vec = { 1, 2, 3 };

int main()
{
 // This may generate code that indexes into vec, or it may generate
 // code that loads an immediate 2.
 return vec[1];
}

如果您想保證這樣的優(yōu)化,您可以在c++11或以后的版本中使用constexpr。使用constexpr聲明的變量只對(duì)可以靜態(tài)初始化的類型進(jìn)行編譯,因此,如果編譯了它,就會(huì)得到一個(gè)ROM-able的對(duì)象。

constexpr std::array<int, 3> arr = { 1, 2, 3 };

int main()
{
 // This generates code that loads an immediate 2 on every
 // compiler I tried.
 return arr[1];
}

constexpr只處理字面常量類型(literal types)。這些類型與你可能在C中找到的類型相似。任何被聲明為const的int或其他整數(shù)值都可以像文字一樣使用。

void foo(int const arg)
{
 int const size = 2; 

 int array_0[2];  // Ok.
 int array_1[arg]; // Error! arg is a runtime value.
 int array_2[size]; // Ok.
}

靜態(tài)const類成員

如果聲明一個(gè)類成員static const,就很像聲明一個(gè)全局const變量。

int const global_size = 3;

struct my_struct
{
 static int const size = 2;
};

std::array<int, global_size> make_global_array()
{ return {}; }

std::array<int, my_struct::size> make_my_struct_array()
{ return {}; }

但因?yàn)檫@是c++,所以有個(gè)問題。如果定義的static const整數(shù)值超越界限,則它可能無法被當(dāng)作字面常量使用,例如一下的例子。

struct my_struct
{
 static int const size;
};

std::array<int, my_struct::size> make_my_struct_array() // Error!
{ return {}; }

int const my_struct::size = 2;

這是的錯(cuò)誤時(shí)因?yàn)榫幾g器在解析foo()時(shí)不知道要為my_class::size使用什么值。如果你希望像使用全局const整數(shù)值一樣使用static const整數(shù)值,請(qǐng)始終將它們聲明為內(nèi)聯(lián)(inline)。

總結(jié)

到此這篇關(guān)于C++中const的文章就介紹到這了,更多相關(guān)C++中的const內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

1. Use const to protect yourself from silly mistakes, and use it everywhere.

2. You can use const on globals that you want in ROM, but prefer constexpr.

3. Use const_cast sparingly, or not at all.

4. When you do use const_cast, be careful of the UB that might result, including crashes.

5. Use const globals and stack variables instead of macros for named values that are "as good as literals".

6. Define static const integral data members inline, if possible.

相關(guān)文章

  • ubuntu中打開終端的三種解決方法

    ubuntu中打開終端的三種解決方法

    本篇文章是對(duì)ubuntu中打開終端的三種方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • 利用c++和easyx圖形庫做一個(gè)低配版掃雷游戲

    利用c++和easyx圖形庫做一個(gè)低配版掃雷游戲

    這篇文章主要介紹了用c++和easyx圖形庫做一個(gè)低配版掃雷游戲,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-01-01
  • C語言for語句用法詳解

    C語言for語句用法詳解

    今天,小編講訴C語言中循環(huán)語句(for)的使用方法,作為示例,以一個(gè)簡單的例子講訴for語法。
    2015-11-11
  • C++多線程std::call_once的使用

    C++多線程std::call_once的使用

    本文主要介紹了C++多線程std::call_once的使用,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Windows環(huán)境給FFmpeg集成AVS3解碼器

    Windows環(huán)境給FFmpeg集成AVS3解碼器

    libuavs3d是AVS3標(biāo)準(zhǔn)的解碼器,支持windows/linux/arm/ios等所有常用平臺(tái),在移動(dòng)端最高支持4K/30fps視頻實(shí)時(shí)解碼,解碼速度大幅領(lǐng)先AV1開源解碼器dav1d和aomdec,由于FFmpeg默認(rèn)未啟用libuavs3d,因此需要重新配置FFmpeg,標(biāo)明啟用libuavs3d,然后重新編譯安裝FFmpeg
    2024-05-05
  • 淺談c++調(diào)用python鏈接的問題及解決方法

    淺談c++調(diào)用python鏈接的問題及解決方法

    下面小編就為大家?guī)硪黄獪\談c++調(diào)用python鏈接的問題及解決方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-03-03
  • C++中malloc與free、new與delete的詳解與應(yīng)用

    C++中malloc與free、new與delete的詳解與應(yīng)用

    今天小編就為大家分享一篇關(guān)于C++中malloc與free、new與delete的詳解與應(yīng)用,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • 基于Qt的TCP實(shí)現(xiàn)通信

    基于Qt的TCP實(shí)現(xiàn)通信

    這篇文章主要為大家詳細(xì)介紹了基于Qt的TCP實(shí)現(xiàn)通信,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • C語言strtod()函數(shù)案例詳解

    C語言strtod()函數(shù)案例詳解

    這篇文章主要介紹了C語言strtod()函數(shù)案例詳解,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C++中 string 中的常用方法使用心得

    C++中 string 中的常用方法使用心得

    這篇文章主要介紹了C++中 string 中的常用方法使用心得,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-03-03

最新評(píng)論