类中的嵌套类型
考虑以下简短程序:
#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 ++标准库在某些情况下会这样做,例如使用迭代器类。我们将在以后的课程中介绍迭代器。