13.12. Локальные классы A

13.12. Локальные классы A

Класс, определенный внутри тела функции, называется локальным. Он виден только в той локальной области, где определен. Не существует синтаксиса, позволяющего обратиться к члену такого класса, в отличие от вложенного, извне локальной области видимости, содержащей его определение. Поэтому функции-члены локального класса должны определяться внутри определения самого класса. На практике это ограничивает их сложность несколькими строками кода; помимо всего прочего, такой код становится трудно читать.

Поскольку невозможно определить член локального класса в области видимости пространства имен, то в таком классе не бывает статических членов.

Класс, вложенный в локальный, может быть определен вне определения объемлющего класса, но только в локальной области видимости, содержащей это определение. Имя вложенного класса в таком определении должно быть квалифицировано именем объемлющего класса. Объявление вложенного класса в объемлющем нельзя опускать:

void foo( int val )

{

class Bar {

public:

int barVal;

class nested; // объявление вложенного класса обязательно

};

// определение вложенного класса

class Bar::nexted {

// ...

};

}

У объемлющей функции нет никаких специальных прав доступа к закрытым членам локального класса. Разумеется, это можно обойти, объявив ее другом данного класса. Однако необходимость делать его члены закрытыми вообще сомнительна, поскольку часть программы, из которой разрешается обратиться к нему, весьма ограничена. Локальный класс инкапсулирован в своей локальной области видимости. Дальнейшая инкапсуляция путем сокрытия информации не требуется: вряд ли на практике найдется причина, по которой не все члены локального класса должны быть открыты.

У локального класса, как и у вложенного, ограничен доступ к именам из объемлющей области видимости. Он может обратиться только к именам типов, статических переменных и элементов перечислений, определенных в объемлющих локальных областях. Например:

int a, val;

void foo( int val )

{

static int si;

enum Loc { a = 1024, b };

class Bar {

public:

Loc locVal; // правильно

int barVal;

void fooBar ( Loc l = a ) { // правильно: Loc::a

barVal = val; // ошибка: локальный объект

barVal = ::val; // правильно: глобальный объект

barVal = si; // правильно: статический локальный объект

locVal = b; // правильно: элемент перечисления

}

};

// ...

}

Имена в теле локального класса разрешаются лексически путем поиска в объемлющих областях видимости объявлений, предшествующих определению такого класса. При разрешении имен, встречающихся в телах его функций-членов, сначала просматривается область видимости класса, а только потом – объемлющие области,

Как всегда, если первое найденное объявление таково, что употребление имени оказывается некорректным, поиск других объявлений не производится. Несмотря на то что использование val в fooBar() выше является ошибкой, глобальная переменная val не будет найдена, если только ее имени не предшествует оператор разрешения глобальной области видимости.

2014-09-07 13:25:31 Евгений

Вот это да, почитаю спасибо )

2013-11-01 03:57:59 Сергей

Спасибо за данное пособие, благодаря ему наконец то смог понять классы:)

2012-11-02 15:24:04 Pavel

спасибо за материал.ТО что нужно))

2012-06-08 07:31:08 cmd

Хороший материал

2012-03-27 20:42:52 Слава

Очень полезный материал и объяснено на доступном языке!!!

2012-01-31 09:33:40 Ivan

Пробуем:)

2012-01-03 03:10:13 Ion Botezatu

Супер, мне очень помог этот материа! Спосибо авторам!

2011-12-03 00:14:08 Makc

Отличный материал, спасибо за проделанную работу!

2011-10-05 21:44:13 Андрей

Отличный текст и всё нужно в одном месте. Часто пользуюсь! Спасибо.

2011-05-23 20:40:57 я

Спасибо!

2011-04-17 10:31:54 Аза

Спасибо за материал