日本免费精品_最新日韩一区_亚洲视频一区在线_a在线视频观看_天天射夜夜骑_粉嫩av一区二区三区_欧美中日韩免费视频_综合图区欧美_国内精品美女在线观看_午夜精品久久久久久久男人的天堂

首頁 > 編程 > C++ > 正文

C++中的const和constexpr詳解

2020-05-23 14:11:19
字體:
來源:轉載
供稿:網友
C++ const 和 constexpr 的區別呢,constexpr表示這玩意兒在編譯期就可以算出來(前提是為了算出它所依賴的東西也是在編譯期可以算出來的)。而const只保證了運行時不直接被修改(但這個東西仍然可能是個動態變量)。下面我們來詳細講解下。
 

C++中的const可用于修飾變量、函數,且在不同的地方有著不同的含義,現總結如下。

const的語義

C++中的const的目的是通過編譯器來保證對象的常量性,強制編譯器將所有可能違背const對象的常量性的操作都視為error。

對象的常量性可以分為兩種:物理常量性(即每個bit都不可改變)和邏輯常量性(即對象的表現保持不變)。C++中采用的是物理常量性,例如下面的例子:

struct A {  int *ptr;};int k = 5, r = 6;const A a = {&k};a.ptr = &r; // !error*a.ptr = 7; // no error

a是const對象,則對a的任何成員進行賦值都會被視為error,但如果不改動ptr,而是改動ptr指向的對象,編譯器就不會報錯。這實際上違背了邏輯常量性,因為A的表現已經改變了!

邏輯常量性的另一個特點是,const對象中可以有某些用戶不可見的域,改變它們不會違背邏輯常量性。Effective C++中的例子是:

