Чтение онлайн

на главную - закладки

Жанры

Программирование на Objective-C 2.0
Шрифт:

В программе 10.2 определение класса Fraction расширяется за счет добавления двух новых методов. Метод класса allocF выделяется память для нового объекта типа Fraction и следит за числом дробей (объектов Fraction), которые он выделил, а метод count возвращает значение этого счетчика. Метод count тоже является методом класса. Его можно было бы реализовать как метод экземпляра, но лучше запросить класс, сколько экземпляров он выделил, вместо передачи сообщения определенному экземпляру этого класса.

Ниже приводятся объявления для двух новых методов класса, добавленные в файл Fraction.h. +(Fraction *) allocF; +(int) count;

Отметим, что здесь не замещается наследуемый метод alloc; вместо этого определяется наш собственный метод выделения памяти. В этом методе будет использоваться наследуемый метод alloc. Следующий код нужно поместить в файл секции implementation Fraction.m. static int gCounter; @implementation Fraction +(Fraction *) allocF { extern int gCounter; ++gCounter; return [Fraction alloc]; } +(int) count { extern int gCounter; return gCounter; } // здесь находятся другие методы из класса Fraction @end

Примечание. В практике надежного программирования не принято замещать метод alloc, поскольку он работает с физическим местоположением в памяти. Не следует вмешиваться в работу системы на этом уровне.

Объявление static для переменной gCounter делает ее доступной для любого метода, определенного в секции implementation, но при этом она недоступна вне этого файла. Метод allocF просто наращивает значение переменной gCounter и затем использует метод alloc для создания новой дроби (Fraction), возвращая результат. Метод count просто возвращает значение счетчика (gCounter), не давая пользователю непосредственный доступ к этой переменной.

Напомним, что объявления extern не требуются в этих методах, поскольку переменная gCounter определена внутри этого файла. Это просто помогает читателю метода понять, что выполняется доступ к переменной, определенной вне метода. Префикс g в имени переменной предназначен для той же цели, поэтому большинство программистов обычно не включают объявления extern. В программе Ю.2 выполняется тестирование этих методов. #import "Fraction.h" int main (int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; Fraction *a, *b, *c; NSLog (@"Fractions allocated: %i", [Fraction count]); a = [[Fraction allocF] init]; b = [[Fraction allocF] init]; c = [[Fraction allocF] init]; NSLog (@"Fractions allocated: %i", [Fraction count]); [a release]; [b release]; [c release]; [pool drain]; return 0; }

Вывод программы 10.2 Fractions allocated: 0 (Выделено объектов Fraction) Fractions allocated: 3

Когда начинается выполнение этой программы, значение gCounter автоматически задается равным 0 (напомним, что вы можете замещать наследуемый метод инициализации класса, если хотите выполнить специальную инициализацию класса в целом, например, присвоить статическим переменным некоторые ненулевые значения). После выделения (и последующей инициализации) трех объектов типа Fraction с помощью метода allocF метод count считывает переменную counter, значение которой действительно стало равным 3. Вы можете добавить метод-установщик (setter) для этого класса, если хотите выполнять сброс счетчика или задавать для него определенное значение, но в данном случае это не требуется. 10.3. Описатели хранения для класса

Вы уже познакомились с описателями хранения для класса, которые можно помещать перед именами переменных. Здесь мы рассмотрим другие описатели, которые предоставляют компилятору информацию о предполагаемом использовании переменной в программе. auto

Это ключевое слово используется для объявления автоматической локальной переменной (в противоположность статической). Это описатель по умолчанию для объявления переменной внутри функции или метода, но никто не использует его в явном виде. auto int index;

Это объявление переменной index как автоматической локальной переменной; это означает, что для нее выполняется автоматическое выделение памяти при входе в блок (которым может быть заключенная в фигурные скобки последовательность операторов, метод или функция) и автоматическое освобождение при выходе из этого блока. Поскольку это происходит по умолчанию внутри блока, оператор int index;

эквивалентен оператору auto int index;

В отличие от статических переменных, которые имеют по умолчанию начальные значения 0, автоматические переменные остаются неопределенными, пока вы не присвоите им значения в явном виде. const

