►Ограничивайте видимость...332

Ограничение видимости внутреннего содержимого класса для внешнего мира — один из краеугольных камней объектно-ориентированного программирования. Класс сам отвечает за своё содержимое, а приложение лишь использует класс для решения поставленных задач.

В частности, ограниченная видимость означает, что данные-члены не должны быть доступны извне класса, т.е. они должны быть защищёнными или закрытыми. Кроме того, должны быть защищены функции-члены, о которых внешние приложения не должны знать.

Открытые функции-члены должны как можно меньше доверять внешнему коду — любой аргумент, переданный открытой функции-члену, должен рассматриваться как потенциальный источник ошибки, пока не будет достоверно доказано обратное. Функция, приведённая ниже, представляет собой мину, которая только и ждёт своего часа.

_________________

332 стр. Часть 6. Великолепная десятка

    class Array

    {

    public :

        Array( int s )

        {

            size = 0 ;

            pData = new int[ s ] ;

            if ( pData )

            {

                size = s ;

            }

        }

        ~Array( )

        {

            delete pData ;

            size = 0 ;

            pData = 0 ;

        }

        /* Вернуть или установить данные в массиве */

        int data( int index )

        {

            return pData[ index ] ;

        }

        int data ( int index , int newValue )

        {

            int oldValue = pData[ index ] ;

            pData[ index ] = newValue ;

            return oldValue ;

        }

    protected :

        int size ;

        int *pData ;

    } ;

Функция data( int ) позволяет внешнему приложению читать данные из Array. Эта функция слишком доверчива: она не проверяет, находится ли переменная index в допустимом диапазоне. А что, если она выйдет за предусмотренные границы? Функция data( int , int ) с этой точки зрения ещё хуже, поскольку производит запись в неизвестное место в памяти.

В следующем примере показано, как осуществить такую проверку. Для краткости приведём только пример функции data( int ).

    int data( unsigned int index )

    {

        if ( index >= size )

        {

            throw Exception( "Индекс массива вне "

                            "допустимого диапазона" ) ;

        }

        return pData[ index ] ;

    }

Теперь, если переменная index будет выходить за пределы допустимого диапазона, это будет выявлено на этапе проверки ( беззнаковость переменной index избавляет от необходимости проверки на отрицательность значения индекса ).

_________________

333 стр. Глава 29. Десять способов избежать ошибок