static 與 this 指針
static
當類被多次實例化后帐要,一般數據成員會有多份把敞,而成員函數只有一份,通過this指針確定當前數據成員是在那個對象中被調用榨惠。但是類中的static成員卻不盡相同:
static成員數據
類中的static數據成員奋早,在類中只有一份,可以理解成赠橙,類范圍內的靜態(tài)全局變量耽装。
類中的static數據成員必須在類外定義并初始化,類中聲明期揪。
就像靜態(tài)變量掉奄,類中的static數據成員也只初始化一次,并在整個程序的聲明周期中一直存在凤薛。
static成員函數
類的static成員函數姓建,與普通成員函數不同,它被調用時不會傳遞this指針缤苫,也就是說他沒有對象的概念速兔。
類中的static成員函數,只能使用類中的static數據成員活玲。(因為沒有this指針不能確認那個普通數據成員可以使用)
static成員函數的調用方式有兩種:
1.通過對象調用
2.通過class name調用
class complex{
private:
double re, im;
static int instance_cnt;
public:
complex(double _re = 0, double _im = 0) : re(_re), im(_im) { instance_cnt++; }
complex(const complex & c):re(c.re), im(c.im) { instance_cnt++; }
static int get_instance_num(){ return instance_cnt; } //返回當前類共有多少對象
}憨栽;
int complex::instance_cnt = 0;
int main(){
complex c1(1,2);
complex c2(c1);
complex c3 = c2;
complex *pc = new complex(2,3);
cout << "complex class has " << complex::get_instance_num() << " objects in total." << endl;//通過類名調用
delete pc;
pc = NULL;
cout << "now the complex class has " << c1.get_instance_num() << " objects left." << endl;//通過類對象調用
}
以上運行結果:
注:static 成員數據在類外定義的時候不需要使用static關鍵字:
this指針
類的成員函數都有一個隱藏的參數——this指針,當數據成員被調用時都會隱式傳入this指針翼虫。但是屑柔,對于類中的static成員函授,不會傳入this指針珍剑,所以static成員函數無法處理對象的成員數據掸宛,而只能處理類中的static數據。
放在private區(qū)中的constructor函數(singleton)
類的構造函數通常為public招拙,這樣才能構造出很多實例唧瘾。但是,在設計模式中有一種專門把構造函數設計成私有成員别凤,其作用就是保證一個類只能有一個實例饰序,并提供一個全局唯一的訪問點。這種設計模式叫做單例設計模式(singleton)
class Singleton{
public:
static Singleton* getInstance(){
if(!pIns){
pIns = new Singleton();
}
return pIns ;
}
static void dosth(){……}
static void destory(){
if(pIns){
delete pIns;
pIns = NULL;
}
}
private:
singleton(){}
static singleton * pIns;
};
//調用:
int main(){
for(int i = 0; i < 10; ++i){
Singleton *ps = Singleton::getInstance();//通過全局訪問點訪問规哪,其實只有一個實例求豫,并不是每次循環(huán)都創(chuàng)建
Singleton::dosth();
}
Singleton::destroy();
return 0;
}
singleton的特點:
不調用getInstance就沒有Singleton類的實例存在,調用一次后,不管再調用多少次蝠嘉,都只有一個實例最疆。
cout——一種ostream,重載了“<<”操作符
cout是一種ostream類蚤告,在其內部針對各種內置數據類型多次重載了操作符“<<”努酸,使其可以輸出內置數據類型的各種實例。因此用戶定義的類中杜恰,如果想重載操作符"<<"获诈,必須定義成全局的操作符重載函數,第一個參數是ostream cout心褐,第二個參數是自定義的類烙荷,這樣才符合cout 在 “<<”左邊,實例在右邊的日常使用習慣檬寂。
complex類终抽,重載操作符“<<”的代碼示例:
class complex{
private:
double re, im;
public:
friend ostream & operator<<(ostream & os, const complex& c);
};
ostream & operator<<(ostream & os, const complex& c){
os << "(" << c.re << "," << c.im << ")" ;
return os;
}
int main(){
complex c1(1,2);
cout << c1 << endl;
}
如果把操作符“<<”的重載設計成類成員函數,則其參數將只能有一個ostream類型桶至,在調用的時候會默認出入this指針作為左值昼伴,這樣對其的調用形式將是:“c1 << cout”,是不是很奇怪呢镣屹?完全不符合我們日常的使用習慣圃郊。
因此切記:對于自定義的類,其操作符“<<”的重載函數必須要寫成全局變量才好女蜈!
類模板與函數模板
類模板
使用時必須顯示指定類型
函數模板
使用時編譯器會作參數推導持舆,不用顯示指定類型
namespace
使用命令的方式引用
語法:using namespace <名字空間名>
使用聲明的方式引用
語法:using <名字空間名>::<函數名>
不使用using引用
語法:在使用的地方,直接以 <名字空間名>::<函數名> 的方式使用