При определении вложенного класса вне его содержащего класса следует квалифицировать имя вложенного класса именем его содержащего класса:
//
class TextQuery::QueryResult {
//
//
friend std::ostream&
print(std::ostream&, const QueryResult&);
public:
//
//
//
QueryResult(std::string,
std::shared_ptr
std::shared_ptr
//
};
Единственное изменение, внесенное в первоначальный класс, заключается в том, что в классе QueryResult
больше не определяется переменная-член line_no
. Члены класса QueryResult
могут обращаться к этому имени непосредственно в классе TextQuery
, таким образом, нет никакой необходимости определять его снова.
В этой версии конструктор QueryResult()
не определяется в теле класса. Чтобы определить конструктор, следует указать, что класс QueryResult
вложен в пределы класса TextQuery
. Для этого имя вложенного класса квалифицируют именем содержащего его класса:
//
//
TextQuery::QueryResult::QueryResult(string s,
shared_ptr
shared_ptr
sought(s), lines (p), file(f) { }
Читая имя функции справа налево, можно заметить, что это определение конструктора для класса QueryResult
, который вложен в пределы класса TextQuery
. Сам код только сохраняет данные аргументов в переменных-членах и не делает больше ничего.
Если бы класс QueryResult
объявлял статический член, его определение находилось бы вне области видимости класса TextQuery
. Например, статический член класса QueryResult
был бы определен как-то так:
//
//
int TextQuery::QueryResult::static_mem = 1024;
Во вложенном классе выполняются обычные правила поиска имен (см. раздел 7.4.1). Конечно, поскольку вложенный класс — это вложенная область видимости, для поиска у него есть дополнительные области видимости в содержащем классе. Такое вложение областей видимости объясняет, почему переменная-член line_no
не определялась во вложенной версии класса QueryResult
. Первоначальный класс QueryResult
определял этот член для того, чтобы его собственные члены могли избежать необходимости записи TextQuery::line_no
. После вложения определения класса результатов в класс TextQuery
такое определение типа больше не нужно. Вложенный класс QueryResult
может обратиться к переменной line_no
без указания, что она определена в классе TextQuery
.
Как уже упоминалось, вложенный класс — это тип-член содержащего его класса. Члены содержащего класса могут использовать имена вложенного класса таким же образом, как и любой другой тип-член. Поскольку класс QueryResult
вложен в класс TextQuery
, функция-член query()
класса TextQuery
может обращаться к имени QueryResult
непосредственно:
//
//
TextQuery::QueryResult
TextQuery::query(const string &sought) const {
//
//
static shared_ptr