嵌套类

一个类可以定义在另一个类的内部,前者称为嵌套类或者嵌套类型。嵌套类常用于定义作为实现部分的类。

嵌套类是一个独立的类,与外层类基本没有关。特别是,外层类的对象和嵌套类的对象是相互独立的:

  • 在嵌套类的对象中不包含任何外层类定义的成员。
  • 在外层类的对象也不包含任何嵌套类定义的成员。

嵌套类的名字在外层类作用域中是可见的,在外层类作用域之外不可见。和其它嵌套的名字一样,嵌套类的名字不会和别的作用域中的同一个名字冲突。

嵌套类也使用访问限定符来控制外界对成员的访问权限:

  • 外层类对嵌套类的成员没有特殊的访问权限。
  • 嵌套类对外层类的成员也没有特殊的访问权限。

嵌套类在其外层类中定义了一个类型成员,该类型的访问权限由外层类决定:

  • 位于外层类 public 部分的嵌套类型实际上定义了一种可以随处访问的类型。
  • 位于外层类 protected 部分的嵌套类定义的类型只能被外层类及其友元和派生类访问。
  • 位于外层类 private 部分的嵌套类定义的类型只能被外层类的成员和友元访问。

声明和定义一个嵌套类

声明一个嵌套类

class TextQuery {
public:
	class QueryResult;	//@ 声明一个嵌套类
};

在外层类之外定义一个嵌套类

嵌套类必须声明在类的内部,但是可以定义在类的内部或者外部。

在外层类之外定义一个嵌套类时,必须以外层类的名字限定嵌套类的名字:

class TextQuery::QueryResult {
	//@ 参数 QueryResult 位于类的作用域内,因此不需要加限定符
	friend std::ostream& print(std::ostream&, const QueryResult&);
public:
	//@ 嵌套类可以直接使用外层类的成员,无须对该成员的名字进行限定
	QueryResult(std::string,
		std::shared_ptr<std::set<line_no>>,
		std::shared_ptr<std::vector<std::string>>);
};

line_no 属于 TextQuery 的成员,QueryResult 可以直接访问它而不必再定义一次。

定义嵌套类的成员

TextQuery::QueryResult::QueryResult(std::string s,
	std::shared_ptr<std::set<line_no>> p,
	std::shared_ptr<std::vector<std::string>> f):
	sought(s),lines(p),file(f){ }

嵌套类的静态成员定义

如果 QueryResult 声明了一个静态成员,则该成员的定义位于 TextQuery 的作用域之外。

int TextQuery::QueryResult::static_mem = 1024;

嵌套类作用域中的名字查找

嵌套类是其外层类的一个类型成员,因此外层类的成员可以像使用任何其它类型成员一样使用嵌套类的名字。QueryResult 嵌套在 TextQuery 中,所以 TextQuery 的成员可以直接使用名字 QueryResult 。

TextQuery::QueryResult
TextQuery::query(const string& sought) const
{
	static shared_ptr<set<line_no>> nodata(new set<line_no>);
	auto loc = wm.find(sought);
	if (loc == wm.end())
		return QueryResult(sought, nodata, file);
	else
		return QueryResult(sought, loc->second, file);
}

嵌套类和外层类是相互独立的

尽管嵌套类定义在其外层类的作用域中,但是外层类的对象和嵌套类的对象没有任何关系:

  • 嵌套类的对象只包含嵌套类定义的成员。
  • 外层类的对象只包含外层类定义的成员,在外层类对象中不会有任何嵌套类的成员。
原文地址:https://www.cnblogs.com/xiaojianliu/p/12484826.html