1、嵌套类
类定义中不仅仅可以包含成员函数与数据成员。也可以包含嵌套类与struct,类型别名,以及枚举。在类中声明的任何东西都在类范围内。如果它是public,可以通过className::的范围解析语法来在类外进行访问。
可以在另一个类定义中提供一个类定义。例如,你可能决定 让SpreadsheetCell类成为Spreadsheet类的一部分。由于它变成了Spreadsheet类的一部分,你可能也会重新将其命名为Cell。可以将它们定义成这样子:
cpp
export class Spreadsheet
{
public:
class Cell
{
public:
Cell() = default;
Cell(double initialValue);
// Remainder omitted for brevity
};
Spreadsheet(std::size_t width, std::size_t height,
const SpreadsheetApplication& theApp);
// Remainder of Spreadsheet declarations omitted for brevity
};
现在,Cell类定义在了Spreadsheet类的内部,所以在Spreadsheet类之外对Cell的任何动作,必须给出Spreadsheet::的范围名。即使对于成员函数定义也一样。例如,Cell的double构造函数看起来像这样:
cpp
Spreadsheet::Cell::Cell(double initialValue)
: m_value { initialValue }
{
}
甚至对于Spreadsheet类自身的成员函数的返回类型(不是参数)也要使用这个语法:
cpp
const Spreadsheet::Cell& Spreadsheet::getCellAt(size_t x, size_t y) const
{
verifyCoordinate(x, y);
return m_cells[x][y];
}
在Spreadsheet类内部直接完整地定义嵌套Cell类舍不得Spreadsheet类定义有一点儿臃肿。可以通过只包含一个Spreadsheet类的Cell的前向声明来简化,然后对Cell类进行单独定义,如下:
cpp
export class Spreadsheet
{
public:
class Cell;
Spreadsheet(std::size_t width, std::size_t height,
const SpreadsheetApplication& theApp);
// Remainder of Spreadsheet declarations omitted for brevity
};
class Spreadsheet::Cell
{
public:
Cell() = default;
Cell(double initialValue);
// Omitted for brevity
};
2、类中枚举
枚举也可以成为类中的数据成员。例如,可以添加SpreadsheetCell类的cell颜色如下:
cpp
export class SpreadsheetCell
{
public:
// Omitted for brevity
enum class Color { Red = 1, Green, Blue, Yellow };
void setColor(Color color);
Color getColor() const;
private:
// Omitted for brevity
Color m_color{ Color::Red };
};
setColor()与getColor()成员函数的实现很直接:
cpp
void SpreadsheetCell::setColor(Color color) { m_color = color; }
SpreadsheetCell::Color SpreadsheetCell::getColor() const { return m_color; }
新的成员函数使用如下:
cpp
SpreadsheetCell myCell { 5 };
myCell.setColor(SpreadsheetCell::Color::Blue);
auto color { myCell.getColor() };