- •1)Классы, объявление классов, спецификаторы доступа.
- •2)Классы, поля классов, инкапсуляция.
- •3)Методы и их реализация на примере класса «Комплексное число».
- •4)Создание объектов. Объекты и методы.
- •5)Конструкторы, виды конструкторов.
- •6) Конструктор по умолчанию, конструктор с параметрами.
- •7)Конструктор преобразования, конструктор копии.
- •8) Деструкторы
- •9)Перегрузка операций.
- •10) Стековые и динамические объекты, указатели и ссылки, достоинства и недостатки стековых объектов.
- •Размещение в стеке
- •Динамическое размещение
- •Указатели и ссылки
- •Недостатки стековых объектов
- •Достоинства стековых объектов
- •11) Указатели, арифметика указателей.
- •12)Указатель на константу, константный указатель, константный указатель на константу, константные аргументы функций, константные функции классов.
- •Константные переменные
- •Константы в перечислениях
- •Указатель на константу
- •Константный указатель
- •Константный указатель на константу
- •Константные аргументы функций
- •Неконстантные аргументы функций
- •Константные функции классов
- •13)Механизмы передачи параметров в функции, аргументы по умолчанию, указатель на функцию.
- •14)Дружественные функции (методы).
- •15)Статические поля и методы.
- •16) Инкапсуляция, ее реализация через понятие class.
13)Механизмы передачи параметров в функции, аргументы по умолчанию, указатель на функцию.
Механизм параметров является основным способом обмена информацией между
вызываемой и вызывающей функциями. Параметры, перечисленные в заголовке
описания функции, называются формальными параметрами, или просто параметрами,
а записанные в операторе вызова функции — фактическими параметрами,
или аргументами.
При вызове функции в первую очередь вычисляются выражения, стоящие на
месте аргументов; затем в стеке выделяется память под формальные параметры
функции в соответствии с их типом, и каждому из них присваивается значение
соответствующего аргумента. При этом проверяется соответствие типов и при
необходимости выполняются их преобразования. При несоответствии типов выдается
диагностическое сообщение.
Существует два способа передачи параметров в функцию: по значению и по адресу.
При передаче по значению в стек заносятся копии значений аргументов, и операторы
функции работают с этими копиями. Доступа к исходным значениям параметров
у функции нет, а, следовательно, нет и возможности их изменить.
При передаче по адресу в стек заносятся копии адресов аргументов, а функция
осуществляет доступ к ячейкам памяти по этим адресам и может изменить исходные
значения аргументов:
#1nclude <iostream.h>
void f (int I, int* j . int& k);
int main(){
int i = 1, j = 2, к = 3;
cout « I << “ “<< j <<” “ << k << “\n";
f(I, &j,k);
cout « I << “ “<< j <<” “ << k;
return 0
}
void f (int I, int* j . int& k){
i++; (*j)++; k++;
}
Результат работы программы:
I j k
1 2 3
13 4
Первый параметр (i) передается по значению. Его изменение в функции не
влияет на исходное значение. Второй параметр (j) передается по адресу с помощью
указателя, при этом для передачи в функцию адреса фактического параметра
используется операция взятия адреса, а для получения его значения в
функции требуется операция разыменования. Третий параметр (к) передается по
адресу с помощью ссылки.
При передаче по ссылке в функцию передается адрес указанного при вызове параметра,
а внутри функции все обращения к параметру неявно разыменовываются.
Поэтому использование ссылок вместо указателей улучшает читаемость программы,
избавляя от необходимости применять операции получения адреса и
разыменования. Использование ссылок вместо передачи по значению более эффективно,
поскольку не требует копирования параметров, что имеет значение
при передаче структур данных большого объема.
Если требуется запретить изменение параметра внутри функции, используется
модификатор const:
int f(const char*);
char* t(char* a. const int* b);
Рекомендуется указывать const перед всеми параметрами, изменение которых в функции
не предусмотрено. Это облегчает отладку больших программ, так как по заголовку функции
можно сделать вывод о том, какие величины в ней изменяются, а какие нет. Кроме
того, на место параметра типа const& может передаваться константа, а для переменной при
необходимости выполняются преобразования типа.
Таким образом, исходные данные, которые не должны изменяться в функции,
предпочтительнее передавать ей с помощью константных ссылок.
По умолчанию параметры любого типа, кроме массива и функции (например, вещественного,
структурного, перечисление, объединение, указатель), передаются
в функцию по значению. При использовании в качестве параметра массива в функцию передается указатель
на его первый элемент, иными словами, массив всегда передается по адресу.
Параметры со значениями по умолчанию
Чтобы упростить вызов функции, в ее заголовке можно указать значения параметров
по умолчанию. Эти параметры должны быть последними в списке и могут
опускаться при вызове функции. Если при вызове параметр опущен, должны
быть опущены и все параметры, стоящие за ним. В качестве значений параметров
по умолчанию могут использоваться константы, глобальные переменные и выражения:
Int fdnt а. Int b = 0):
void fldnt. Int = 100. char* = 0); /* обратите внимание на пробел между * и
= (без него получилась бы операция сложного присваивания *=) */
void errdnt errValue = errno); // errno - глобальная переменная
fdOO); f(a. 1): // варианты вызова функции f
fl(a): fl(a. 10); fl(a. 10. "Vasia"): // варианты вызова функции fl
fl(a,."Vasia") // неверно!
Функцию можно вызвать через указатель на нее. Для этого объявляется указатель
соответствующего типа и ему с помощью операции взятия адреса присваивается
адрес функции;
void f ( i n t а ) { / * . . . * / } // определение функции
void (*pf)(int); // указатель на функцию
….
pf = &f; // указателю присваивается адрес функции
/ / (можно написать pf = f ;)
pf(10); // функция f вызывается через указатель pf
// (можно написать (*pf)(10) )
Для того чтобы сделать программу легко читаемой, при описании указателей на
функции используют переименование типов (typedef). Можно объявлять массивы
указателей на функции (это может быть полезно, например, при реализации
меню);
// Описание типа PF как указателя
// на функцию с одним параметром типа int;
typedef void (*PF)(int);
// Описание и инициализация массива указателей:
PF menu[] = {&new. &open. &save};
menu[l](10); // Вызов функции open
Здесь new, open и save — имена функций, которые должны быть объявлены ранее.
Указатели на функции передаются в подпрограмму таким же образом, как и параметры
других типов:
#include <1ostream.h>
typedef void (*PF)(int);
void fKPF pf){ // функция f l получает в качестве параметра указатель типа PF
pf(5); // вызов функции, переданной через указатель
}
void fdnt 1 ){cout « 1 :}
Int ma1n(){
f l ( f ) ;
return 0:
}
Тип указателя и тип функции, которая вызывается посредством этого указателя,
должны совпадать в точности.
