亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

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

c++常量詳解

2020-01-26 14:06:35
字體:
來源:轉載
供稿:網友

概念

常量是存放固定且不可變值的,一旦確定初始值則在程序其它地方不可改變, 所以const對象必須初始化。常量一般使用const關鍵字來修飾。

const 對象可以大致分為三類:

1. const int a

const int a =10;
int const b =10;

 這兩種格式是完全相同的。也就是說const 與int哪個寫前都不影響語義。有了這個概念后,我們來看這兩個家伙:const int * pi與int const * pi ,它們的語義有不同嗎?

你只要記住一點,int 與const 哪個放前哪個放后都是一樣的,就好比const int n;與int const n;一樣。也就是說,它們是相同的。

2. const int * p

前面已經說了 const int * p與int const * p 是完全一樣的。

我們根據下面的例子看看它們的含義。

int a =30; int b =40; const int * p=&a; p=&b;   //注意這里,p可以在任意時候重新賦值一個新內存地址 b=80;   //想想看:這里能用*pi=80;來代替嗎?當然不能 printf( “%d”, *p ) ;  //輸出是80 

語義分析:

p的值是可以被修改的。即它可以重新指向另一個地址的,但是,不能通過*p來修改b的值。

首先const  修飾的是整個*p(注意,是*p而不是p)。所以*p(p指向的對象)是常量,是不能被賦值的(雖然p所指的b是變量,不是常量)。
其次,p前并沒有用const 修飾,所以p是指針變量,能被賦值重新指向另一內存地址的。

你可能會疑問:那又如何用const 來修飾pi呢?其實,你注意到int * const pi中const 的位置就大概可以明白了。請記住,通過格式看語義。 我們看看下面的定義。

3. int* const p

這里的const修飾的p,而不是上面的*p,我們根據下面的例子來分析:

int a=30; int b=40; int * const p=&a; //p=&b;   注意這里,p不能再這樣重新賦值了,即不能再指向另一個新地址。 b=80;   //這里能用*p=80;來代替嗎?可以,這里可以通過*p修改a的值。 //請自行與前面一個例子比較。 printf( “%d”, *p ) ;  //輸出是80 *p=100;printf( “%d”, a ) ;  //輸出是100

語義分析: 
    
p值是不能重新賦值修改了。它只能永遠指向初始化時的內存地址了。并且可以通過*p來修改a的值了。與前一個例子對照一下吧!看以下的兩點分析

     1). p因為有了const 的修飾,所以只是一個指針常量:也就是說p值是不可修改的(即p不可以重新指向b這個變量了)。

     2). 整個*p的前面沒有const 的修飾。也就是說,*p是變量而不是常量,所以我們可以通過*p來修改它所指內存a的值。

     總之一句話,這次的p是一個指向int變量類型數據的指針常量。
最后總結兩句:
     1).如果const 修飾在*p前則不能改的是*p而不是指p
     2).如果const 是直接寫在p前則p不能改。

4.補充三種情況。

 這里,我再補充以下三種情況。其實只要上面的語義搞清楚了,這三種情況也就已經被包含了。不過作為三種具體的形式,我還是簡單提一下吧!

情況一:int * pi指針指向const int n常量的情況

const int n1=40; int *pi; pi=&n1;//這樣可以嗎?不行,VC下是編譯錯。const int 類型的n1的地址是不能賦值給指向int類型地址的指針pi的。否則pi豈不是能修改n1的值了嗎!  pi=(int* ) &n1;  // 這樣可以嗎?強制類型轉換可是C所支持的。 VC下編譯通過,但是仍不能通過*pi=80來修改n1的值。去試試吧!看看具體的怎樣。

情況二:const int * pi指針指向const int n1的情況

const int n1=40; const int * pi; pi=&n1;//兩個類型相同,可以這樣賦值。n1的值無論是通過pi還是n1都不能修改的。

情況三:用const int * const pi申明的指針

int n; const int * const pi=&n; //你能想象pi能夠作什么操作嗎?pi值不能改,也不能通過pi修改n的值。因為不管是 //*pi還是pi都是const的。

5. 常量引用

int a = 10;int& p1 = a;//正確int& p2 = 2;//錯誤,需要引用左值const int& p3 = a;//正確const int& p4 = 4;//正確

關于引用的初始化有兩點值得注意:

(1)當初始化值是一個左值(可以取得地址)時,沒有任何問題,可以用常量引用也可以用非常量引用, 如p1,p3;
(2)當初始化值不是一個左值時,則只能對一個const T&(常量引用)賦值。如p2,p3。而且這個賦值是有一個過程的:

首先將值隱式轉換到類型T,然后將這個轉換結果存放在一個臨時對象里,最后用這個臨時對象來初始化這個引用變量。

如果是對一個常量進行引用,則編譯器首先建立一個臨時變量,然后將該常量的值置入臨時變量中,對該引用的操作就是對該臨時變量的操作。對常量的引用可以用其它任何引用來初始化;但不能改變。

