Локальные и вложенные классы
Локальные классы. Класс можно описать в определении функции, такой класс называется локальным. Имя локального класса считается локальным в объемлющей области видимости, а областью видимости локального класса является объемлющая область видимости. В описаниях локального класса из объемлющей области видимости можно использовать только имена типов, статических переменных, внешних переменных и функций, а также элементы перечисления. Приведем пример: int x; void f() { static int s; int x; extern int g(); struct local { int h() { return x; } // ошибка: ’x’ автоматическая int j() { return s; } // нормально int k() { return::x; } // нормально int l() { return g(); } // нормально } } Объемлющая функция не имеет особых прав доступа к членам локального класса, она подчиняется обычным правилам доступа. Функцию-член локального класса следует определять в определении этого класса. Локальный класс не может иметь статических членов, представляющих данные. Вложенные классы Класс можно описать в описании другого класса. Такой класс называют вложенным. Имя вложенного класса локально по отношению к объемлющему классу. Вложенный класс находится в области видимости объемлющего класса. Если не считать явного использования указателей, ссылок или имен объектов, то в описаниях вложенного класса допустимы только имена типов, статических членов и элементов перечисления из объемлющего класса. int x; int y; class enclose { public: int x; static int s; class inner { void f(int i) { x = i; // ошибка: присваивание enclose::x s = i; // нормально: присваивание enclose::s ::x = i; // нормально: присваивание глобальному x y = i; // нормально: присваивание глобальному y } void g(enclose* p, int i) { p->x = i; // нормально: присваивание enclose::x } }; }; inner* p = 0; // ошибка: `inner' вне области видимости
Функции-члены вложенного класса не имеют особых прав доступа к членам объемлющего класса, они подчиняются обычным правилам доступа. Аналогично, функции-члены объемлющего класса не имеют особых прав доступа к членам вложенного класса и подчиняются обычным правилам доступа. Функции-члены и представляющие данные, статические члены из вложенного класса можно определить в глобальной области видимости. Подобно функции-члену дружественная функция, определенная в данном классе, находится в области видимости этого класса. Она подчиняется тем же правилам связывания имен, что и функции-члены (они указаны выше), и не имеет так же как они особых прав доступа к членам объемлющего класса и к локальным переменным функций этого класса.
Специальный вид методов класса - конструкторы и деструкторы. Некоторые особенности конструкторов и деструкторов Конструкторы класса Конструктор - неотъемлемый компонент класса. Нет классов, задающих тип данных и не имеющих конструкторов. Конструктор представляет собой специальный метод класса, позволяющий создавать объекты класса. У конструкторов две синтаксические особенности:
Из первого свойства следует, что конструкторы класса представляют собой множество перегруженных методов и должны отличаться сигнатурой - числом аргументов либо типами аргументов. Чтобы справиться с этим ограничением, иногда приходится в один из конструкторов добавлять фиктивный аргумент, изменяя тем самым его сигнатуру. Если в классе явно не задан ни один конструктор, то к классу автоматически добавляется конструктор по умолчанию - конструктор без аргументов. Заметьте, что если в классе явно определен один или несколько конструкторов, то автоматического добавления конструктора без аргументов не происходит.
Большинство конструкторов класса имеют модификатор доступа public Person pers1 = new Person(), pers2 = new Person();Person pers3= new Person("Петрова");
Сущности pers1, pers2, pers3 класса Person объявляются с инициализацией, задаваемой унарной операцией new, которой в качестве аргумента передается конструктор класса Person. У класса Person несколько конструкторов - это типичная практика, - отличающихся сигнатурой. В данном примере в первой строке вызывается конструктор без аргументов, во второй строке для сущности pers3 вызывается конструктор с одним аргументом типа string. Конструктор может быть объявлен с атрибутом private. Понятно, что в этом случае внешний пользователь не может применить его для создания объектов. Но это могут делать методы класса, создавая объекты для собственных нужд со специальной инициализацией. Можно отметить, что объекты создаются динамически в процессе выполнения программы, для создания объекта всегда вызывается тот или иной конструктор класса. В Си++ есть возможность гарантированного освобождения занятых объектом ресурсов при выходе объекта из области его жизни, т.е. гарантированное разрушение. Для такого разрушения используется деструктор. Синтаксически это функция с именем ~MyClass: class C{public: ~C();};
Деструктор вызывается когда-то для любого объекта. Как и с конструктором, нельзя брать адрес деструктора и он не возвращает значений (даже void). Деструкторы не наследуются. Если у класса не написан деструктор явно - он генерится компилятором, сгенеренный деструктор аналогичен пустому телу - ~C() {} Деструкторы могут быть виртуальными, и это рекомендуется практически всегда, кроме случаев, когда у класса вообще нет виртуальных методов. Тело деструктора должно разрушить все поля объекта - позвать close(), CloseHandle, ->Release() и тому подобные функции. Деструктор может быть объявлен private. Объекты такого класса могут создаваться только оператором new без квадратных скобок, любая другая попытка создания даст ошибку "разрушение невыполнимо-деструктор приватен". Такие объекты должны иметь метод разрушения, в котором будет исполняться delete this;
Воспользуйтесь поиском по сайту: ©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|