C++: методы-члены класса, дружественные классы и члены класса
Методы с переменным числом параметров
Метод может иметь переменное число параметров: это указывается в конце списка параметров символом многоточия ... . Методы с переменным числом параметров должны иметь как минимум один описанный формальный параметр.
Для применения переменного числа параметров можно использовать:
- макрос 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++ позволяет выполнять перегрузку функций и методов - членов класса, то есть вызывать функцию (метод) с тем же именем, но с различными типами фактических параметров. Для создания перегружаемой функции следует указать отдельный прототип и сделать отдельное объявление для каждого списка параметров. Если функции различаются только типом и имеют совпадающие списки параметров, то для таких функций перегрузка не допускается.
Для определения вызываемой перегружаемой функции учитываются только списки параметров, а тип возвращаемого значения не учитывается. При этом для соответствия списка параметров вызываемой функции может применяться преобразование типов и соответствие по многоточию (соответствие по многоточию?) для функций с переменным числом параметров.