учебники, программирование, основы, введение в,

 

C++: методы-члены класса, дружественные классы и члены класса

Методы-члены класса
В терминологии объектно-ориентированного программирования функции также называются методами или методами - членами класса, для того чтобы подчеркнуть, что конкретная функция является членом некоторого класса.
По стандарту ANSI C, используемому компилятором Visual C++, любая используемая в модуле компиляции функция должна иметь прототип, включающий в себя тип функции, имя функции и список параметров с их типами. Прототип - это некоторое предварительное описание функции, заканчивающееся символом ;.
Прототип функции должен быть вставлен во все модули компиляции, использующие функцию. Для небольших программ прототип функции обычно записывается в модуль компиляции. Для программ, создаваемых средствами Visual C++, и программ, состоящих из нескольких модулей, прототип функции указывается в заголовочном файле. Объявление функции должно однозначно соответствовать ее прототипу и может находиться в любом модуле компиляции (для которого доступен прототип функции).
Прототип метода, являющегося членом некоторого класса, записывается в заголовочном файле, содержащем объявление класса в теле этого класса.
Метод - член класса может иметь следующие модификаторы доступа:

  • public - общедоступный метод;
  • protected - метод, доступный только для членов и объектов данного класса и наследуемых классов (наследуемых с модификаторами доступа public или protected);
  • private - защищенный метод, доступный только внутри класса.

Прототип метода может иметь следующее формальное описание:
модификатор_доступа тип_метода имя_метода
(список_параметров);
Объявление метода может иметь следующее формальное описание:
модификатор_доступа тип_метода имя_метода
(список_параметров)
{ тело_метода }
Тип метода является типом возвращаемого методом значения и может быть любым допустимым базовым или производным типом, включая и тип указателя.
Указатели типа void могут использоваться для объявления параметров метода в том случае, если тип этих параметров на момент компиляции неизвестен.
Например:
void Fx(void *pV); //Прототип метода
...
piVar=new int;
pfVar=new float;
Fx(piVar);        // Вызов метода для
// параметра типа int
Fx(pfVar);        // Вызов метода для
// параметра типа float
...
// Реализация метода
void Fx(void *pV) {*pV=12345;}
Метод, возвращающий указатель, записывается следующим образом:
тип *имя_метода(список_параметров).
Список формальных параметров - это значения, передаваемые в функцию. Каждый элемент этого списка может иметь любой допустимый тип.
Язык C++ допускает передачу параметров по значению и по ссылке или указателю. Параметры, передаваемые по значению, при выполнении программы заносятся в стек, и для больших размеров структур или массивов может возникнуть ситуация переполнения стека. Параметры, передаваемые как ссылки или указатели, не копируются в стек.
Изменение значений самих параметров происходит только для параметров, переданных по ссылке или указателю. При передаче параметра по значению метод изменяет не сам параметр, а его копию.
Список параметров может включать параметры, имеющие значения по умолчанию. Такие параметры указываются в конце списка параметров. Значение по умолчанию будет использовано только в том случае, если число переданных параметров меньше числа указанных формальных параметров в описании метода.
Язык C++ разрешает рекурсивный вызов методов.
В методах класса можно использовать ключевое слово this, являющееся указателем на объект данного класса. Это ключевое слово нельзя использовать вне метода члена класса.
Создание метода-члена класса
Для того чтобы в среде Visual Studio .NET добавить в класс новый метод - член класса, следует в окне просмотра классов Class View выделить секцию с именем класса и выполнить команду контекстного меню Add|Add Function, а затем в диалоге - мастере построения метода ввести имя метода, его тип, а также определить список параметров.
При добавлении метода - члена класса в файл реализации класса автоматически добавляется код реализации нового метода, а в заголовочный файл - объявление этого метода.

http://localhost:3232/img/empty.gifМетоды с переменным числом параметров

Метод может иметь переменное число параметров: это указывается в конце списка параметров символом многоточия ... . Методы с переменным числом параметров должны иметь как минимум один описанный формальный параметр.
Для применения переменного числа параметров можно использовать:

  • макрос va_start(указатель_списка_параметров,последний_параметр) - при инициализации указателя и установке его на начало переменного списка параметров;
  • макрос va_arg(указатель_списка_параметров,i) - при выборе параметра и продвижении указателя в соответствии с его типом на следующий параметр;
  • макрос va_end((указатель_списка_параметров) - при установке указателя на список параметров, равный null, после извлечения значений всех параметров;
  • тип va_list - для создания указателя на список параметров.

Например:
#include <stdio.h>  
// Библиотека, содержащая тип va_list
#include <varargs.h>
#include <iostream>
int Fx ( int i1, ... );
// Прототип Функции с переменным
// числом параметров
void main( void )
{   // Вызов функции Fx с различным
// числом параметров
std::cout<< Fx ( 100, 200) );
std::cout<< Fx ( 5 ) );
std::cout<< Fx ( -1,-3,45 ) );
}
int Fx ( int i1, ... ) 
// Реализация функции с переменным
// числом параметров
{  int sumx,i;
sumx = 0, i = i1; 
va_list list1;       
// Список параметров
va_start(list1, i1 );
// Инициализация списка параметров
while( i != -1 )   {
sumx += i;
i = va_arg(list1, int);
//Извлечение следующего параметра
}
va_end(list1);     
return( sumx );
}