6. 常量函數、常量引用參數、常量引用返回值

例1:bool verifyObjectCorrectness(const myObj &obj); //const reference parameter
例2:void Add(const int &arg) const; //const function
例3:IStack const & GetStack() const { return _stack; } //return const reference

  6.1 常量函數
  1. 一個函數通過在其后面加關鍵字const,它將被聲明為常量函數
  2. 在C++,只有將成員函數聲明為常量函數才有意義。帶有const作后綴的常量成員函數又被稱為視察者(inspector),沒
         有const作后綴的非常量成員函數被稱為變異者(mutator)
  3. 與const有關的錯誤總是在編譯時發現
  4. [摘]If the function is not declared const, in can not be applied to a const object, and the compiler will 
         give an error message. A const function can be applied to a non-const object
  5. 在C++中,一個對象的所有方法都接收一個指向對象本身的隱含的this指針;常量方法則獲取了一個隱含的常量this指針
      void func_name() const;
      以上說明函數func_name()不會改變*this。當你把this指針看成函數func_name()的一個不可見參數就理解了
      void func_name(T *this) (no const)
      void func_name(const T *this) (const)
  6. 常量函數可以被任何對象調用,而非常量函數則只能被非常量對象調用,不能被常量對象調用,如:

class Fred { public:  void inspect() const;  // This member promises NOT to change *this  void mutate();     // This member function might change *this };  void userCode(Fred& changeable, const Fred& unchangeable) {  changeable.inspect();  // OK: doesn't change a changeable object  changeable.mutate();  // OK: changes a changeable object   unchangeable.inspect(); // OK: doesn't change an unchangeable object  unchangeable.mutate(); // ERROR: attempt to change unchangeable object }

7. 在類中允許存在同名的常量函數和非常量函數,編譯器根據調用該函數的對象選擇合適的函數
當非常量對象調用該函數時,先調用非常量函數;
當常量對象調用該函數時,只能調用常量函數;
如果在類中只有常量函數而沒有與其同名的非常量函數,則非常量與常量對象都可調用該常量函數;如:

#include <iostream>using namespace std; struct A{  void f() const { cout<<"const function f is called"<<endl; }  void f() { cout<<"non-const function f is called"<<endl; }  void g() { cout<<"non-const function g is called"<<endl; }}; void main(){  A a;  const A& ref_a = a;  a.f(); //calls void f(),輸出:non-const function f is called<br>  ref_a.f();//calls void f () const, 輸出:const function f is called a.g(); //ok, normal call <br>  ref_a.g(); //error, const object can not call non-const function }

8. const關鍵字不能用在構造函數與析構函數中。因為構造函數的目的是初始化域值,因此它必須更改對象,析構函數同理

  6.2 常量引用參數

  本例中,一個myObj類型的對象obj通過引用傳入函數verifyObjectCorrectness。為安全起見,使用了const關鍵字來確保函數verifyObjectCorrectness不會改變對象obj所引用的對象的狀態。此外,通過聲明參數常量,函數的使用者可以確保他們的對象 不會被改變,也不必擔心在調用函數時帶來副作用。以下代碼試圖對聲明為常量引用的形參進行修改,從而不會通過編譯!

#include <iostream>using namespace std; class Test{public:  void f(const int& arg);private:  int value;};  void Test::f(const int& arg) {  arg=10; //試圖修改arg的值,此行將引起編譯器錯誤 //error C2166: l-value specifies const object  cout<<"arg="<<arg<<endl;  value=20;}  void main(){ int i=7; Test test; test.f(i); cout<<"i="<<i<<endl;}

6.3 常量引用返回值

