C++开发初级
1323 浏览 5 years, 10 months
7 嵌套类
版权声明: 转载请注明出处 http://www.codingsoho.com/嵌套类
类定义不仅可以包含方法以及成员,您还可以编写嵌套类以及嵌套结构、声明typedef或者创建枚举类型。类中声明的一切内容都具有类作用域。如果声明的内容是public,那么可以在类外面使用ClassName::作用域解析语法访问。 可在类的定义中提供另一个类定义。例如,您可能认为SpreadsheetCell类实际上是Spreadsheet类的一部分,可以这样定义这两个类:
class Spreadsheet
{
public:
class SpreadsheetCell
{
public:
SpreadsheetCell();
SpreadsheetCell(double initialValue);
// .......
protected:
double mValue;
string mString;
mutable int mNumAccesses;
};
Spreadsheet(const SpreadsheetApplication& theApp,
int inWidth = kMaxWidth, int inHeight = kMaxHeight);
Spreadsheet(const Spreadsheet& src);
~Spreadsheet();
// ......
};
代码取自 NestedClasses\Spreadsheet.h
现在SpreadsheetCell类定义位于Spreadsheet类内部,因此在Spreadsheet类外面引用SpreadsheetCell必须用Spreadsheet::作用域限定名称,即使在方法定义的时候也是如此。例如,默认构造函数应该是这样的:
Spreadsheet::SpreadsheetCell::SpreadsheetCell() : mValue(0), mNumAccesses(0)
{
}
代码取自 NestedClasses\Spreadsheet.h
这个语法很笨拙。例如, SpreadsheetCell()运算符的定义应该是这样的:
Spreadsheet::SpreadsheetCell& Spreadsheet::SpreadsheetCell::operator=(const SpreadsheetCell& rhs)
{
if (this == &rhs) {
return *this;
}
mValue = rhs.mValue;
mString = rhs.mString;
mNumAccesses = rhs.mNumAccesses;
return *this;
}
代码取自 NestedClasses\Spreadsheet.cpp
实际上,在Spreadsheet类中方法的返回类型(不是参数)也必须使用这一语法:
Spreadsheet::SpreadsheetCell Spreadsheet::getCellAt(int x, int y)
{
if (!inRange(x, mWidth) || !inRange(y, mHeight)) {
throw std::out_of_range("");
}
return mCells[x][y];
}
代码取自 NestedClasses\Spreadsheet.cpp
为了避免这一笨拙的语法,可以使用typedef
将Spreadsheet::SpreadsheetCell重命名为容易管理的名称,例如SCell:
typedef Spreadsheet::SpreadsheetCell SCell;
代码取自 NestedClasses\Spreadsheet.h
应该在Spreadsheet类定义的外部,否则就必须用Spreadsheet::将typedef名称本身限定为Spreadsheet:: SCell,这样做并没有什么好处!
现在,构造函数看起来应该是这样的:
SCell::SpreadsheetCell() : mValue(0), mNumAccesses(0)
{
}
代码取自 NestedClasses\Spreadsheet.cpp
普通的访问控制也适用于嵌套类定义。如果声明了private或者protected嵌套类,这个类只能在包含它的类中使用。
通常嵌套类定义只适用于微小的类。如果将类似于SpreadsheetCell的类作为嵌套类实在是太笨拙了。