1. 程式人生 > >C++基礎教程面向物件(學習筆記(15))

C++基礎教程面向物件(學習筆記(15))

類中的巢狀型別

考慮以下簡短程式:

#include <iostream>
 
enum FruitType
{
	APPLE,
	BANANA,
	CHERRY
};
 
class Fruit
{
private:
	FruitType m_type;
	int m_percentageEaten = 0;
 
public:
 
 
	Fruit(FruitType type) :
		m_type(type)
	{
	}
 
	FruitType getType() { return m_type;  }
	int getPercentageEaten() { return m_percentageEaten;  }
};
 
int main()
{
	Fruit apple(APPLE);
	
	if (apple.getType() == APPLE)
		std::cout << "I am an apple";
	else
		std::cout << "I am not an apple";
	
	return 0;
}

這個程式沒什麼問題。但是因為列舉FruitType意味著與Fruit類一起使用,所以讓它獨立於類本身存在有點奇怪。

巢狀型別

與不能巢狀在彼此內部的函式不同,在C ++中,可以在類中定義(巢狀)型別。為此,您只需在相應的訪問說明符下定義類中的型別。

這是與上面相同的程式,在類中定義了FruitType:

#include <iostream>
 
class Fruit
{
public:
	// Note: we've moved FruitType inside the class, under the public access specifier
	enum FruitType
	{
		APPLE,
		BANANA,
		CHERRY
	};
 
private:
	FruitType m_type;
	int m_percentageEaten = 0;
 
public:
 
 
	Fruit(FruitType type) :
		m_type(type)
	{
	}
 
	FruitType getType() { return m_type;  }
	int getPercentageEaten() { return m_percentageEaten;  }
};
 
int main()
{
	// Note: we access the FruitType via Fruit now
	Fruit apple(Fruit::APPLE);
	
	if (apple.getType() == Fruit::APPLE)
		std::cout << "I am an apple";
	else
		std::cout << "I am not an apple";
	
	return 0;
}

首先,請注意FruitType現在在類中定義。其次,請注意我們已在公共訪問說明符下定義它,因此可以從類外部訪問型別定義。

類本質上充當任何巢狀型別的名稱空間。在前面的例子中,我們能夠直接訪問列舉器APPLE,因為APPLE列舉器被置於全域性範圍內(我們可以通過使用列舉類而不是列舉來防止這種情況,在這種情況下我們已經通過訪問APPLE FruitType :: APPLE代替)。現在,因為FruitType被認為是類的一部分,我們通過在其前面加上類名稱來訪問APPLE列舉器:Fruit :: APPLE。

請注意,因為列舉類也像名稱空間一樣,如果我們將Fruit中的FruitType巢狀為列舉類而不是列舉,我們將通過Fruit :: FruitType :: APPLE訪問APPLE列舉器。

其他型別也可以巢狀

雖然列舉可能是巢狀在類中最常見的型別,但C ++允許您在類中定義其他型別,例如typedef,類型別名,甚至其他類!

與類的任何普通成員一樣,巢狀類對封閉類所執行的封閉類的成員具有相同的訪問許可權。但是,巢狀類對封閉類的“this”指標沒有任何特殊訪問許可權。

定義巢狀類並不常見,但C ++標準庫在某些情況下會這樣做,例如使用迭代器類。我們將在以後的課程中介紹迭代器。