C++語法點

函數

1.帶默認形參值的函數,默認形參值必須按從右向左定義,實參從做到右初始化

int add(int x, int y=5, int z=6){} 
add(1); //y和z使用默認形參值

默認形參值可以通過函數聲明在不同作用域中設置不同的值
2.函數模板

template <typename T>

函數定義
eg:

template <typename T>
T abs(T x)
{
	return x<0?-x,x;
}

類和對象

1.類的聲明

class 類名稱
{
public:
	外部接口
protected:
	保護型成員
private:
	私有成員
}

public聲明類的外部接口,任何來自外部的訪問都必須通過這個外部接口來進行
private成員只允許本類的成員函數訪問,類外部的任何訪問都是非法的
protected成員可以被繼承的新類訪問

2.類成員函數聲明

返回值類型 類名:函數成員名(參數表)
{
	函數體
}

內聯成員函數:與java不同,C++類體中只包含變量和函數的聲明,帶函數的定義的函數被隱式聲明爲inline函數,類體外內聯函數的聲明需要加inline關鍵字

3.構造函數和析構函數
構造函數的函數名和類名相同,沒有返回值,可以是內聯函數,支持重載。
java有內存自動回收機制,因此所有類的創建都使用“類名 對象名 = new 類名(參數列表);”的方式創建
C++的new不會自動回收,但是可以在指定作用域內通過"類名 對象名(參數列表);"定義局部類,此時的對象名作爲一塊棧內存的指針,不像new出來的對象名指向堆內存,因此不可以直接被return,系統會調用拷貝構造函數

拷貝構造函數形參是本類對象的引用,作用是使用一個已經存在的對象去初始化一個新的同類對象:

class 類名稱
{
public:
	類名(參數表);			//拷貝函數
	類名(類名 &對象名);	//拷貝構造函數
}
類名::類名(類名 &對象名)	//拷貝構造函數的實現
{
	函數體
}

拷貝構造函數在對象作爲形參或者作爲對象作爲返回值的時候被自動調用

析構函數是在對象的生命期即將結束的時刻由系統自動調用的,不接受任何參數,可以是虛函數。

~類名()
{
	函數體
}

java有內存自動回收,因此類不需要析構函數,finalize()成員作爲內存釋放的hook函數

如果類具有內嵌對象成員(聚合關係),且需要對內嵌對象成員進行初始化,構造函數定義爲:

類名::類名(參數表):內嵌對象1(參數表),內嵌對象2(參數表),...(單冒號:後面跟的是類成員的初始化值,這裏傳入對象即調用內嵌對象的拷貝構造函數)
{
	類的初始化
}

eg:

class Distance
{
public:
	Distance(Point xp1, Point xp2);
private:
	Point p1,p2;
}
Distance::Distance(Point xp1, Point xp2):p1(xp1),p2(xp2)
{
	cout<<"Distance構造函數"<<endl;
}

調用順序爲先按照內嵌對象在組合類的聲明中出現的次序,依次調用內嵌對象的構造函數,最後執行本類的構造函數的函數體,析構函數的順序則相反。

4.類模板

template <模板參數表>

類聲明

模板<模板參數表> 對象名1,...,對象名n

eg:

template <class T>
class Store			//類模板
{
private:
	T item;
	int haveValue;
public:
	Store(void);
}
template <class T>
Store<T>::Store(void):haveValue(0) //函數模板實現的構造函數
{}
Store<int> S1,S2;  //類模板調用

5.UML圖
Coad/Yourdon標記中類使用帶有圓角的矩形表示;
對象標記在類標記外加一個帶有圓角的矩形框;
帶實心箭頭表示消息聯繫,箭頭方向是消息接收方;
帶空心半圓表示繼承關係,半圓方向是父類;
帶空心三角形表示包含關係,三角方向是外部類;

6.靜態成員

C++中的靜態成員不能像java一樣使用類名訪問,需要使用類限定符如Point::countP = 0;

7.友元
友元關係不可傳遞,單向的。
友元函數是在類聲明中由關鍵字friend修飾的非成員函數,在它的函數體中可以通過對象名訪問類的私有和保護成員。
若A類是B類的友元類,則A類的所有成員函數都是B類的友元函數,都可以訪問B類的私有和保護成員。

8.常量
常引用所引用的對象不能被更新,比如常引用作爲形參,在函數中不能更新該引用引用的對象;
常對象必須進行初始化,而且不能被更新,常對象只能調用它的常成員函數,不能調用其他成員函數;
常成員函數說明格式:

類型說明符 函數名(參數表)const;

常成員函數不能更新對象數據成員,也不能調用非const修飾的成員函數
const關鍵字可以被用於參與對重載函數的區分,eg:

R a(5);
a.print();  //調用 void print()
const R b(4);
b.print(); //調用 void print() const

繼承與派生

1.派生類(子類)的聲明語法:

class 派生類名:繼承方式 基類名1,繼承方式 基類名2,...,繼承方式 基類名n
{
	派生類成員聲明;
};

