靜態成員、靜態函式(static)

相同類別所產生的物件,擁有各自的成員變數,類別有時擁有某個不變的特性,例如對Ball這個類別來說,不同的Ball都有相同的圓周率PI,這時不需要讓Ball實例,擁有各自的圓周率成員變數,可以加上關鍵字static,將PI成員變數設為靜態成員。

靜態成員有以下幾個特性:
1.靜態成員屬於類別,而不屬於個別的物件。
2.非const的static成員要在類別定義區塊之外初始化。
3.可以用物件實例的名稱,或是類別名稱加上::運算子來存取,通常使用類別名稱加上::運算子來存取,一方面也可以避免與非靜態資料成員混淆。
4.靜態成員同樣遵守public、protected與private的存取限制。

以下程式碼為靜態成員的使用方式。

class Ball{
private:
    int m_x;
    int m_y;
public:
    Ball(int x, int y);
    static float PI;
};

int main() {
    float val = Ball::PI;  //val=3.14
    return 0; 
}

float Ball::PI = 3.14;
Ball::Ball(int x, int y){
    m_x = x;
    m_y = y;
}

與靜態成員變數類似,我們也可以將函式加上關鍵字static,將函式設為靜態函式,靜態函式通常是作為工具函式,例如在Ball類別上增加一個計算面積的函式calcArea()。

靜態函式同樣可以透過類別名稱來呼叫,由於靜態成員是屬於類別而不是物件,所以呼叫靜態函式時,並不會傳入物件的位址,所以靜態函式中不會有this指標,也不允許使用非靜態成員,所以calcArea()不能取用非靜態成員的m_x或m_y。

class Ball{
private:
    int m_x;
    int m_y;
public:
    Ball(int x, int y);
    static float PI;
    static double calcArea(double);
};

int main() {
    float val = Ball::PI;  //val=3.14
    float tempArea = Ball::calcArea(10); 
    return 0; 
}

float Ball::PI = 3.14;
double Ball::calcArea(double radius) {
    return PI*radius*radius;
}
Ball::Ball(int x, int y){
    m_x = x;
    m_y = y;
}