static成員

類定義 

class Account{
public:
    static double rate(){
        return interestRate;
    }

private:
    static double interestRate;
    static double initRate()
    {
        return 1;
    }
};

double Account::interestRate = 0;

動機

一些成員變量沒必要每個對象都持有一份,比如銀行賬戶類的利率。還能減小內存佔用。

靜態成員函數

1.不能聲明爲const

靜態成員函數屬於大家,所以沒有this指針,而const是修飾this指針的,所以靜態成員函數不能聲明爲const

2.訪問方式(成員變量同理)

既可以通過類作用域訪問,也能通過對象,指針,引用訪問(以前經常誤會成只能通過類訪問)

double r = Account::rate();

Account ac1;
Account *ac2 = &ac1;
r = ac1.rate();
r = ac2->rate();

靜態成員變量

1.初始化時機

因爲靜態成員變量屬於所有對象,所以不能在構造函數初始化,需要在類外初始化。

2. 可以調用其他static的private函數和成員進行初始化

double Account::interestRate = initRate();

3.static const整數類型

可以在類裏初始化,但必須用常量表達式。在類外也必須定義一下,但不用帶初始值,否則外面的函數找不到這個變量。

#include <iostream>
#include <vector>
#include <string>
using namespace std;

class Account
{
public:
    static constexpr int period = 30;
};
void f(const int&)
{

}

void g(const int)
{

}

int main() {
    cout<<Account::period<<endl;  //爲啥這個找到了
    f(Account::period);   //xxx,找不到,undefined reference to `Account::period'
    g(Account::period);   //沒錯
    return 0;
}

解決方法是在類外定義使之地址可見

constexpr int Account::period;

問題:

爲啥cout沒錯?爲啥函數形參爲const int 沒錯? 爲啥函數形參爲const int& 錯了? 

推測是想引用地址就必須在同一塊下可見才行

番外:

cout是個流對象,或者說是ostream這個類的對象,該類內部有輸出緩衝區,當執行cout << x的時候,其實就是調用了ostream的operator<< 方法,該方法是對<<運算符的重載,該方法的參數即是x。
operator<<方法返回ostream類的引用,即該類對象自身,所以cout << x 語句可以做左值,即支持連續調用: cout << x << y.....
x變量內容拷貝到緩衝區中,ostream內部會根據某種緩衝機制(全緩衝,行緩衝,無緩衝)將緩衝區的內容輸出到屏幕終端。
執行cout << a++時,先打印a,之後將a加一,同理類推。
所以cout << (a++) << (a++) << (a++) << endl;語句打印三次a變量,每次執行同時將a加一,最後endl即將緩衝區所有內容輸出,同時打印換行。
執行結果是: 1 2 3

4. static變量的優勢

1.適用於非完全類型

class Bar{
private:
    static Bar mem1;   //正確,但外面的初始化咋整呢?
    Bar * mem2;
    Bar mem3;   //xxx
};

Bar Bar::mem1 = Bar(); //這樣嗎?

2.可以作爲默認實參

class Screen{
public:
    Screen &clear(char = bkGround);

private:
    static const char bkGround;
};

這倆之所以可以還是時間先後順序。

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