1. 程式人生 > >10、【C++】前向宣告、巢狀類、區域性類(內部類)

10、【C++】前向宣告、巢狀類、區域性類(內部類)

一、前向宣告

    在C++中,類需要先定義,而後才能被例項化,但是實際存在一種場景是:兩個類需要相互引用或相互成為類中的子物件成員時,就無法先定義使用,在編譯環節就出現錯誤導致編譯失敗,這時就需要用到前向宣告,此外,前向宣告的類不能被例項化。 【示例】

//A.h
#ifndef  _A_H
#define _A_H

#include "B.h"
class A
{
public:
    A(void);
    ~A(void);
    B b_; //A類中包含B類物件
};
#endif
//B.h
#ifndef _B_H 
#define _B_H 

/*B類包含A類物件,A類又包含B類物件時,標頭檔案也互相包含,這是不允許的,需要前向宣告:
 在B.h中將A類前向宣告,此時就不再需要包含A.h標頭檔案,且B中不能有A類的物件,因為前向聲
 明的類不能被例項化,但是可以是A類的指標或者引用*/
//#include "A.h" class A; //類A的前向宣告 class B { public: B(void); ~B(void); //A a_; //前向聲明後,B類中不能含有A的物件 A *a_; //可以是指標 void Fun(A &a ) //可以是引用 { } }; #endif

二、巢狀類

    顧名思義,巢狀類就是在類體中再定義另外一個類,形成類中類的情況。我們將最外層定義的類稱為外圍類外圍類內部再定義的類稱為巢狀類巢狀類的主要作用是為外圍類提供服務的,外圍類可以使用巢狀類物件作為外圍類的底層實現,同時可以對使用者隱藏該底層的實現。

巢狀類需要注意的幾點

    (1) 作用域上,巢狀類是定義在外圍類內部的,所以該類名只能在外圍類內部使用,如果在外圍類外部使用該類名時,需要加名字限定,如Out::Inner i;

    (2) 巢狀類中的成員函式可以在它的外部定義。

    (3) 巢狀類的成員函式對外圍類的資料成員沒有訪問權,反之亦然。因為巢狀類僅僅是語法上的嵌入,它與外圍類實際上是平級的。

下面是巢狀類的簡單例子:

class Outer //外圍類 
{ 
public: 
	class Inner //巢狀類
	{ 
	public: 
		void Fun() //也可以定義在外部 
		//{
			//cout << "Inner::Fun()"<<endl; 
//} }; public: Inner obj_; void Fun() { cout << "Outer::Fun() "<<endl; obj_.fun(); //巢狀類為外圍類提供服務,對使用者隱藏。 } }; //Inner::Fun() //Error, 注意作用域。Inner對外部不可見 void Outer::Inner::Fun() { cout << "Inner::Fun() << endl; } int main() { Outer o; //注意作用域,可以像使用其它類一樣使用巢狀類,它僅僅是語法上的嵌入. Outer::Inner i; o.Fun(); i.Fun(); return 0; }

三、區域性類

    區域性類是指在函式內部定義的類,這樣的類稱為區域性類local class,也稱內部類。區域性類只在定義它的區域性域內是可見的。此外,區域性類的成員函式必須定義在類體中,並且不能有靜態成員下面內部類的示例:

void Fun() 
{ 	
	//區域性類,只在函式內部有效 
	class LocalClass 
	{ 
	public: 
		int a_; 
		void Init(int &a ) //只能在類體中定義. 
		{ 
			a_ = a; 
		} 
		//static int b_; //Error,區域性類不能定義static靜態資料成員. 
	}; 

	LocalClass lc; 
	lc.Init(10); 
} 
int main() 
{ 
	Fun(); 
	LocalClass lc; //Error, 區域性類在函式外部不可用。 
}