Функции-члены класса
Концепция structрасширена в С ++ так, что функции могут быть членами структур. Объявление функции включается в объявление структуры и эта функция вызывается с использованием методов доступа, которые определены для членов структуры. Давайте перепишем наш примерch_stackи объявим как функции-члены различные функции, связанные с
ch_stack.
struct ch_stack {
// представление данных
inttop;
enum {max_len = 100, EMPTY = -1, FULL = max_len -1};
char s [max_len];
//операции, представленные как функции-члены
void reset ( ) {top = EMPTY; }
void push (char c) {top ++; s [top] = c;}
char pop ( ) {return s [top--];}
char top_of ( ) {return s [top]; }
bool empty ( ) {return (top = = EMPTY) ;}
bool full ( ) {return (top = = FULL) ;}
};
Функции-члены (memberfunction) записаны подобно обычным функциям. Единственное отличие состоит в том, что они могут использовать имена членов класса « как есть ». Так, функции-членыch_stackиспользуют переменныеtopиsбез явного указания имени структуры. При вызове функций-членов применительно к конкретному объекту типаch_stackони действуют на указанные члены данных именно этого объекта.
Следующий пример иллюстрирует изложенные идеи. Пусть описаны две переменных типа ch_stack:
ch_stack data, operands;
тогда
data. reset ( ) ;
operands. reset ( ) ;
вызывают функцию-член reset, которая устанавливаетdata.topиoperands.topв значениеEMPTY. Если объявлен указатель на
ch_stack
ch_stack* ptr_operands = &operands;
то
ptr_operands -> push (‘A’);
вызывает функцию член push, которая приводит к приращениюoperands.topи устанавливаетoperands.s[top] в ‘A’.
Функции-члены, которые определены внутри struct, являются неявно встраиваемыми. Как правило, только короткие, интенсивно используемые функции-члены должны определяться внутриstruct, как в только что приведенном примере. Чтобы определить функцию-член внеstruct, используется оператор разрешения области видимости (scope resolution) . Перепишем наш пример, используя оператор разрешения области видимости. В этом случае функция уже не будет неявно встраиваемой.
struct ch_stack {
// предоставление данных
inttop;
enum {max_len = 100, EMPTY = -1, FULL = max_len -1};
char s [max_len];
// операции, представленные как функции-члены
voidreset( ) {top=EMPTY; } //неявно встроенная функция
void push (char c) ; //прототип функции
…..
};
voidch_stack: :push(charc)//определение невстроенной функции
{
top ++;
s [top] = c;
}
Оператор разрешения области видимости позволяет функциям-членам из разных типов structиметь одинаковые имена. То, какая именно функция-член вызывается, зависит от типа объекта, на который она направлена. Функции-члены внутри одной структуры могут быть перегружены.
struct ch_stack {
…..
char pop (int n); // в пределах ch_stack
…..
};
char ch_stack : : pop (int n)
{
while (n-- > 1)
top--;
return s [top--]
}
Что конкретно будет вызвано, зависит от текущих аргументов функции pop:
data.pop( ); // вызывает стандартный рор
data.pop(5); // вызывает многократный рор
Объявление
ch_stack s, t, u;
создает три отдельных объекта ch_stackразмером в
sizeof(ch_stack) байт. Каждая из этих переменных имеет свои собственные члены данных:
int top;
char s [max_len];
Функция-член по определению является частью типа. Не существует отдельной функции-члена для каждой из этих трех переменных ch_stack..
Спецификация inlineможет использоваться явно с функциями-членами, определенными в пределах области видимости файла.
struct ch_stack {
…..
void reset ( )
void push (char c) ;
…..
};
inline void ch_stack : : reset ( )
{
top = EMPTY;
}
inline void ch_stack : : push (char c)
{
s [++ top] = c;
}
Объединение операций с данными подчеркивает их «объективность».