類定義
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;
};
這倆之所以可以還是時間先後順序。