class CTextBlock { public:   ...   std::size_t length() const; private:   char *pText;   std::size_t textLength;      // last calculated length of textblock   bool lengthIsValid;        // whether length is currently valid };

CTextBlock對象每次調用length方法后,都會將當前的長度緩存到textLength成員中,而lengthIsValid對象則表示緩存的有效性。這個場景中textLength和lengthIsValid如果改變了,其實是不違背CTextBlock對象的邏輯常量性的,但因為改變了對象中的某些bit,就會被編譯器阻止。C++中為了解決此問題,增加了mutable關鍵字。

本部分總結:C++中const的語義是保證物理常量性,但通過mutable關鍵字可以支持一部分的邏輯常量性。

const修飾變量

如上節所述,用const修飾變量的語義是要求編譯器去阻止所有對該變量的賦值行為。因此,必須在const變量初始化時就提供給它初值:

const int i;i = 5; // !errorconst int j = 10; // ok

這個初值可以是編譯時即確定的值,也可以是運行期才確定的值。如果給整數類型的const變量一個編譯時初值,那么可以用這個變量作為聲明數組時的長度:

const int COMPILE_CONST = 10;const int RunTimeConst = cin.get();int a1[COMPLIE_CONST]; // ok in C++ and error in Cint a2[RunTimeConst]; // !error in C++

因為C++編譯器可以將數組長度中出現的編譯時常量直接替換為其字面值,相當于自動的宏替換。(gcc驗證發現,只有數組長度那里直接做了替換,而其它用COMPILE_CONST賦值的地方并沒有進行替換。)

文件域的const變量默認是文件內可見的,如果需要在b.cpp中使用a.cpp中的const變量M,需要在M的初始化處增加extern:

//a.cppextern const int M = 20; //b.cppextern const int M;

一般認為將變量的定義放在.h文件中會導致所有include該.h文件的.cpp文件都有此變量的定義,在鏈接時會造成沖突。但將const變量的定義放在.h文件中是可以的,編譯器會將這個變量放入每個.cpp文件的匿名namespace中,因而屬于是不同變量,不會造成鏈接沖突。(注意:但如果頭文件中的const量的初始值依賴于某個函數,而每次調用此函數的返回值不固定的話,會導致不同的編譯單元中看到的該const量的值不相等。猜測:此時將該const量作為某個類的static成員可能會解決此問題。)

const修飾指針與引用

const修飾引用時,其意義與修飾變量相同。但const在修飾指針時,規則就有些復雜了。

簡單的說,可以將指針變量的類型按變量名左邊最近的‘*'分成兩部分,右邊的部分表示指針變量自己的性質,而左邊的部分則表示它指向元素的性質:

const int *p1; // p1 is a non-const pointer and points to a const intint * const p2; // p2 is a const pointer and points to a non-const intconst int * const p3; // p3 is a const pointer and points to a const itconst int *pa1[10]; // pa1 is an array and contains 10 non-const pointer point to a const intint * const pa2[10]; // pa2 is an array and contains 10 const pointer point to a non-const intconst int (* p4)[10]; // p4 is a non-const pointer and points to an array contains 10 const intconst int (*pf)(); // pf is a non-const pointer and points to a function which has no arguments and returns a const int...

const指針的解讀規則差不多就是這些了……

指針自身為const表示不可對該指針進行賦值,而指向物為const則表示不可對其指向進行賦值。因此可以將引用看成是一個自身為const的指針,而const引用則是const Type * const指針。

指向為const的指針是不可以賦值給指向為非const的指針,const引用也不可以賦值給非const引用,但反過來就沒有問題了,這也是為了保證const語義不被破壞。

可以用const_cast來去掉某個指針或引用的const性質,或者用static_cast來為某個非const指針或引用加上const性質:

int i;const int *cp = &i;int *p = const_cast<int *>(cp);const int *cp2 = static_cast<const int *>(p); // here the static_cast is optional

C++類中的this指針就是一個自身為const的指針,而類的const方法中的this指針則是自身和指向都為const的指針。

類中的const成員變量

類中的const成員變量可分為兩種:非static常量和static常量。

非static常量:
類中的非static常量必須在構造函數的初始化列表中進行初始化,因為類中的非static成員是在進入構造函數的函數體之前就要構造完成的,而const常量在構造時就必須初始化,構造后的賦值會被編譯器阻止。

class B {public:  B(): name("aaa") {    name = "bbb"; // !error  }private:  const std::string name;};

static常量:
static常量是在類中直接聲明的,但要在類外進行唯一的定義和初始值,常用的方法是在對應的.cpp中包含類的static常量的定義:

// a.hclass A {  ...  static const std::string name;}; // a.cppconst std::string A::name("aaa");

一個特例是,如果static常量的類型是內置的整數類型,如char、int、size_t等,那么可以在類中直接給出初始值,且不需要在類外再進行定義了。編譯器會將這種static常量直接替換為相應的初始值,相當于宏替換。但如果在代碼中我們像正常變量那樣使用這個static常量,如取它的地址,而不是像宏一樣只使用它的值,那么我們還是需要在類外給它提供一個定義,但不需要初始值了(因為在聲明處已經有了)。

// a.hclass A {  ...  static const int SIZE = 50; }; // a.cppconst int A::SIZE = 50; // if use SIZE as a variable, not a macro

const修飾函數

C++中可以用const去修飾一個類的非static成員函數,其語義是保證該函數所對應的對象本身的const性。在const成員函數中,所有可能違背this指針const性(const成員函數中的this指針是一個雙const指針)的操作都會被阻止,如對其它成員變量的賦值以及調用它們的非const方法、調用對象本身的非const方法。但對一個聲明為mutable的成員變量所做的任何操作都不會被阻止。這里保證了一定的邏輯常量性。

另外,const修飾函數時還會參與到函數的重載中,即通過const對象、const指針或引用調用方法時,優先調用const方法。

class A {public:  int &operator[](int i) {    ++cachedReadCount;    return data[i];  }  const int &operator[](int i) const {    ++size; // !error    --size; // !error    ++cachedReadCount; // ok    return data[i];  }private:  int size;  mutable cachedReadCount;  std::vector<int> data;}; A &a = ...;const A &ca = ...;int i = a[0]; // call operator[]int j = ca[0]; // call const operator[]a[0] = 2; // okca[0] = 2; // !error

這個例子中,如果兩個版本的operator[]有著基本相同的代碼,可以考慮在其中一個函數中去調用另一個函數來實現代碼的重用(參考Effective C++)。這里我們只能用非const版本去調用const版本。

int &A::operator[](int i) {  return const_cast<int &>(static_cast<const A &>(*this).operator[](i));}

其中為了避免調用自身導致死循環,首先要將*this轉型為const A &,可以使用static_cast來完成。而在獲取到const operator[]的返回值后,還要手動去掉它的const,可以使用const_cast來完成。一般來說const_cast是不推薦使用的,但這里我們明確知道我們處理的對象其實是非const的,那么這里使用const_cast就是安全的。

constexpr

constexpr是C++11中新增的關鍵字,其語義是“常量表達式”,也就是在編譯期可求值的表達式。最基礎的常量表達式就是字面值或全局變量/函數的地址或sizeof等關鍵字返回的結果,而其它常量表達式都是由基礎表達式通過各種確定的運算得到的。constexpr值可用于enum、switch、數組長度等場合。

constexpr所修飾的變量一定是編譯期可求值的,所修飾的函數在其所有參數都是constexpr時,一定會返回constexpr。

constexpr int Inc(int i) {  return i + 1;} constexpr int a = Inc(1); // okconstexpr int b = Inc(cin.get()); // !errorconstexpr int c = a * 2 + 1; // ok

constexpr還能用于修飾類的構造函數,即保證如果提供給該構造函數的參數都是constexpr,那么產生的對象中的所有成員都會是constexpr,該對象也就是constexpr對象了,可用于各種只能使用constexpr的場合。注意,constexpr構造函數必須有一個空的函數體,即所有成員變量的初始化都放到初始化列表中。

struct A {  constexpr A(int xx, int yy): x(xx), y(yy) {}  int x, y;}; constexpr A a(1, 2);enum {SIZE_X = a.x, SIZE_Y = a.y};

constexpr的好處:

是一種很強的約束,更好地保證程序的正確語義不被破壞。
編譯器可以在編譯期對constexpr的代碼進行非常大的優化,比如將用到的constexpr表達式都直接替換成最終結果等。
相比宏來說,沒有額外的開銷,但更安全可靠。



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲成在线观看| 欧美日韩激情一区二区三区| 亚洲欧美久久久| 国产日韩成人精品| 亚洲区中文字幕| 在线一区二区三区精品| 日韩不卡一二区| 高清中文字幕在线| 欧美日韩免费不卡视频一区二区三区 | 国产福利在线播放| 日韩欧美国产一二三区| 久久精品久久久久| 午夜影院在线观看欧美| 精品一二线国产| 在线视频日韩欧美| 五月天久久比比资源色| 欧美日韩不卡在线视频| 亚洲 欧美 中文字幕| 日韩在线一区二区| 久久久综合精品| 国产一级片播放| eeuss一区| 在线视频观看日韩| 国产成人精品综合网站| 亚洲小说春色综合另类网蜜桃| 午夜国产欧美理论在线播放| 国产丝袜欧美中文另类| av午夜在线| 国产成免费视频| 中文字幕伊人| 国产在线拍揄自揄拍| 天堂精品高清1区2区3区| 91精品国产色综合久久久蜜香臀 | 日韩视频1区| 日韩在线一区二区视频| 蜜桃久久av一区| 日韩在线精品| 久久99精品久久久久婷婷| 欧美日韩国产在线观看| 国产欧美日韩精品综合| 日本精品在线中文字幕| 国产蜜臀在线| 国产欧美日韩中文字幕| 在线观看国产一级片| 香蕉av一区| 影音先锋一区二区资源站| 日韩久久精品网| 亚洲美女视频一区| 色综合天天综合网国产成人综合天| 日韩中文字幕在线一区| 91麻豆视频网站| 国产欧美日韩中文字幕| 天天综合天天| 国产黄在线看| 麻豆精品视频入口| 国产黄色在线网站| 国产日韩精品电影| 国产婷婷色一区二区三区在线| 天堂在线一区二区三区| 91精品在线观看国产| 欧美日韩国产一区在线| 欧美在线视频一区二区| 日韩视频精品在线| 第一页在线观看| 蜜桃视频一日韩欧美专区| 国产永久免费高清在线观看| 亚洲免费中文字幕| 亚洲综合日韩欧美| 天堂在线中文| 国产高清一级片| 亚洲一区不卡在线| 欧美日韩国产91| 99久久www免费| 91精品久久久久久蜜臀| 中文字幕2020第一页| 欧美乱大交xxxxx另类| 国产欧美日韩最新| 精品国产99久久久久久| 亚洲小说春色综合另类网蜜桃| 一级片免费在线| 国产欧美日韩中文| 91精品国产综合久久香蕉最新版 | 一区二区三区在线播放视频| 黄色在线资源| 日韩精品视频免费看| 欧美日韩综合不卡| 国产99在线 | 亚洲| 国产成人精品网址| 国产一区精品| 国产日韩成人精品| 久久精品在线观看| 午夜国产在线| 欧美日韩精品国产| 1区不卡电影| 欧美在线观看视频一区| 欧美日韩高清一区二区| 亚洲开心激情| 欧美日韩成人综合| 日韩国产欧美在线视频| 国产欧美日韩中文久久| 中文字幕国产亚洲| 91精品国产91久久久久| 欧美日韩亚洲综合| 日韩中文欧美| 国产欧美日韩在线播放| 高清中文字幕在线| 日韩亚洲不卡在线| 日韩av一区二| 国产一区不卡在线| 日韩精品在线免费观看| 91精品国产乱码久久蜜臀| 色综合影院在线| 日韩区欧美区| 91精品国产自产观看在线| 一区二区三区在线播| 欧美亚洲综合视频| 中文字幕亚洲一区在线观看| 三级精品视频| 一区二区中文字幕在线| 精品久久久三级| 99久久精品国产成人一区二区| 日韩一级二级三级精品视频| 国产色在线视频| 精品日韩视频在线观看| 在线观看中文字幕一区| 精品视频123区在线观看| 韩国av一区二区| 亚洲理论中文字幕| 黄色片免费看| 五月天久久比比资源色| 久久99精品久久久| 伊人国产视频| 日韩一级网站| 韩国一区二区av| 亚洲 国产 欧美 日韩| 日本亚洲欧美| 中文精品视频| 欧美三级在线看| 国产 中文 字幕 日韩 在线| 91国内在线| 不卡在线视频| 国产高潮久久久| 香蕉精品久久| 国产精久久久久| 免费国产h视频在线观看86| 久99久视频| 中文字幕欧美人妻精品一区蜜臀| 国产激情久久| 精品国产免费视频| 国产91久久久久| 国产午夜精品久久| 亚洲图片小说综合| 亚洲免费婷婷| 国产一级在线免费观看| 亚洲日产av中文字幕| 在线观看国产一区| 91久久中文| 欧美日韩精品综合在线| 国产网站av| 中文字幕国产日韩| 国产高清大尺度一区二区不卡| 精品人妻一区二区免费视频| 久久精品免费看| 高清日韩中文字幕| 欧美日韩精品是欧美日韩精品| 二区中文字幕| 91精品国产综合久久久蜜臀粉嫩 | 99热最新网址| 欧美日韩精品不卡| 日韩亚洲不卡在线| 日韩欧美中文字幕在线观看| 亚洲国产无线乱码在线观看| 国产日韩中文字幕在线| 一区免费在线| 国产三级视频在线| 欧美国产一级| 在线中文字幕网站| 中文不卡在线| 中文字幕一区二区三区精品| 欧美日韩国产在线看| 欧美日韩精品国产| 精品在线一区二区| 日韩欧美色综合| 午夜国产视频 | 日韩欧美综合在线视频| 免费视频久久| 亚洲中文字幕一区| 最近中文av字幕在线中文 | 中文字幕欧美日韩在线不卡| 欧美日韩国产中字 | 国产日韩专区| 欧美日韩国产91| 国产区高清在线| 日韩精品大片| 亚洲黄色片在线观看| 国产 中文 字幕 日韩 在线| 日韩高清不卡一区| 国产日韩免费| 日韩中文字幕在线视频播放| 亚洲国产无线乱码在线观看| 欧美二三四区| 日韩欧美三级| 午夜伦欧美伦电影理论片| 在线不卡一区二区| 亚洲社区在线| 欧美日韩激情一区| 成人精品视频一区| 激情国产在线| 黄色资源在线观看| 欧美三级在线看| 国产乱国产乱300精品| 搞黄在线观看| 婷婷精品进入| 日韩高清不卡在线| 国产一二三四| av免费观看国产| 玖玖在线免费视频| 国内国产区免费视频| 中文字幕在线国产| 一区在线免费| 久久riav| 精品不卡一区二区| 成人xxxx| 日韩欧美中文| 日韩免费高清一区二区| 精品在线99| 欧美特黄一区| 欧美日韩成人一区二区| 日韩三级精品电影久久久| 欧美日本精品在线| 欧美日韩亚洲综合| 久久精品日韩无码| 国产99精品| 亚洲一区在线观看免费| 国产99对白在线播放| 日韩欧美在线第一页| 日韩国产一区久久| 亚洲 欧美综合在线网络| 欧美日韩在线三级| 日韩欧美在线视频| 高清1区2区| 91精品国产手机| 天天在线视频色| 国产一级一片免费播放| 中文字幕 欧美日韩| 国产在线观看精品| 91精品在线观看入口| 欧美日韩在线视频一区| 亚洲欧洲综合另类| 成人欧美亚洲| 国产一卡2卡3卡四卡网站| 国产在线拍偷自揄拍精品| 免费看黄资源大全高清| 精品免费久久久| 欧美另类久久久品| 精品日韩视频在线观看| 日韩影院二区| 日韩va亚洲va欧洲va国产| 粉嫩喷白浆久久| 天堂在线中文| 欧美 日韩 国产 在线观看| 欧美日韩国产免费| 国产一级片在线| 亚洲成在线观看| 中文字幕在线播出| 精品国产欧美成人夜夜嗨| 国产手机精品视频| 国产区高清在线| 精品播放一区二区| 国产 欧美在线| 美女在线视频一区| 伊人伊成久久人综合网小说| 91吃瓜在线观看| 国产福利免费观看| 国产激情久久| 国产在线高潮| 一二三区精品视频| 97最新国自产拍视频在线完整在线看| 国产午夜精品视频| 国产高清一区| 国产亚洲一级| 中文字幕高清在线播放| 日韩精品视频在线看| 国产午夜精品视频| 欧洲精品久久久| 不卡专区在线| 国产一区在线精品| 91一区二区| 国产福利一区二区| 国产成人精品免费久久久久| 在线视频一区二区三区在线播放| 欧美va亚洲va日韩∨a综合色| 欧美久久综合性欧美| 精品亚洲成a人片在线观看| 日韩综合精品| 最近中文字幕日韩精品| 欧美日韩国产系列| 中文字幕第一页在线| 中文字幕在线观看国产| 国产 欧美 日韩 在线| 欧美日韩精品区| 97视频在线| 国产日韩免费| 精品国产网站在线观看| 久久99久久久久| 日韩中文欧美| 日韩欧美国产成人精品免费| 婷婷中文字幕一区三区| 国产性一级片| 欧美不卡一二三| 国产真实乱子伦精品视频| 欧美日中文字幕| 日韩精品第一区| 91精品视频观看| 国产网站av| 中文字幕视频一区二区三区久| 不卡福利视频| 色综合天天综合网国产成人综合天| 亚洲大胆人体av| 中文字幕亚洲乱码| 91麻豆精品国产91久久久使用方法 | 国产中文在线观看| 国产在线日韩精品| 欧美一级免费在线观看| 国产区日韩欧美| 国产欧美日韩久久| 狠狠色综合色区| 亚洲欧洲三级| 精品国产欧美| 中文字幕一区不卡| 欧美日韩第一区日日骚| 欧美成人vr18sexvr| 中文字幕亚洲二区| 久久久精品国产免费观看同学| 欧美三级精品| 日韩国产欧美三级| 亚洲黄色www| 国产专区中文字幕| 中文字幕在线国产| 999精品网| 亚洲经典中文字幕| 91精品在线免费观看| 亚亚洲欧洲精品| 日韩不卡在线播放| 精品国产乱码久久久久久蜜臀| 日韩精品欧美在线| 日韩在线视频一区二区三区| 日韩不卡在线观看| 欧美国产亚洲一区| 国产欧美日韩中文久久| 国产一区不卡精品| 国产三级视频网站| 在线视频你懂得一区| 日韩美女视频一区二区在线观看| 中文字幕日韩亚洲| 大香一本蕉伊线亚洲网| 免费在线视频一区二区| 国产欧美日韩久久| 色一区在线观看| 一区二区视频国产| 精品日韩在线| 欧美国产综合视频| 国产绿帽一区二区三区| 国产丝袜一区二区| av中文资源在线| 欧美日韩视频在线| 欧美日韩国产一区在线| 日韩一级免费视频| 精品欧美不卡一区二区在线观看| 欧美日韩成人综合| 日韩欧美一级视频| 欧美日韩激情一区二区三区| 精品亚洲成a人片在线观看| 午夜伦欧美伦电影理论片| 国产高清在线视频| 精品综合久久久久| 国产日韩精品在线| 亚洲制服丝袜一区| 91精品国产综合久久蜜臀| 国产日韩精品电影| 久久99精品久久久久子伦| 99精品视频99| 中文字幕欧美日韩| 中文字幕亚洲国产| 日韩一级在线免费观看| 国产视频中文字幕在线观看| 欧美日韩高清| 精品视频在线视频| 日韩视频1区| 国产一级久久久| 国产福利第一页| 国产日韩精品在线| 偷窥国产亚洲免费视频| 在线视频观看日韩| 一本大道一区二区三区| 国产最新在线| 一区二区三区在线|网站| 精品国产31久久久久久| 国产亚洲一区字幕| 日本精品二区|