c++關鍵字:const、constexpr、auto、decltype


const關鍵字

const修飾的對象一旦創建后其值就不能再改變,所以const修飾的對象必須初始化

用法:

  1. 定義常量對象,被const修飾的對象不能被更改

    const int i = 42;			//正確,編譯時初始化
    const int j = get_size();	//正確,編譯時初始化
    const int l;				//錯誤,l未經初始化
    
  2. 默認狀態下,const對象僅在文件內有效,要想在多個文件直接共享const對象,必須在變量的定義之前添加extern關鍵字

  3. 可以把引用綁定到const對象上,我們稱之為對常量的引用。對常量的引用不能修改所綁定的對象

    const int ci = 1024;	
    const int &r1 = ci;		//正確,引用及其引用的對象都是常量
    r1 = 2048;				//錯誤,r1是對常量的引用,不能修改
    int &r2 = ci;			//錯誤,r2是非常量引用,不能指向一個常量對象
    

    對const的引用可能引用一個並非const的對象

    int i = 42;			
    int &r1 = i;		//引用r1綁定1
    const int &r2 = i;	//r2也綁定對象i,但是不允許通過r2改變i的值
    r1 = 0;				//正確
    r2 = 0;				//錯誤
    
  4. 和引用一樣,可以將指針指向常量或者非常量。同時指針也是對象,因此指針也可以被const修飾。常量指針必須初始化,並且之后它的值就不能再更改了,把*放在const之前表示指針是一個常量

    const double pi = 3.14;			//pi是一個常量
    double *ptr = pi;				//錯誤,普通指針不能指向常量
    const double *cptr = π		//正確,cptr可以指向一個double的常量
    *cptr = 42;						//錯誤,不能給*cptr賦值
    
    int errNumb = 0;
    int *const curErr = &errNumb;		//curErr將一直指向errNumb
    const double pi = 3.14159;
    const double *const pip = π		//pip是一個指向常量對象的常量指針
    
  5. 我們用頂層cost表示任意的對象是常量,底層const則表示指針和引用復合類型的基本類型部分有關

    int i = 0;
    int *const p1 = &i;			//不能改變p1的值,頂層const
    const int ci = 42;			//不能改變ci的值,頂層const
    const int *p2 = &ci;		//可以改變p2的值,底層const
    const int *const p3 = p2;	//即是頂層const又是底層const
    const int &r = ci;			//對於引用的聲明都是底層const
    

constexpr關鍵字

constexpr是C++11新引入的關鍵字,用來表示常量表達式。常量表達式是指值不會改變,並且在編譯過程中就能得到計算結果的表達式。constexpr限定在了編譯期就要初始化,const是可以再運行時初始化的。

int foo()
{
    return 5;
}
int main()
{
    const int p1 = foo();		//正確	
    constexpr int p2 = foo();	//錯誤,表達式必須含有常量值,無法調用非 constexpr 函數
}

constexpr只能定義字面值類型,如算術類型,指針和引用。而類似IO庫,string類型則不屬於字面值類型,也就不能被定義為constexpr。

盡管指針和引用可以被定義為constexpr,但是他們的初始值必須為nullptr或者0,或者是存儲於某個固定地址中的對象。

auto和decltype關鍵字

auto和decltype關鍵字都可以進行類型推導,可以在編譯期就推導出變量或者表達式所屬的類型。

  • auto類型說明符:讓編譯器在編譯期通過初始值推算變量的類型。在一條語句聲明多個變量時,基礎數據類型必須一樣

    auto i = 0, *p = &i;		//正確,i為整型,p為整型指針
    auto sz = 0, pi = 3.14;		//錯誤,sz為整型,pi為雙精度浮點數
    

    在不聲明的情況下,編譯器會以引用對象的類型作為auto的類型。

    auto也會忽略頂層const,保留底層const

    int i = 0, &r = i;
    auto a = r;		//a是int
    
    const int ci = i, &cr = ci;
    auto b = ci;	//b是int
    auto c = cr;	//c是int
    auto d = &i;	//d是int*
    auto e = &ci;	//e是一個const int*
    
    
  • decltype類型說明符:用於編譯器推導表達式類型,表達式並不會進行實際上的運算

    decltype(exp) i;	
    //exp可以是表達式,也可以是函數調用,這時候i是表達式的類型或者函數調用的返回值
    //其他情況,若exp為左值,decltype(exp)是exp類型的左值引用
    

    與auto不同,對於頂層const的處理不相同

    const int ci = 0, &cj = ci;
    auto x = ci;			//x是int
    decltype(ci) y = ci;	//y是const int
    auto z = cj;			//z是int
    auto az = &cj;			//az是const int*
    decltype(cj) cz = cj;	//cz是const int&
    

    當exp是加了括號的變量,結果將是引用

    int i = 42;
    decltype((i)) d;	//錯誤,d是int&,必須初始化
    decltype(i)	e;		//正確,e是未初始化的int
    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM