Const和Static詳解

const 分爲三種介紹

  1. 普通const對象(變量) 一旦創建就不能再改變,所以const的對象必須要初始化,必須賦值,不然沒有意義(難道不可更改一個沒有的東西)
    這裏插播一個define,雖然# define a 30;也是讓a不可更改,但是他是替代,出現幾次替代幾次。產生多個副本,const只有一個副本,define不能定義數據類型

  2. 對於類裏面的const我們分爲四種

  • const成員變量(只讀),和普通的const變量一樣,定義的時候在前面加上const關鍵字就可以,初始化const成員變量只有一個方法,就是參數初始化表(構造函數初始化),所以不同的對象const的數值不一樣。這和static的類外初始化非常不同,const static 和static const都是類外初始化
  • const成員函數爲了保護數據設置,可以使用類中的所有成員變量,但是不能修改變量,語法就是在聲明和定義的時候在函數頭部的結尾加上const關鍵字,const成員函數不能調用類中非const的成員函數
double getprice() const;
  • const對象,常對象只能調用類中的常成員函數(const的對象只能調用const的函數),常對象就是不能對當前對象的成員進行修改,進行左值操作
const 類名 對象名(實參名);   const Book a(a);
類名 const 對象名(實參名);
  • 對象的const引用,將對象作爲函數的參數時,常常採用引用的方式作爲函數的參數,爲了避免對對象本身做修改,在函數形參前加上const關鍵字
  1. const指針:注意 * 在const的前面還是後面,* 在const之前說明指針是一個常量,這樣不變的就是指針本身的值(地址)而不是指針指向的值(簡單一句話就看離對象名最近的是const還是*)
int a = 0;
int * const p = &a;//p是一個常量指針,不能更改,也就是不能進行p++這種操作
const int *p;//p是一個指向常量的指針,也就是不能通過p修改他指向的值

以上我們也可以區分頂層const和底層const(以下描述不僅適用於指針,其他數據類型也可以)
頂層const:指針本身是個常量,指針本身不可變,就是離對象名最近的是const(這種記憶法不一定全對,總之是對象本身的值不改變的就是頂層)
底層const:指針所指的對象是一個常量,也就是所指向的對象不能被改變,離對象名最近的是指針(或其他數據類型)

static

  1. static局部變量,因爲是static是存在靜態區,函數執行結束不會被釋放,繼續保存在內存,這時的static的作用範圍只是這個函數,內存只被分配一次,下次再調用的時候維持原值

  2. 類中的靜態成員變量(或函數)特點屬於類不屬於對象,當然任何對象都可以共享這個成員變量和函數,我們可以細分成以下幾點:

  • 靜態成員變量,把static加到變量的聲明前面,類內聲明的靜態成員變量的定義必須在任何程序塊之外,也就是不被任何花括號包圍,必須外部定義,定義的時候帶上類名和作用域 A::b ==(類內聲明類外定義,定義時不帶static,帶類名)==調用該變量的時候可以直接類名::變量名,這是static成員變量特有的引用方式,靜態成員變量默認初始化爲0
  • 靜態成員變量不會影響類及對象的大小,即sizeof的結果不會被影響,類的大小隻與虛函數和變量有關
  • 數據共享,靜態成員變量屬於類不屬於某一個對象,因此可以實現數據共享的功能,靜態成員在類的所有對象中都是共享的,共享性就是有一個調用靜態成員變量的修改了值,其他所有的都會被修改,而且也不會因爲對象的創建new或銷燬delete而改變,如下代碼:
  class Test{
         public:
            static int num;}
        int Test::num = 1;//定義在程序塊之外
        int main(){
            Test one;
            Test two;
            cout << Test::num << "  "<< one.num<< "  "<< two.num << endl;//打印都是1111
           Test::num = 5;
           cout << Test::num << "  "<< one.num<< "  "<< two.num << endl;//打印都是5555}

  • 靜態成員函數只能訪問靜態成員變量(這點和const有點像),不能訪問非靜態成員函數,靜態成員函數也是屬於類的,也是通過類名::函數名來訪問,普通成員函數和變量不能通過類訪問,只能通過對象來訪問。
  • 由於靜態成員函數和變量都是屬於類,而不是屬於對象,所以靜態成員函數內部不存在this指針,因爲靜態成員函數不屬於對象,可以用靜態成員函數判斷類的某些對象是否已經創建,因爲他們不能訪問類的this指針(this指針一般指當前對象,static不屬於任何對象)
  • 類內聲明瞭,那麼類外定義靜態成員函數不需要static關鍵字,因爲static的兩個作用就是作用域限制和生存期限制,如果加了關鍵字,由於作用域的限制,只能在本cpp中,就不能再程序的其他地方調用了,如果其他文件要調用我們一般加extern,但是跟static是對立的,不能用到一起。
  • 靜態成員函數不能聲明爲虛函數,只有非靜態成員函數才能成爲虛函數,因爲靜態成員函數屬於一個類,而不是一個對象,沒有this指針,無法對對象進行判別,不屬於任何對象

此外: static可以隱藏數據,保護數據,因爲static只能在本文件訪問,所以在a.cpp聲明瞭static int a,b.cpp就不能訪問a,間接實現了保護數據的作用

PS:看到static的這些作用,你是否也想到了單例模式喃

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章