Компилятор позволяет связывать атрибут const с переменными, значения которых не будут изменяться. Иначе говоря, он сообщает компилятору, что указанные переменные имеют постоянное значение при выполнении программы. Если попытаться присвоить значение переменной, объявленной с атрибутом const, после инициализации, или попытаться выполнить ее наращивание или уменьшение, компилятор выдаст предупреждающее сообщение. Ниже в переменной pi используется атрибут const: const double pi = 3.141592654;

Он указывает компилятору, что программа не будет изменять эту переменную. Естественно, значение такой переменной должно быть инициализировано при ее определении.

Определение переменной с атрибутом const указывает читателю, что программа не будет изменять значение этой переменной. volatile

Это описатель, противоположный const. Он в явном виде указывает компилятору, что соответствующая переменная будет изменять свое значение. Он включен в язык Objective-C, чтобы компилятор не оптимизировал операторы, которые кажутся избыточными, и выполнял повторную проверку переменной, когда ее значение, казалось бы, не изменяется. Типичный пример — порт ввода-вывода, (I/O) (подробнее см. главу 13).

Предположим, что у вас имеется адрес выходного порта, хранящегося в программе в переменной с именем outPort. Записать в этот порт два символа, например 0 и N, можно с помощью следующего кода. *outPort = 'O’; *outPort = ’N’;

В первой строке указывается, что символ 0 нужно сохранить по адресу памяти, указанному переменной outPort. Во второй строке указывается, что символ N нужно сохранить по тому же адресу. Оптимизирующий компилятор может заметить, что это две последовательные записи по одному адресу, и поскольку outPort между ними не изменяется, может просто удалить первый оператор из программы. Чтобы этого не произошло, нужно объявить переменную outPort с атрибутом volatile, например: volatile char *outPort; 10.4. Перечислимые типы данных

Поделиться:
Популярные книги

Личный аптекарь императора. Том 5

Карелин Сергей Витальевич
5. Личный аптекарь императора
Фантастика:
городское фэнтези
попаданцы
аниме
сказочная фантастика
фэнтези
7.50
рейтинг книги
Личный аптекарь императора. Том 5

Кодекс Охотника. Книга II

Винокуров Юрий
2. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
боевая фантастика
юмористическое фэнтези
5.00
рейтинг книги
Кодекс Охотника. Книга II

Студент из прошлого тысячелетия

Еслер Андрей
2. Соприкосновение миров
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Студент из прошлого тысячелетия

Последний Герой. Том 5

Дамиров Рафаэль
5. Последний герой
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Последний Герой. Том 5

На границе империй. Том 8

INDIGO
12. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 8

Адвокат Империи 14

Карелин Сергей Витальевич
14. Адвокат империи
Фантастика:
городское фэнтези
аниме
попаданцы
5.00
рейтинг книги
Адвокат Империи 14

Ваше Сиятельство 4т

Моури Эрли
4. Ваше Сиятельство
Любовные романы:
эро литература
5.00
рейтинг книги
Ваше Сиятельство 4т

Кодекс Охотника

Винокуров Юрий
1. Кодекс Охотника
Фантастика:
фэнтези
юмористическое фэнтези
попаданцы
боевая фантастика
5.00
рейтинг книги
Кодекс Охотника

Алые перья стрел

Крапивин Владислав Петрович
Детские:
детские приключения
8.58
рейтинг книги
Алые перья стрел

Кодекс Крови. Книга VII

Борзых М.
7. РОС: Кодекс Крови
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга VII

Черный Маг Императора 14

Герда Александр
14. Черный маг императора
Фантастика:
аниме
сказочная фантастика
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Черный Маг Императора 14

Древесный маг Орловского княжества 3

Павлов Игорь Васильевич
3. Орловское княжество
Фантастика:
аниме
сказочная фантастика
фэнтези
попаданцы
гаремник
5.00
рейтинг книги
Древесный маг Орловского княжества 3

Снайпер

Поселягин Владимир Геннадьевич
3. Жнец
Фантастика:
боевая фантастика
попаданцы
5.60
рейтинг книги
Снайпер

Элизиум. Аликс и монеты

Андерсон Александр
1. Элизиум
Фантастика:
фэнтези
сказочная фантастика
8.98
рейтинг книги
Элизиум. Аликс и монеты