Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Когда использовать встроенные функции-члены



Обратите внимание, что определения функций home(), get(), height() и width() приведены прямо в теле класса. Такие функции называются встроенными. (Мы говорили об этом в разделе 7.6.)

Функции-члены можно объявить в теле класса встроенными и явно, поместив перед типом возвращаемого значения ключевое слово inline:

class Screen {

public:

// использование ключевого слова inline

// для объявления встроенных функций-членов

inline void home() { _cursor = 0; }

inline char get() { return _screen[_cursor]; }

//...

};

Определения home() и get() в приведенных примерах эквивалентны. Поскольку ключевое слово inline избыточно, мы в этой книге не пишем его явно для функций-членов, определенных в теле класса.

Функции-члены, состоящие из двух или более строк, лучше определять вне тела. Для идентификации функции как члена некоторого класса требуется специальный синтаксис объявления: имя функции должно быть квалифицировано именем ее класса. Вот как выглядит определение функции checkRange(), квалифицированное именем Screen:

#include < iostream>

#include " screen.h"

 

// имя функции-члена квалифицировано именем Screen::

bool Screen:: checkRange( int row, int col )

{ // проверить корректность координат

if ( row < 1 || row > _height ||

   col < 1 || col > _width ) {

cerr < < " Screen coordinates ( "

      < < row < < ", " < < col

      < < " ) out of bounds.\n";

return false;

}

return true;

}

Прежде чем определять функцию-член вне тела класса, необходимо объявить ее внутри тела, обеспечив ее видимость. Например, если бы перед определением функции checkRange() не был включен заголовочный файл Screen.h, то компилятор выдал бы сообщение об ошибке. Тело класса определяет полный список его членов. Этот список не может быть расширен после закрытия тела.

Обычно функции-члены, определенные вне тела класса, не делают встроенными. Но объявить такую функцию встроенной можно, если явно добавить слово inline в объявление функции внутри тела класса или в ее определение вне тела, либо сделав то и другое одновременно. В следующем примере move() определена как встроенная функция-член класса Screen:

inline void Screen:: move( int r, int c )

{ // переместить курсор в абсолютную позицию

if ( checkRange( r, c ) ) // позиция на экране задана корректно?

{

int row = (r-1) * _width; // смещение начала строки

_cursor = row + c - 1;

}

}

Функция get(int, int) объявляется встроенной с помощью слова inline:

class Screen {

public:

inline char get( int, int );

// объявления других функций-членов не изменяются

};

Определение функции следует после объявления класса. При этом слово inline можно опустить:

char Screen:: get( int r, int c )

{

move( r, c ); // устанавливаем _cursor

return get(); // вызываем другую функцию-член get()

}

Так как встроенные функции-члены должны быть определены в каждом исходном файле, где они вызываются, то встроенную функцию, не определенную в теле класса, следует поместить в тот же заголовочный файл, в котором определен ее класс. Например, представленные ранее определения move() и get() должны находиться в заголовочном файле Screen.h после определения класса Screen.

Доступ к членам класса

Говорят, что определение функции-члена принадлежит области видимости класса независимо от того, находится ли оно вне или внутри его тела. Отсюда следуют два вывода:

· в определении функции-члена могут быть обращения к любым членам класса, открытым или закрытым, и это не нарушает ограничений доступа;

· когда функция-член обращается к членам класса, операторы доступа “точка” и “стрелка” не необходимы.

Например:

#include < string>

 

void Screen:: copy( const Screen & sobj )

{

// если этот объект и объект sobj - одно и то же,

// копирование излишне

// мы анализируем указатель this (см. раздел 13.4)

if ( this! = & sobj )

{

_height = sobj._height;

_width = sobj._width;

_cursor = 0;

 

// создаем новую строку;

// ее содержимое такое же, как sobj._screen

_screen = sobj._screen;

}

}

Хотя _screen, _height, _width и _cursor являются закрытыми членами класса Screen, функция-член copy() работает с ними напрямую. Если при обращении к члену отсутствует оператор доступа, то считается, что речь идет о члене того класса, для которого функция-член вызвана. Если вызвать copy() следующим образом:

#include " Screen.h"

 

int main()

{

Screen s1;

// Установить s1

 

Screen s2;

s2.copy(s1);

 

//...

}

то параметр sobj внутри определения copy() соотносится с объектом s1 из функции main(). Функция-член copy() вызвана для объекта s2, стоящего перед оператором “точка”. Для такого вызова члены _screen, _height, _width и _cursor, при обращении к которым внутри определения этой функции нет оператора доступа, – это члены объекта s2. В следующем разделе мы рассмотрим доступ к членам класса внутри определения функции-члена более подробно и, в частности, покажем, как для поддержки такого доступа применяется указатель this.


Поделиться:



Последнее изменение этой страницы: 2019-04-09; Просмотров: 277; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.011 с.)
Главная | Случайная страница | Обратная связь