常量和靜態的區別和詳解

  • 常量函數: 你在 int f(int s) 後面加了一個const(int f(int s) const),表示這函數是常函數(只能被常量對象或指針或引用調用)。

常量函數調用規則:

  • 常量函數不能修改除了靜態成員變量以外的變量
  • 常量函數不能調用除了靜態成員函數以外的其他函數
  • 可以調用靜態成員函數
  • 可以對靜態成員變量進行操作

常量對象、常量指針、常量引用使用const關鍵字創建。

不希望某個對象的值被改變,在定義該對象的時候在前面加上const關鍵字。
對象調用常量函數的規則:

  • .非常量對象可以調用非常量函數和常量函數

  • .常量對象可以調用常量函數,不可以調用非常量函數

  • .常量函數與非常量函數構成重載時,非常量對象調用非常量函數,常量對象調用常量函數

爲什麼y.set(50)編譯不過?

:1常量對象可以調用常量函數,不可以調用非常量函數,即使加個void set(int a) const常量函數也會出錯,因爲常量函數不能修改成員數據,每個成員函數隱藏了一個指向對象本身的this指針,this指針的類型取決於對象,常對象的this指針是常量指針,常函數無法通過this去修改對象對應的內存

解決方法:

把常量指針this強制轉換爲非常量指針
加個函數:

void set(int a) const;
    {
        DEMO*p=const_cast<DEMO*>(this);

        p->a=a;
    }

靜態數據成員(簡單理解就是爲了延長數據或成員的生命週期)
static引入

我們知道在函數內部定義的變量,當程序執行到它的定義處時,編譯器爲它在棧上分配空間,函數在棧上分配的空間在此函數執行結束時會釋放掉,這樣就產生了一個問題: 如果想將函數中此變量的值保存至下一次調用時,如何實現? 最容易想到的方法是定義爲全局的變量,但定義一個全局變量有許多缺點,最明顯的缺點是破壞了此變量的訪問範圍(使得在此函數中定義的變量,不只受此函數控制)。static關鍵字則可以很好的解決這個問題。

另外,在C++中,需要一個數據對象爲整個類而非某個對象服務,同時又力求不破壞類的封裝性,即要求此成員隱藏在類的內部,對外不可見時,可將其定義爲靜態數據。

全局(靜態)存儲區:分爲DATA段和BSS段。DATA段(全局初始化區)存放初始化的全局變量和靜態變量;BSS段(全局未初始化區)存放未初始化的全局變量和靜態變量。程序運行結束時自動釋放。其中BBS段在程序執行之前會被系統自動清0,所以未初始化的全局變量和靜態變量在程序執行之前已經爲0。存儲在靜態數據區的變量會在程序剛開始運行時就完成初始化,也是唯一的一次初始化。

  • 靜態變量(與普通變量相比,最明顯的不同就是程序的生命週期更長)
  • 靜態函數:
    靜態成員函數與普通成員函數的根本區別在於
  • 普通成員函數有 this 指針,可以訪問類中的任意成員(包括靜態變量和靜態函數);
  • 而靜態成員函數沒有 this 指針,只能訪問靜態成員(包括靜態成員變量和靜態成員函數)

從內存角度分析,靜態變量和靜態函數的生命週期是在程序開始之前就已經分配內存,存在了,如果調用了非靜態變量或者非靜態函數,但程序還未運行到那兒,那麼就會報錯,因爲非靜態變量和非靜態函數可能還沒有初始化(即沒有分配內存),在程序結束時,清除內存,即清除靜態成員。

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