Информационный сайт

 

Реклама
bulletinsite.net -> Книги на сайте -> Программисту -> Мизрохи С.В. -> "Turbo Pascal и объектно-ориентированное программирование" -> 55

Turbo Pascal и объектно-ориентированное программирование - Мизрохи С.В.

Мизрохи С.В. Turbo Pascal и объектно-ориентированное программирование — М.: Финансы и статистика , 1992. — 192 c.
ISBN 5-279-00903-2
Скачать (прямая ссылка): efektispolzc2000.djvu
Предыдущая << 1 .. 49 50 51 52 53 54 < 55 > 56 57 58 59 60 61 .. 105 >> Следующая

Смысл определения закрытых или защищенных членов класса заключается в ограничении доступа, не так ли? Бедные компиляторы С++ трудятся в ноте лица, чтобы ваши ограничения нельзя было обойти. Поэтому нет смысла писать функции, дающие случайным пользователям свободный доступ к членам с ограниченным доступом. Если вы считаете, что в этом есть смысл, пожалуйста, перечитайте данный абзац снова и снова, пока не придете к выводу, что ваше мнение неверно.
Вышеуказанное правило легко нарушить. Вот пример:
class Address {...}; Il Чье-либо место жительства, class Person { public:
AddressSc personAddress () { return address; }
private:
Address address;
};
Функция-член personAddress возвращает пользователю объект класса Address, содержащийся в объекте Person, но, возможно из соображений эффективности, результат возвращается по ссылке, а не по значению (см. правило 22). К сожалению, наличие этой функции-члена делает бессмысленным определение Person: : address как закрытого члена класса:
Person scott (...); Il Для простоты аргументы опущены.
AddressSc addr = // Предполагаем, что addr - глобально,
scott.personAddress();
Теперь глобальный объект addr - это другой идентификатор для доступа к scott .address, который может быть при желании использован для чтения и записи. С практической точки зрения scott. address уже не является закрытым членом. Теперь он - открытый член класса, и причина этого превращения -функция-член personAddress. Конечно, в уровне доступа private нет ничего особенного. Если бы Address был защищенным членом, к нему следовало бы применять ту же самую логику.
Ссылки - не единственный повод для беспокойства. В равной степени опасения вызывают и указатели. Рассмотрим тот же пример, только на сей раз с использованием указателя:
Правило ЗО
125
private:
Address address;
};
Address *addrPtr = scott .personAddress () ; Il Ta же проблема, что и выше.
При использовании указателей необходимо обращать внимание не только на члены классов, но и на функции-члены. Дело в том, что вы можете вернуть указатель и на функцию-член:
class Person; Il Предварительное объявление.
// PPMF указатель на функцию-член класса Person, typedef void (Person::*PPMF)(); class Person { public:
static PPMF verificationFunction() { return ScPerson: : verify Address; }
private:
Address address; void verifуAddress ();
};
Если вы до сих пор не сталкивались с указателями на функции-члены, то объявление Person: : verif icationFunction может показаться устрашающим. Не стоит пугаться. Все, что там написано, - это:
? verif icationFunction - функция-член, не требующая аргументов;
? возвращаемое значение - указатель на функцию-член класса Person;
? функция, на которую указывает указатель (то есть значение, возвращаемое verif icationFunction), не требует параметров и ничего не возвращает, то есть void.
Что же касается слова static, оно означает то же, что и всегда при объявлении членов классов: для всего класса существует только одна копия члена, и к ней можно получить доступ, не используя объекта. О подробностях справьтесь в своем учебнике по С++. (Если ваш учебник по С++ не содержит информации о статических членах класса, разорвите его и сдайте в макулатуру, а затем одолжите или купите лучший.)
В данном примере verifyAddress - закрытая функция. Об этой детали реализации класса должны быть «осведомлены» только члены класса и, конечно друзья. Однако открытая функция-член verif icationFunction возвращает указатель на verifyAddress, поэтому пользователи могут сделать что-нибудь вроде:
PPMF pmf = scott.verificationFunction();
(scott.*pmf)(); // То же самое, что и вызов scott.verifyAddress.
Здесь pmf становится синонимом Person: :verifyAddress с той лишь существенной разницей, что нет никаких ограничений на его использование.
ЕЕНЯНШНМИ* Классы и функции: реализация
Иногда из соображений производительности бывает чрезвычайно важно написать функцию-член, возвращающую ссылку или указатель на член класса с более ограниченным доступом. В то же время жертвовать ограничениями доступа, даваемыми private и protected, не всегда желательно. В этих случаях вы практически стопроцентно можете достигнуть обеих целей, возвращая указатель или ссылку на константный объект const. Подробнее см. правило 21.
Правило 31. Никогда не возвращайте ссылку на локальный объект или разыменованный указатель, инициализированный внутри функции посредством new
Название правила может показаться чересчур многословным, но на самом деле это не так. Оно просто продиктовано соображениями здравого смысла. В самом деле. Честное слово. Поверьте мне.
Сначала рассмотрим возвращение ссылки на локальный объект. Проблема здесь в следующем: локальность объектов означает именно то, что они локальны. Иначе говоря, они создаются при их определении и разрушаются при выходе из области видимости. Их область видимости - тело той функции, в которой они определены. Когда вы возвращаетесь из функции, вы выходите из их области видимости. В результате, если возвращается ссылка на локальный объект, он удаляется прежде, чем пользователь функции успевает с ним что-либо сделать.
Предыдущая << 1 .. 49 50 51 52 53 54 < 55 > 56 57 58 59 60 61 .. 105 >> Следующая
Реклама
Авторские права © 2009 AdsNet. Все права защищены.
Rambler's Top100