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

溫馨提示×

溫馨提示×

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

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

深入淺析C++中的const

發布時間:2020-11-18 15:16:00 來源:億速云 閱讀:145 作者:Leah 欄目:開發技術

本篇文章給大家分享的是有關深入淺析C++中的const,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

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

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

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

可以通過例子來看下const的應用。第一個例子中,使用const覆蓋了整個例子:

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

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

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

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

如果一個變量定義在ROM中,對它的寫操作很可能會使程序崩潰,這取決于平臺。如果一個變量不在ROM中,對它的寫操作只會改變它的值。這兩種情況的結合就是為什么對const變量執行寫操作的行為是未定義行為而不是錯誤。

如果真的需要改寫一個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的變量時永遠不會遭遇未定義行為的陷阱。

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

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

**那么,究竟在什么時候什么地方使用const&#63;**

答案就是**Everywhere**。將每個變量聲明為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);
}

優化器視角下的const

為了優化目的,編譯器通常不能使用一致性進行優化。

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

此時,在這些函數參數中使用const對優化器沒有幫助。x上的const不起作用,因為x已經通過引用傳遞了。沒有x的副本,編譯器不知道x是否聲明為const。在參數at上的const不能幫助我們,因為at是一個拷貝,它可以以任何方式裝入寄存器。
如果編譯器可以看到const對象的聲明,它有時可以使用其一致性進行優化。

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];
}

如果您想保證這樣的優化,您可以在c++11或以后的版本中使用constexpr。使用constexpr聲明的變量只對可以靜態初始化的類型進行編譯,因此,如果編譯了它,就會得到一個ROM-able的對象。

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或其他整數值都可以像文字一樣使用。

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.
}

靜態const類成員

如果聲明一個類成員static const,就很像聲明一個全局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 {}; }

但因為這是c++,所以有個問題。如果定義的static const整數值超越界限,則它可能無法被當作字面常量使用,例如一下的例子。

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;

這是的錯誤時因為編譯器在解析foo()時不知道要為my_class::size使用什么值。如果你希望像使用全局const整數值一樣使用static const整數值,請始終將它們聲明為內聯(inline)。

以上就是深入淺析C++中的const,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

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

AI

汝南县| 大丰市| 西安市| 宁国市| 昌图县| 马公市| 永州市| 汉沽区| 双鸭山市| 雷山县| 博罗县| 文化| 调兵山市| 五河县| 牙克石市| 大同县| 青冈县| 洞口县| 黔江区| 山阴县| 金秀| 来凤县| 乌兰察布市| 鹤岗市| 金门县| 金平| 东光县| 钦州市| 娄烦县| 兴海县| 左权县| 文成县| 白水县| 宣恩县| 德清县| 岑溪市| 鹤山市| 和龙市| 北流市| 沭阳县| 红桥区|