С++ для начинающих




.Вложенные классы * - часть 5


   // должен использоваться через объект или указатель на тип List

   value = init( val );   // ошибка: неверное использование init

};

При использовании нестатических членов класса компилятор должен иметь возможность идентифицировать объект, которому принадлежит такой член. Внутри функции-члена класса ListItem указатель this неявно применяется лишь к его членам. Благодаря неявному this мы знаем, что член value относится к объекту, для которого вызван конструктор. Внутри конструктора ListItem указатель this имеет тип ListItem*. Для доступа же к функции-члену init() нужен объект типа List или указатель типа List*.

Следующая функция-член mf() обращается к init() с помощью параметра-ссылки. Таким образом, init() вызывается для объекта, переданного в аргументе функции:

void List::ListItem::mf( List &i1 ) {

   memb = i1.init();   // правильно: обращается к init() по ссылке

}

Хотя для доступа к нестатическим членам объемлющего класса нужен объект, указатель или ссылка, к статическим его членам, именам типов и элементам перечисления вложенный класс может обращаться напрямую (если, конечно, эти члены открыты). Имя типа – это либо имя typedef, либо имя перечисления, либо имя класса. Например:

class List {

public:

   typedef int (*pFunc)();

   enum ListStatus { Good, Empty, Corrupted };

   //...

private:

   class ListItem {

   public:

      void check_status();

      ListStatus status;     // правильно

      pFunc action;   // правильно

      // ...

   };

   // ...

};

pFunc, ListStatus и ListItem – все это вложенные имена типов в области видимости объемлющего класса List. К ним, а также к элементам перечисления ListStatus можно обращаться в области видимости класса ListItem даже без квалификации:

void List::ListItem::check_status()

{

   ListStatus s = status;

   switch ( s ) {

      case Empty: ...

      case Corrupted: ...

      case Good: ...

   }

}

Вне области видимости ListItem и List при обращении к статическим членам, именам типов и элементам перечисления объемлющего класса требуется оператор разрешения области видимости:

List::pFunc myAction;  // правильно

List::ListStatus stat = List::Empty;   // правильно

При обращении к элементам перечисления мы не пишем:

List::ListStatus::Empty

поскольку они доступны непосредственно в той области видимости, в которой определено само перечисление. Почему? Потому что с ним, в отличие от класса, не связана отдельная область.




Содержание  Назад  Вперед