  如果你想從常量方法(函數)中通過引用返回this對象的一個成員, 你應該使用常量引用來返回它,即const X&
  也就是說你想通過引用返回的東西如果從邏輯上來講是this對象的一部分(與它是否在物理上嵌入在this對象中無關),那么常量方法需要通過常量引用或者通過值來返回,而不能通過非常量引用返回

class Person {public:  const string& name_good() const; // Right: the caller can't change the name  string& name_evil() const;    // Wrong: the caller can change the name  .}; void myCode(const Person& p) // You're promising not to change the Person object{  p.name_evil() = "Igor"; // but you changed it anyway!!}

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲精品久久久久国产| 久久亚洲欧美日韩精品专区| 久久深夜福利免费观看| 欧美成人免费一级人片100| 欧美一二三视频| 亚洲美女激情视频| 国内精品视频久久| 久久欧美在线电影| 色噜噜亚洲精品中文字幕| 精品久久久精品| 欧美日韩免费在线| 国产精品久久久久久久一区探花| 欧美日韩国产中文字幕| 亚洲精品国产美女| 九九热在线精品视频| 一本色道久久88综合日韩精品| 欧美日韩精品中文字幕| 菠萝蜜影院一区二区免费| 奇米四色中文综合久久| 亚洲成年网站在线观看| 97国产成人精品视频| 亚洲人成网7777777国产| 97免费视频在线播放| 国产精品1区2区在线观看| 日韩av在线免费看| 欧美久久精品一级黑人c片| 国产亚洲精品综合一区91| 日韩精品久久久久久福利| 理论片在线不卡免费观看| 日韩av中文字幕在线播放| 成人福利网站在线观看11| 国产精品美女久久| 欧美精品在线免费播放| 成人av在线网址| 欧美成人自拍视频| 亚洲情综合五月天| 日韩av在线天堂网| 一区二区三区视频免费在线观看| 欧美精品videossex性护士| 欧美日韩一区二区免费在线观看| 日韩欧美在线国产| 国产视频自拍一区| 少妇高潮 亚洲精品| 日韩电影免费观看在线观看| 日韩av在线一区二区| 国产suv精品一区二区三区88区| 亚洲欧美国产视频| 亚洲美女www午夜| 一区二区三欧美| 日韩精品在线观看一区二区| 日韩色av导航| 成人乱人伦精品视频在线观看| 国产精品三级美女白浆呻吟| 亚洲va久久久噜噜噜| 亚洲日本中文字幕免费在线不卡| 国产一区视频在线播放| 欧美精品久久久久| 国产精品尤物福利片在线观看| 原创国产精品91| 久久夜色撩人精品| 在线不卡国产精品| 岛国av一区二区三区| 国产91精品久久久久| 成人国产在线激情| 欧美肥臀大乳一区二区免费视频| 狠狠躁夜夜躁久久躁别揉| 亚洲精品一区久久久久久| 98精品国产高清在线xxxx天堂| 亚洲精品一区中文| 欧美精品福利在线| 国产日韩av在线播放| 欧美成人亚洲成人日韩成人| 2019亚洲男人天堂| 亚洲国产日韩欧美在线动漫| 国产91精品网站| 欧美精品午夜视频| 欧美一级淫片aaaaaaa视频| 亚洲第一男人av| 久久久久久这里只有精品| 中文字幕日韩精品在线| 亚洲欧美精品一区二区| 亚洲国产精品一区二区三区| 日本伊人精品一区二区三区介绍| 欧美电影免费观看| 欧美激情va永久在线播放| 中日韩美女免费视频网站在线观看| 久久色免费在线视频| 亚洲第一二三四五区| 久久久精品一区二区| 2025国产精品视频| 亚洲综合日韩中文字幕v在线| 91高清免费在线观看| 在线精品高清中文字幕| 高清在线视频日韩欧美| 亚洲aaaaaa| 国产精品爽黄69| 亚洲第一页中文字幕| 日韩中文字幕不卡视频| 久久亚洲精品中文字幕冲田杏梨| 亚洲综合在线中文字幕| 久久这里只有精品视频首页| 亚洲精品国产精品乱码不99按摩| 久久精品国产96久久久香蕉| 日韩中文字幕在线| 国产精品对白刺激| 国产主播在线一区| 精品无人区乱码1区2区3区在线| 成人国产亚洲精品a区天堂华泰| 亚洲天堂免费观看| 亚洲三级免费看| 啪一啪鲁一鲁2019在线视频| 久久久久99精品久久久久| 国产va免费精品高清在线观看| 91sao在线观看国产| 国产视频精品在线| 欧美成人在线免费| 国内精品久久久久久影视8| 亚洲精品美女久久久久| 亚洲第一av网| 欧美性色19p| 日韩在线视频中文字幕| 国产美女精品免费电影| 国产精品白嫩美女在线观看| 国产精品自拍偷拍视频| xxx一区二区| 日韩色av导航| 色综合久久88色综合天天看泰| 亚洲欧美日韩国产精品| 亚洲国产私拍精品国模在线观看| 日韩av在线免播放器| 国产精品无av码在线观看| 日韩中文字幕在线精品| 色播久久人人爽人人爽人人片视av| 综合国产在线观看| 久久久久久久91| 国产精品久久久久久久9999| 中文字幕亚洲欧美日韩高清| 北条麻妃99精品青青久久| 孩xxxx性bbbb欧美| 成人精品aaaa网站| 精品免费在线观看| 韩国三级日本三级少妇99| 日本精品久久久久久久| 日韩欧美高清在线视频| 欧美成年人网站| 55夜色66夜色国产精品视频| 日韩精品在线影院| 精品高清一区二区三区| 日韩精品极品在线观看播放免费视频| 欧美大肥婆大肥bbbbb| 色偷偷综合社区| 国产精品成人va在线观看| 亚洲自拍偷拍色图| 国产精品99久久久久久白浆小说| 国产亚洲欧美日韩精品| 日韩美女写真福利在线观看| 亚洲丁香婷深爱综合| 欧美大片在线影院| 91极品女神在线| 理论片在线不卡免费观看| 国产精品日韩欧美综合| 国产欧美最新羞羞视频在线观看| 日本久久久久亚洲中字幕| 午夜精品国产精品大乳美女|