同時繼承多個類是c++獨有的特性,java只能繼承一個類
繼承過程中,如果派生類聲明瞭一個和某個基類成員同名的新成員,派生的新成員就覆蓋了外層同名成員(如果是成員函數,參數表不同則屬於重載,否則屬於覆蓋)。

2.訪問控制
1.公有繼承,基類的公有和保護成員的訪問屬性在派生類中不變,而基類的私有成員不可訪問。
2.私有繼承,基類的公有成員和保護成員都以私有成員身份出現在派生類中,而基類的私有成員在派生類中不可訪問。
3.保護繼承,基類的公有成員和保護成員都以保護成員身份出現在派生類中,而基類的私有成員在派生類中不可訪問。

3.派生類構造函數

派生類名::派生類名(參數總表):基類名(參數表1),...,基類名n(參數表n),內嵌對象名1(內嵌對象參數表1),...,內嵌對象m(內嵌對象參數表m)
{
	派生類新增成員的初始化語句;
}

上述定義中,內嵌對象名和基類名順序是隨意的,實際調用順序是先基類構造函數(按照派生類聲明時的順序),後調用內嵌對象構造函數(按照成員在類中的聲明順序)。
析構函數的執行順序與構造函數正好嚴格相反。

4.多繼承下成員訪問
4.1 多個不同基類(這些基類沒有共同父類)的同名成員或者被覆蓋的同名成員,可以通過類作用域分辨
eg:

D1 d1;
d1.nV = 1;		//訪問子類自身的
d1.B1::nV = 2;  //訪問B1基類成員
d1.B2::nV = 3;  //訪問B2基類成員

4.2 如果某個派生類的部分或者全部直接基類從另一個共同的基類派生而來,這些基類繼承下來的成員就有相同名稱的多個不同副本,此時必須使用直接基類進行限定
比如B1和B2有共同基類B0,B0中有變量nV,D1同時繼承B1和B2,則

D1 d1;
d1.B1::nV=2;	//使用直接基類B1和B2限定
d1.B2::nV=3;

java中父類被覆蓋的成員只能通過巧用super()來實現訪問,無法直接訪問

5.虛基類
如4.2所述問題,將共同基類設置爲虛基類,這時從不同路徑繼承過來的同名數據成員就只有一個拷貝
class 派生類名:virtual 繼承方式 基類名
此時將上述B1和B2繼承方式聲明爲

class B1:virtual public B0{}
class B2:virtual public B0{}
d1.nV=2; //則d1中只有一個副本,可以使用d1.nV進行訪問

虛基類的構造函數會在最遠派生類構造函數(D1)之外的構造函數(B1和B2)被自動忽略,保證只被調用一次

6.賦值兼容
需要基類對象的任何地方可以使用公有派生類對象進行替代,替代後只能使用從基類繼承的成員。

多態

1.運算符重載
語法:

[friend] 函數類型 operator 運算符(參數表) //聲明爲成員函數,操作數減1,聲明爲友元函數,操作數不便
{
	函數體;
}

eg:

complex complex::operator +(complex c2){}            //成員函數
friend complex operator +(complex c1, complex c2){}  //友元函數

2.虛函數
語法:

virtual 函數類型 函數名(形參表)
{
	函數體
}

虛函數聲明只能出現在類聲明中的函數原型聲明中,不能出現在成員的函數體實現中
eg:

class B0
{
public:
	virtual void display(){cout << "B0::display()"<<endl;} //基類聲明虛函數,只能出現在聲明
}
class B1:public B0
{
public:
	void display();
}
void B1::display(){cout<<"B1::display()"<<endl;} //B1的虛函數實現
B0 *p,b0;
B1 b1;
p=&b0;
p->display(); //B0中的display()
p=&b1;
p->display(); //B1中的display()

java中可以直接用父類引用指向子類對象,通過調用被覆蓋的成員實現多態,這是因爲在java中父類被覆蓋的成員,對於子類來說是透明的,因此無需虛函數
C++的多態是在上述“6.賦值兼容”的條件下,滿足指針訪問和虛函數的條件下,才能夠實現。
C++中不能聲明虛構造函數,但能聲明虛析構函數。

3.抽象類
純虛函數有點類似java的抽象函數,沒有函數體:

virtual 函數類型 函數名(參數表)=0;

帶有純虛函數的類是抽象類。

羣體類

1.線性羣體
1.1.數組類:Array A(10);
1.2.鏈表類:Node *head=NULL;
1.3.棧類:Stack S;
1.4.循環隊列類:Queue Q;
2.容器
2.1向量:vector vint;
2.2雙端隊列:dqueue dqueue;
2.3標準棧:Stack <vector> Sk;
2.4標準隊列:queue<list> MyQueue;
2.5列表:list Link;

異常處理

語法:

throw 表達式
try
	複合語句
catch(異常類型聲明)
	複合語句
catch(異常類型聲明)
	複合語句
	...
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章