1. 程式人生 > 實用技巧 >C++中static關鍵字詳解

C++中static關鍵字詳解

1.static關鍵字的理解

static關鍵字主要分為四大點:static修飾全域性變數,static修飾區域性變數,static修飾靜態成員變數,static修飾靜態成員函式

1.1static修飾普通變數

static修飾普通變數有兩種情況:全域性變數和區域性變數

1.1.1 static修飾全域性變數

在全域性變數前加上一個static關鍵字,普通全域性變數就變成一個靜態全域性變數,我們主要從三個方面來進行說明:儲存,初始化和作用域

Ø儲存

介紹儲存之前,我們首先需要了解資料在記憶體中的儲存結構,儲存結構圖如下

靜態全域性變數都儲存在靜態儲存區(data段的ro段或者

BSS段)。未初始化的靜態全域性變數儲存在BSS段。初始化了的靜態全域性變數儲存在data段的ro段,並且靜態全域性變數和普通全域性變數一樣,在整個程式執行期間會一直存在。

Ø初始化

未經初始化的全域性變數會被系統自動初始化為0

Ø作用域

靜態全域性變數在宣告他的檔案外是不可見的,使用更加安全。

1.1.2 static修飾區域性變數

普通區域性變數加上static關鍵字修飾後,變成靜態區域性變數,我們仍然從三個方面來進行說明:儲存,初始化和作用域

Ø儲存

靜態區域性變數儲存在靜態儲存區,和靜態全域性變數一樣,初始化了的靜態區域性變數儲存在data段的ro

段,沒有初始化的靜態區域性變數儲存在BSS段。

Ø初始化

未經初始化的全域性靜態變數會被自動初始化為0

Ø作用域

靜態區域性變數作用域仍然為區域性作用域。當定義它的函式或者語句塊結束的時候,作用域結束。但是當局部靜態變數離開作用域後,沒有銷燬,而是留在記憶體塊中,只是我們不能再對其進行訪問。直到函式再次被呼叫,並且靜態區域性變數的值是不變的。

1.2static修飾類的成員

static可以實現在同一個類中, 不同物件之間實現資料共享、協調工作。

靜態變數有全域性變數的優勢,但不會被全域性變數一樣被濫用,而用於管理靜態變數。

類的靜態成員。屬於類,也屬於物件,但終究屬於類。

1.2.1 static修飾類的資料成員

在類的資料成員前加上關鍵字static,類的資料成員就成為靜態資料成員,我們主要從五個方面來進行說明:共享、初始化、類大小、儲存、訪問

Ø共享

設定靜態資料成員,可以實現在同一個類中,不同物件之間實現資料共享

Ø初始化

可以分為宣告和定義,

在類內宣告,宣告格式:static 資料型別 資料變數

在類外定義,定義格式:資料型別 類名::資料變數=初始化的值

如果宣告和定義是分開的,將定義寫到.cpp

Ø類大小

static宣告的資料成員是不佔用物件的大小

Ø儲存

儲存在靜態儲存區data段的ro段。

Ø訪問

可以通過物件訪問,也可以通過類名訪問。類的靜態資料成員,屬於類,也屬於物件,但終究屬於類。

1.2.2 static修飾類的函式成員

之前我們已經瞭解到,類的靜態成員變數是可以在沒有物件的情況下進行訪問的,因此要訪問類的靜態成員變數的函式也要能實現在沒有物件的時候訪問。為了實現這樣的情況,我們可以把訪問靜態資料成員的函式設定為靜態成員函式。static修飾類的成員函式,主要用來管理靜態資料成員。

Ø靜態成員函式的意義,不在於資訊共享,而在於管理靜態資料成員,完成對靜態資料成員的封裝

Østatic修飾成員函式和修飾資料成員一樣,僅出現在宣告處,不出現在定義出

Østatic只能訪問靜態資料成員而不能訪問非靜態資料成員。因為非靜態資料成員在呼叫時this指標被當做引數傳入。而靜態成員函式屬於類,而不屬於物件,沒有this指標

Ø非靜態成員函式可以訪問靜態成員函式。

對於static關鍵字中類的成員來說,我們可以舉一下的例子進行說明

  • 題目描述
  求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等關鍵字及條件判斷語句(A?B:C)。
  • 題目分析

  要實現不同乘除法實現求和,我們可以考慮類的建構函式以及靜態資料成員的特性:靜態資料成員在同一個類中、多個物件之間實現資料共享。

  由於每創造一個物件就會呼叫一次建構函式,因此我們可以設定一個靜態資料成員,然後每次呼叫遞加一次

 1 class Solution {
 2 public:
 3     //可以利用建構函式來實現不用加減乘除做加法
 4     /*
 5     利用類的靜態成員變數中static特性。static修飾類的資料成員變數,可以實現資料成員變數在類中的不同物件之間的資料共享
 6     因此我們可以在建構函式中使用這個靜態成員變數,由於建立每個資料成員都會呼叫其建構函式,即可以實現相加
 7     */
 8     class temp
 9     {
10     public:
11         temp()
12         {
13             ++N;
14             sum+=N;
15         }
16         static void reset()
17         {
18             N=0;
19             sum=0;
20         }
21         static int getsum()
22         {
23             return sum;
24         }
25         
26     private:
27         static int N;
28         static int sum;
29     };
30     
31     int Sum_Solution(int n) {
32         temp::reset();
33         temp *a=new temp[n];
34         delete []a;
35         a=nullptr;
36         return temp::getsum();
37     }
38 };
39 int Solution::temp::N=0;
40 int Solution::temp::sum=0;