刷劍指offer第64題涉及到類內靜態成員與方法的知識,有點模糊,找了兩篇部落格整理一下。
最近一直看c++相關的專案,但總是會被c++類中的靜態成員變數與靜態成員函式的理解感覺很是模糊,不明白為什麼類中要是用靜態成員變數.於是在網上蒐集了一些資料,自己再稍微總結下。
靜態成員的概念:
靜態類中的成員加入static修飾符,即是靜態成員.可以直接使用類名+靜態成員名訪問此靜態成員,因為靜態成員先於類的宣告而存在於記憶體,也可以根據類宣告的物件來訪問.而非靜態成員必須例項化之後才會分配記憶體.
非靜態成員的概念:
所有沒有加static的成員都是非靜態成員.而類被例項化後,可以通過例項化的類名進行訪問.非靜態成員的生存期決定於該類的生存期.而靜態成員不存在生產期的問題,因為它始終駐留在記憶體.
分兩個方面來總結,面向過程與物件導向.
一:面向過程中的static關鍵字
1.靜態全域性變數
定義全域性變數前,加上關鍵字static,該變數就被定義成了乙個靜態全域性變數.
特點:
程式在記憶體中一般分為四個區域:
一般程式由new產生的動態資料放在堆區,函式內部的自動變數放在棧區.自動變數一般會隨著函式的退出而釋放空間,靜態資料(即使是函式內部的靜態區域性變數)都存放在全域性資料區.因此它們並不會隨著函式的退出而釋放空間.
static int n;//定義靜態全域性變數
改為: int n;//定義全域性變數
區別:靜態全域性變數不能被其他檔案所用.因而其他檔案可以定義相同名字的變數,而不會發生衝突.
例子:
//example
//file 1
#include void fn();
static int n;//定義靜態全域性變數(只能在本檔案中使用)
void main();
int myclass::sum=0;//定義並初始化靜態資料成員
特點:對於非靜態資料成員,每個類物件都有自己的拷貝.而靜態資料成員被當做是類的成員,無論這個類被定義了多少個,靜態資料成員都只有乙份拷貝,為該型別的所有物件所共享(包括其派生類).所以,靜態資料成員的值對每個物件都是一樣的,它的值可以更新.因為靜態資料成員在全域性資料區分配記憶體,屬於本類的所有物件共享,所以它不屬於特定的類物件,在沒有產生類物件前就可以使用.2.靜態成員函式與普通的成員函式相比,靜態成員函式由於不是與任何的物件相聯絡,因此它不具有this指標.從這個意義上來說,它無法訪問屬於類物件的非靜態資料成員,也無法訪問非靜態成員函式,只能呼叫其他的靜態成員函式.
**:
靜態成員的提出是為了解決資料共享的問題。實現共享有許多方法,如:設定全域性性的變數或物件是一種方法。但是,全域性變數或物件是有侷限性的。這一章裡,我們主要講述類的靜態成員來實現資料的共享。
靜態資料成員
在類中,靜態成員可以實現多個物件之間的資料共享,並且使用靜態資料成員還不會破壞隱藏的原則,即保證了安全性。因此,靜態成員是類的所有物件中共享的成員,而不是某個物件的成員。
使用靜態資料成員可以節省記憶體,因為它是所有物件所公有的,因此,對多個物件來說,靜態資料成員只儲存一處,供所有物件共用。靜態資料成員的值對每個物件都是一樣,但它的值是可以更新的。只要對靜態資料成員的值更新一次,保證所有物件訪問更新後的相同的值,這樣可以提高時間效率。
靜態資料成員的使用方法和注意事項如下:
1、靜態資料成員在定義或說明時前面加關鍵字static。//靜態變數的定義
2、靜態成員初始化與一般資料成員初始化不同。靜態資料成員初始化的格式如下:
《資料型別》《類名》::《靜態資料成員名》=《值》 //靜態變數的初始化
這表明:
(1) 初始化在類體外進行,而前面不加static,(這點需要注意)以免與一般靜態變數或物件相混淆。
(2) 初始化時不加該成員的訪問許可權控制符private,public等。
(3) 初始化時使用作用域運算子來標明它所屬類,因此,靜態資料成員是類的成員,而不是物件的成員。
3、靜態資料成員是靜態儲存的,它是靜態生存期,必須對它進行初始化。
4、引用靜態資料成員時,採用如下格式:
《類名》::《靜態成員名》 //靜態變數的使用方式
如果靜態資料成員的訪問許可權允許的話(即public的成員),可在程式中,按上述格式來引用靜態資料成員。
下面舉一例子,說明靜態資料成員的應用:
class statictest
;#include "statictest.h"
#include using namespace std;
int statictest::sum = 0;//靜態成員在此初始化
statictest::statictest(int a, int b, int c)
void statictest::getnumber()
void statictest::getsum()
注意,static成員的初始化要在實現中進行,不能在標頭檔案進行。
從輸出結果可以看到sum的值對m物件和對n物件都是相等的。這是因為在初始化m物件時,將m物件的三個int型資料成員的值求和後賦給了sum,於是sum儲存了該值。在初始化n物件時,對將n物件的三個int型資料成員的值求和後又加到sum已有的值上,於是sum將儲存另後的值。所以,不論是通過物件m還是通過物件n來引用的值都是一樣的,即為54,s.a=3。
靜態成員函式
靜態成員函式和靜態資料成員一樣,它們都屬於類的靜態成員,它們都不是物件成員。因此,對靜態成員的引用不需要用物件名。
在靜態成員函式的實現中不能直接引用類中說明的非靜態成員,可以引用類中說明的靜態成員(這點非常重要)。如果靜態成員函式中要引用非靜態成員時,可通過物件來引用。從中可看出,呼叫靜態成員函式使用如下格式:《類名》::《靜態成員函式名》(《參數列》);
C 類中靜態變數和靜態方法使用介紹
靜態成員的提出是為了解決資料共享的問題。實現共享有許多方法,如 設定全域性性的變數或物件是一種方法。但是,全域性變數或物件是有侷限性的。這一章裡,我們主要講述類的靜態成員來實現資料的共享。靜態資料成員 在類中,靜態成員可以實現多個物件之間的資料共享,並且使用靜態資料成員還不會破壞隱藏的原則,即保證了...
C 類中靜態變數和靜態方法的使用
靜態成員的提出是為了解決資料共享的問題。實現共享有許多方法,如 設定全域性性的變數或物件是一種方法。但是,全域性變數或物件是有侷限性的。這一章裡,我們主要講述類的靜態成員來實現資料的共享。靜態資料成員 在類中,靜態成員可以實現多個物件之間的資料共享,並且使用靜態資料成員還不會破壞隱藏的原則,即保證了...
C 類中靜態變數和靜態方法使用介紹
靜態成員的提出是為了解決資料共享的問題。實現共享有許多方法,如 設定全域性性的變數或物件是一種方法。但是,全域性變數或物件是有侷限性的。這一章裡,我們主要講述類的靜態成員來實現資料的共享。靜態資料成員 在類中,靜態成員可以實現多個物件之間的資料共享,並且使用靜態資料成員還不會破壞隱藏的原則,即保證了...