C++之Static與Const
一、Static定義
1、Static意為靜態成員,若Static修飾的成員位於C++類中,那么Static就實現了同一個類,多個對象共享數據,協調行為的目的。
2、靜態變量具有全局變量的優勢,又不會像全變量一樣被濫用。C++中用於管理靜態變量,就需要用到靜態函數。
3、C++中類的靜態成員,屬於類,也屬於對象,但終歸屬於類。(比較繞,直接記做屬於類)
1.1、Static變量

//示例
#include <iostream>
using namespace std;
class A
{
public:
static int share; //Static變量的聲明
};
int A::share = 5; //Static變量的初始化
int main()
{
A x;
cout<<A::share<<endl; //方法一:Static變量的調用
cout<<x.share<<<<endl; //方法二:Static變量的調用
return 0;
}
1.2、static靜態成員小結
1、 共享 : static 成員變量實現了同族類對象間信息共享;
2、 初始化:static 成員使用時必須初始化,且只能類外初始化。聲明與實現分離時;只能初始化在實現部分(cpp 部分);
3 、類大小: static 成員類外存儲,求類大小,並不包含在內;
4、 存儲 : static 成員是命名空間屬於類的全局變量,存儲在 data 區 rw 段;
5、 訪問 :可以通過類名訪問(無對象生成時亦可),也可以通過對象訪問。備注:static靜態成員可以被類內的普通函數靜態函數都可訪問。
1.2、Static函數

- C++為了管理靜態成員,提供了靜態函數,靜態函數對外提供接口。並且靜態函數只能訪問靜態成員。
//示例
#include <iostream>
using namespace std;
class A
{
public:
int a;
static void foo()
{
// a = 1; 錯誤 只能訪問靜態成員
share++;
}
static int share;
};
int A::share = 0;
int main()
{
A a;
a.foo();
A::foo();
return 0;
}
1.3、static靜態函數小結
1、 靜態成員函數的意義,不在於信息共享,數據溝通,而在於管理靜態數據成員, 完成對靜態數據成員的封裝。
2、 staitc 修飾成員函數,僅出現在聲明處,不可在定義處。
方式一、class A
{
static void fun()
{
}
}
方式二、
class A
{
static void fun();
}
void A:: fun() //staitc 修飾成員函數不能出現在定義處
{
}
3、 靜態成員函數只能訪問靜態數據成員。原因:非靜態成員函數在調用時 this指針被當作參數傳進。而靜態成員函數是屬於類,不屬於對象,沒有 this 指針。
二、Const
2.1、Const變量
1、 const 修飾數據成員,稱為常數據成員。常數據成員可被普通成員函數和常成員函數來使用,不可以更改。
2、const 常數據成員在使用前必須被初始化。也就是定義的同時就要初始化,之后不能再去賦值,只能使用。可以在類中(不推薦),或初始化參數列表中(這是在類對象生成之前唯一一次改變 const 成員的值的機會了)。
Const單變量初始化
const int a = 1;
Const變量在類中初始化
錯誤示范!!!!!
#include <iostream>
using namespace std;
class A
public:
void dis()
{
cout<<data<<endl;
}
private:
const int data;
};
當用該類去定義對象時就會顯示出錯,,提示沒有初始化const成員data,且提示data為只讀。
錯誤示范!!!!!
#include <iostream>
using namespace std;
class A
public:
void A()
{
data = 100; //錯誤的寫法
}
private:
const int data;
};
const成員位於類中成員時會成為只讀屬性(只讀:不能出現在“=”的左邊)。所以也不可以直接在類的構造函數中去初始化const成員。
//當然你也可以把const定義為局部變量,語法OK,但一般一旦定義const都是作為全局的。局部的就和普通局部變量一樣了,沒有多大意義。
#include <iostream>
using namespace std;
class A
public:
void A()
{
const int data = 100; //正確
}
};
2.2、const變量初始化小結
const正確初始化方法 --- <采用初始化列表進行初始化>
1、初始化列表先與本對象的構造函數執行
2、初始化列表與成員的聲明順序相同的。
//方法一:
#include <iostream>
using namespace std;
class A
public:
void A(int i)data(i)
{
cout<<data<<endl;
}
private:
const int data;
};
int main()
{
A a(200);
return 0;
}
//方法二:
#include <iostream>
using namespace std;
class A
public:
void dis()
{
cout<<data<<endl;
}
private:
const int data = 100;
};
int main()
{
A a;
return 0;
}
> 第三種情況:
//方法二:
#include <iostream>
using namespace std;
class A
public:
void A(int i)data(i)
{
cout<<data<<endl;
}
void dis()
{
cout<<data<<endl;
}
private:
const int data = 100;
};
int main()
{
A a(200);
return 0;
}
//輸出結果: 200
//那么可以得出: 最終Const變量的初始化值為確定的初始化參數列表里面的值!!
2.2、Const函數
class Screen
{
public:
char get() const;
};
char Screen::get() const
{
//do something
}
1、const 修飾函數放在聲明之后,實現體之前。
2、const 修飾函數不能修改類內的數據成員變量。
3、const 修飾函數只能調用 const 函數。非 const 函數可以調用 const 函數。
4、const 修飾的全局函數在定義和聲明處都需要 const 修飾符。
三、Const對象
1、const 對象,只能調用const成員函數。
