您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關深入淺析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?**
答案就是**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); }
為了優化目的,編譯器通常不能使用一致性進行優化。
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. }
如果聲明一個類成員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,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。