Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология Образование Политология Производство Психология Стандартизация Технологии |
Глава 15. Создание указателей на объекты 169
<< « int main(int argc,
cout << "Считываем социального страхования \п" « "Введите в поле имени для
// создадим объект класса NameDataSet NameDataSet* pNDS; while (pNDS getDataO) f // добавим его в конец списка объектов // NameDataSet
// поочередно выведем все элементы списка // (выполнение прекратится, когда указатель // на следующий элемент будет равен нулю) cout « "Элементы:\п"; pNDS pHead;
// отобразим текущий элемент
// получим адрес элемента pNDS pNDS->pNext; return 0;
Несмотря на внушительную длину, программа относительно про- ста. Функция main () начинается с вызова функции getData (), которая считывает эле- мент NameDataSet с клавиатуры. Если пользователь вводит строку "exit " в поле име- ни, getData () возвращает ноль. Функция main (} вызывает функцию addTail (), бы добавить элемент, который вернула getData (), в конец связанного списка. Если от пользователя больше не поступает элементов NameDataSet, функция main () выводит на экран все элементы списка, используя функцию displayDat a (). Функция выделяет из кучи пустой объект класса NameDataSet. После этого getData () ожидает ввода имени для записи его в соответствующее поле нового объекта. Если пользователь вводит в поле имени строку "exit" , функция уничтожает последний созданный объект и возвращает 0. В противном случае считы- вает фамилию и номер социального страхования, после чего обнуляет указатель pNext и передает управление вызывающей функции. Никогда не оставляйте связывающие указатели не проинициализирован- ными! Старая поговорка программистов гласит: "Не уверен обнули".
Функция addTai l () из приведенного примера схожа с предыдущей версией addTail О, однако в отличие от нее она проверяет, не является ли данный список пустым. Если указатель pHead нулевой, то addTail О записывает в него указатель на текущий элемент и прекращает выполнение. Функция displayDat a () неоднократно встречалась нам ранее.
170 Часть "Классическое" программирование Глава Защищенные члены не беспокоить! Защищенные члены Чем хороши защищенные члены Обращение к защищенным членам
главе 13, "Классы в C++", рассматривалась концепция классов. Ключевое слово publi c было описано как часть объявления класса, т.е. просто как то, что следу- ет делать. В этой главе вы узнаете, что ключевому слову publi c есть альтернативы.
Защищенныечлены Члены класса могут быть помечены как защищенные, что делает их недоступ- ными извне класса. В отличие от защищенных, открытые (public ) члены класса доступны для всех.
Зачем нужны защищенные члены Для того чтобы понять смысл защиты членов класса, нужно вспомнить, каковы цели объектно-ориентированного программирования. Зашита внутренних элементов класса от внешних функций. Ведь когда вы проектируете микроволновую печь (или что-нибудь другое), то ос- ? нащаете ее по возможности простым интерфейсом с внешним миром и прячете содержимое в металлический ящик. Так делается для того, | чтобы другие не могли поломать микроволновую печь. Защита членов 1 класса выполняет роль железного ящика. Создание класса, способного полноценно управлять своими внутрен- ними членами. Несколько непоследовательно требовать от класса пол- ноценной работы и ответственности за ее результаты и одновременно позволять внешним функциям манипулировать его внутренними чле- нами (это то же самое, что и требовать от создателя микроволновой пе- чи нести ответственность за мои непрофессиональные манипуляции I с элементами ее внутреннего устройства). Сокращение до минимума внешнего интерфейса класса. Гораздо проще изучать и использовать класс, который имеет ограниченный интерфейс (а интерфейсом класса являются его открытые члены). Защищенные члены скрыты от пользователя, и их не надо помнить (в противном | случае интерфейсом становится весь класс). Такой подход называется которая описана в главе 8, "Первое знакомство с указате- в C++" . Глава 16. Защищенные члены класса: не беспокоить! 171 Уменьшение уровня взаимосвязи между классом и внешней I мой. Ограничив взаимосвязь класса с внешним кодом, при мости гораздо проще заменить класс каким-либо другим.
Я так и слышу, как поклонники функционального подхода говорят: "Не нужно лать ничего противоестественного! Достаточно потребовать от программиста, чтобы он попросту не трогал некоторые члены класса". Все это верно в теории, однако не оправдывается на практике. Программисты на- чинают писать программы, будучи переполненными благих намерений, однако при- ближение сроков сдачи программы заставляет их все больше разочаровываться в сутствии возможности прямого доступа к защищенным членам класса.
Как устроены защищенные члены Добавление в класс ключевого слова publi c делает все находящиеся за ним члены класса открытыми, а значит, доступными для функций — не членов класса. Исполь- зовав ключевое слово protected , вы делаете все последующие члены класса защи- щенными, т.е. недоступными для функций, которые не являются членами класса. ключаться между защищенными и открытыми членами класса можно сколько угодно. Допустим, у нас есть класс student . В приведенном ниже примере представлены все необходимые возможности, которые нужны классу, описывающему студента (за исключением разве что функций (тратить деньги) и (пить пи- во), которые тоже являются свойствами студента): (in t hours , floa t grade) пройденный курс; grade — вернуть текущую среднюю оценку; hours () — вернуть количество пройденных часов. Оставшиеся члены класса можно объявить как защищенные, чтобы дру- гие функции не могли "лезть" во внутренние дела класса class Student { public: // grade — возвращает текущую среднюю оценку float { return gpa; } // hours — возвращает количество прослушанных часов int hours { return } // addCourse — добавляет к записи студента // прослушанный курс hours, grade) //приведенные ниже члены недоступны для внешних функций protected: int прослушанных часов float gpa; //средняя оценка }; Теперь члены semesterHours и gpa доступны только из других членов класса и приведенный ниже пример работать не будет. Student s ; int argc,
172 Часть III. "Классическое" программирование //повысим свой рейтинг (но не слишком сильно, //иначе никто не поверит) s.gpa = 3.5; //вызовет ошибку при компиляции float gpa = //эта открытая функция // считывает значение переменной, но вы не можете // непосредственно изменить ее значение извне return 0; } При попытке этой программы изменить значение на этапе компиляции будет выдано сообщение об ошибке. Считается признаком хорошего тона не полагаться на значение защиты по умолчанию, а определить в самом начале объявления класса ключевое слово publi c или private . Обычно класс начинают описывать с откры- тых членов, формируя интерфейс класса. Описание защищенных членов класса выполняется позже.
Члены класса могут быть защищены извне и с помощью еще одного клю- чевого слова — private . Кстати, по умолчанию при описании класса его члены считаются описанными именно как private . Разница между pro - tecte d и privat e станет ясной при изучении наследования в главе 21, "Наследование классов".
защищенные члены Теперь, когда вы немного познакомились с защищенными членами, я приведу аргументы, обосновывающие их использование. |
Последнее изменение этой страницы: 2019-04-19; Просмотров: 275; Нарушение авторского права страницы