Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Срауструп CPP.doc
Скачиваний:
6
Добавлен:
05.11.2018
Размер:
4.95 Mб
Скачать

1.5.4 Инкапсуляция

Пусть члену класса (неважно функции-члену или члену, представляющему

данные) требуется защита от "несанкционированного доступа". Как разумно

ограничить множество функций, которым такой член будет доступен? Очевидный

ответ для языков, поддерживающих объектно-ориентированное

программирование, таков: доступ имеют все операции, которые определены для

этого объекта, иными словами, все функции-члены. Например:

class window

{

// ...

protected:

Rectangle inside;

// ...

};

class dumb_terminal : public window

{

// ...

public:

void prompt ();

// ...

};

Здесь в базовом классе window член inside типа Rectangle описывается

как защищенный (protected), но функции-члены производных классов,

например, dumb_terminal::prompt(), могут обратиться к нему и выяснить, с

какого вида окном они работают. Для всех других функций член

window::inside недоступен.

В таком подходе сочетается высокая степень защищенности

(действительно, вряд ли вы "случайно" определите производный класс) с

гибкостью, необходимой для программ, которые создают классы и используют

их иерархию (действительно, "для себя" всегда можно в производных классах

предусмотреть доступ к защищенным членам).

Неочевидное следствие из этого: нельзя составить полный и

окончательный список всех функций, которым будет доступен защищенный член,

поскольку всегда можно добавить еще одну, определив ее как функцию-член в

новом производном классе. Для метода абстракции данных такой подход часто

бывает мало приемлемым. Если язык ориентируется на метод абстракции

данных, то очевидное для него решение - это требование указывать в

описании класса список всех функций, которым нужен доступ к члену. В С++

для этой цели используется описание частных (private) членов. Оно

использовалось и в приводившихся описаниях классов complex и shape.

Важность инкапсуляции, т.е. заключения членов в защитную оболочку,

резко возрастает с ростом размеров программы и увеличивающимся разбросом

областей приложения. В $$6.6 более подробно обсуждаются возможности языка

по инкапсуляции.

1.6 Пределы совершенства

Язык С++ проектировался как "лучший С", поддерживающий абстракцию

данных и объектно-ориентированное программирование. При этом он должен

быть пригодным для большинства основных задач системного программирования.

Основная трудность для языка, который создавался в расчете на методы

упрятывания данных, абстракции данных и объектно-ориентированного

программирования, в том, что для того, чтобы быть языком общего

назначения, он должен:

- идти на традиционных машинах;

- сосуществовать с традиционными операционными системами и языками;

- соперничать с традиционными языками программирования в эффективности

выполнения программы;

- быть пригодным во всех основных областях приложения.

Это значит, что должны быть возможности для эффективных числовых

операций (арифметика с плавающей точкой без особых накладных расходов,

иначе пользователь предпочтет Фортран) и средства такого доступа к памяти,

который позволит писать на этом языке драйверы устройств. Кроме того, надо

уметь писать вызовы функций в достаточно непривычной записи, принятой для

обращений в традиционных операционных системах. Наконец, должна быть

возможность из языка, поддерживающего объектно-ориентированное

программирование, вызывать функции, написанные на других языках, а из

других языков вызывать функцию на этом языке, поддерживающем

объектно-ориентированное программирование.

Далее, нельзя рассчитывать на широкое использование искомого языка

программирования как языка общего назначения, если реализация его целиком

полагается на возможности, которые отсутствуют в машинах с традиционной

архитектурой.

Если не вводить в язык возможности низкого уровня, то придется для

основных задач большинства областей приложения использовать некоторые

языки низкого уровня, например С или ассемблер. Но С++ проектировался с

расчетом, что в нем можно сделать все, что допустимо на С, причем без

увеличения времени выполнения. Вообще, С++ проектировался, исходя из

принципа, что не должно возникать никаких дополнительных затрат времени и

памяти, если только этого явно не пожелает сам программист.

Язык проектировался в расчете на современные методы трансляции,

которые обеспечивают проверку согласованности программы, ее эффективность

и компактность представления. Основным средством борьбы со сложностью

программ видится, прежде всего, строгий контроль типов и инкапсуляция.

Особенно это касается больших программ, создаваемых многими людьми.

Пользователь может не являться одним из создателей таких программ, и может

вообще не быть программистом. Поскольку никакую настоящую программу

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

программистами, последнее замечание можно отнести практически ко всем

программам.

С++ проектировался для поддержки того принципа, что всякая программа

есть модель некоторых существующих в реальности понятий, а класс является

конкретным представлением понятия, взятого из области приложения ($$12.2).

Поэтому классы пронизывают всю программу на С++, и налагаются жесткие

требования на гибкость понятия класса, компактность объектов класса и

эффективность их использования. Если работать с классами будет неудобно

или слишком накладно, то они просто не будут использоваться, и программы

выродятся в программы на "лучшем С". Значит пользователь не сумеет

насладиться теми возможностями, ради которых, собственно, и создавался

язык.