×
Traktatov.net » Язык программирования C++. Пятое издание » Читать онлайн
Страница 685 из 714 Настройки
вложен в пределы класса >TextQuery. Для этого имя вложенного класса квалифицируют именем содержащего его класса:

>// определение члена класса по имени QueryResult для класса по

>// имени QueryResult, вложенного в класс TextQuery

>TextQuery::QueryResult::QueryResult(string s,

>                                    shared_ptr> p,

>                                    shared_ptr> f):

> sought(s), lines (p), file(f) { }

Читая имя функции справа налево, можно заметить, что это определение конструктора для класса >QueryResult, который вложен в пределы класса >TextQuery. Сам код только сохраняет данные аргументов в переменных-членах и не делает больше ничего.

Определение статических членов вложенных классов

Если бы класс >QueryResult объявлял статический член, его определение находилось бы вне области видимости класса >TextQuery. Например, статический член класса >QueryResult был бы определен как-то так:

>// определение статического члена типа int класса QueryResult

>// вложенного в класс TextQuery

>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 непосредственно:

>// тип возвращаемого значения должен указать, что класс QueryResult

>// теперь вложенный

>TextQuery::QueryResult

>TextQuery::query(const string &sought) const {

> // если искомое значение не найдено, возвратить указатель на этот

> // набор

> static shared_ptr> nodata(new set);

> // во избежания добавления слов к wm использовать поиск, а не

> // индексирование!

> auto loc = wm.find(sought);

> if (loc == wm.end())

>  return QueryResult(sought, nodata, file); // не найдено

> else

>  return QueryResult(sought, loc->second, file);

>}

Как обычно, тип возвращаемого значения не находится в области видимости класса (см. раздел 7.4), поэтому сразу было обращено внимание на то, что функция возвращает значение типа >TextQuery::QueryResult. Но в теле функции к типу >QueryResult можно обращаться непосредственно, как это сделано в операторах >return