Указатели на методы-члены класса и на функции
Указатели на методы и на функции могут быть использованы для передачи метода в качестве параметра другому методу.
Объявление указателя на метод может иметь следующее формальное описание:
тип_метода (имя_класса::*имя_метода_указателя)
(список параметров);
тип_функции (*имя_ функции_указателя)
(список параметров);
Инициализация указателя может иметь следующее формальное описание:
тип_метода имя_класса::*имя_метода_указателя
(список параметров)=
&имя_класса::имя_любого_метода;
тип_функции (*имя_ функции_указателя)
(список параметров)= &имя_функции;
Вызов метода, объявленного как указатель на метод, может быть выполнен следующим образом:
(имя_объекта->*имя_ метода_указателя)
(список параметров);
(*имя_ функции_указателя)(список параметров);
Для функций, но не для методов - членов класса, разрешена другая форма вызова метода:
имя_ функции_указателя(список параметров);
(имя_ функции_указателя)(список параметров);
Объявление функции, имеющей в качестве параметра указатель на метод, может иметь следующее формальное описание:
тип_метода имя_метода (тип_метода_указателя
(*имя_метода_указателя)
(список параметров));
Вызов метода, использующего в качестве параметра указатель на метод, может иметь следующее формальное описание:
имя_метода(имя_объекта->*имя_метода_указателя);
имя_функции(имя_функции_указателя);
Разрешается создавать массив указателей на функции.
При использовании указателей на функцию можно не употреблять операцию разыменования или операцию получения адреса.
Например:
class a1
{
public:
a1(void);
~a1(void);
int Fx1(int i1);
int Fx2(int i2);
};
a1::a1(void){}
a1::~a1(void){}
int a1::Fx1(int i1){    return 1;}
int a1::Fx2(int i2){    return 2;}

int (*Fy_pointer)(); 
// Объявление указателя на функцию
int Fy ();
int _main(int argc, char* argv[])

a1* a1Object = new a1();
int (a1::*Fx_pointer)(int)=&a1::Fx2; 
// Объявление и инициализация указателя
// на метод - член класса
int i;
i=(a1Object->*Fx_pointer)(1); 
// Вызов по указателю на метод
std::cout<<i;
int (*Fy_pointer)()=&Fy;         
// Объявление и инициализация указателя
// на функцию
std::cout<<(Fy_pointer)();  
std::cout<<(*Fy_pointer)(); 
// Вызов по указателю на
// функцию (две формы)
return 0;
}
int Fy ()  {return 5;}
Встроенные функции
Встроенные функции указываются оператором inline. Применение встроенных функций может несколько сократить время выполнения программы, так как компилятор встраивает код такой функции в том месте программы, где указан ее вызов.
Например:
inline void Fx(void) {
std::cout<<"Функция Fx"<<std::endl;}
...
Fx(void);
// Этот код  будет заменен компилятором
// на код встроенной функции
Перегрузка функций и методов
Язык C++ позволяет выполнять перегрузку функций и методов - членов класса, то есть вызывать функцию (метод) с тем же именем, но с различными типами фактических параметров. Для создания перегружаемой функции следует указать отдельный прототип и сделать отдельное объявление для каждого списка параметров. Если функции различаются только типом и имеют совпадающие списки параметров, то для таких функций перегрузка не допускается.
Для определения вызываемой перегружаемой функции учитываются только списки параметров, а тип возвращаемого значения не учитывается. При этом для соответствия списка параметров вызываемой функции может применяться преобразование типов и соответствие по многоточию (соответствие по многоточию?) для функций с переменным числом параметров.

http://localhost:3232/img/empty.gifДружественные члены класса

Дружественные члены класса (методы) позволяют получить доступ к защищенным модификатором private членам класса из методов других классов. Методы и классы, объявляемые дружественными, иногда также называются друзьями класса.
Если метод класса A внутри тела класса B объявляется с модификатором friend, что указывает на то, что он является другом класса, то из него разрешен доступ ко всем членам класса B.
Например:
class A { public: int Fx();}
class B { public: friend int A::Fx();
private:
}
Дружественные классы
Объявление дружественного класса позволяет всем его методам получить доступ ко всем переменным и методам другого класса.
Например:
class A {public: int Fx();}
class B {public:
friend class A;
private:
}
Дружественный класс или член класса будет доступен только в том случае, если он был объявлен в области видимости самого класса или ранее во внешней области видимости, внутри которой располагается область видимости, содержащая объявление класса с объявлениями друзей класса.
Например:
class A {public:
// Класс расположен во внешней
// области видимости
int Fx1();
}
namespace classB {
class B {public:
friend class A;
friend class C;
private:
}
class C { public:
// Класс расположен в том же
// пространстве имен
int Fx2(); 
}
}
Дружественные классы не наследуются, и их дружественность не является транзитивной.
Например:
class A {int Fx();}
class B {friend class A;}
class C {friend class B;}
// Класс А не является
// дружественным классу C
class D : public B {} 
// Класс А не является
// дружественным классу D
http://localhost:3232/img/empty.gif

 
На главную | Содержание | < Назад....Вперёд >
С вопросами и предложениями можно обращаться по nicivas@bk.ru. 2013 г.Яндекс.Метрика