Освой самостоятельно С++ за 21 день.
Шрифт:
Массивы указателей на функции
Аналогично объявлению массива указателей целых чисел можно объявить массив указателей на функции с определенной сигнатурой, возвращающих значения определенного типа. Листинг 14.7 является еще одним вариантом программы из листинга 14.5, в которой все указатели на функции собраны в массив.
Листинг 14.7. Использование массива указателей на функции
1: // Листинг 14.7.
2:
3: #include <iostream.h>
4:
5: void Square (int&,int&);
6: void Cube (int&, int&);
7: void Swap (int&, int &);
8: void GetVals(int&, int&);
9: void PrintVals(int, int);
10:
11: int main
12: {
13: int valOne=1, valTwo=2;
14: int choice, i;
15: const MaxArray = 5;
16: void (*pFuncArray[MaxArray])(int&, int&);
17:
18: for (i=0;i<MaxArray;i++)
19: {
20: cout << "(1)Change Values (2)Square (3)Cube (4)Swap: ";
21: cin >> choice;
22: switch (choice)
23: {
24: case 1:pFuncArray[i] = GetVals; break;
25: case 2:pFuncArray[i] = Square; break;
26: case 3:pFuncArray[i] = Cube; break;
27: case 4:pFuncArray[i] = Swap; break;
28: default:pFuncArray[i] = 0;
29: }
30: }
31:
32: for (i=0;i<MaxArray; i++)
33: {
34: if ( pFuncArray[i] == 0 )
35: continue;
36: pFuncArray[i](valOne,valTwo);
37: PrintVals(valOne,valTwo);
38: }
39: return 0;
40: }
41:
42: void PrintVals(int x, int у)
43: {
44: cout << "x: " << x << " у: " << у << endl;
45: }
46:
47: void Square (int & rX, int & rY)
48: {
49: rX *= rX;
50: rY *= rY;
51: }
52:
53: void Cube (int & rX, int & rY)
54: {
55: int tmp;
56:
57: tmp = rX;
58: rX *= rX;
59: rX = rX * tmp;
60:
61: tmp = rY;
62: rY *= rY;
63: rY = rY * tmp;
64: }
65:
66: void Swap(int & rX, int & rY)
67: {
68: int temp;
69: temp = rX;
70: rX = rY;
71: rY = temp;
72: }
73:
74: void GetVals (int & rValOne, int & rValTwo)
75: {
76: cout << "New value for ValOne: ";
77: cin >> rValOne;
78: cout << "New value for ValTwo: ";
79: cin >> rValTwo;
80: }
Результат:
(1)Change Values (2)Square (3)Cube (4)Swap: 1
(1)Change Values (2)Square (3)Cube (4)Swap: 2
(1)Change Values (2)Square (3)Cube (4)Swap: 3
(1)Change Values (2)Square (3)Cube (4)Swap: 4
(1)Change Values (2)Square (3)Cube (4)Swap: 2
New Value for ValOne: 2
New Value for ValTwo: 3
x: 2 y: 3
x: 4 y: 9
x: 64 y: 729
x: 729 y: 64
x: 531441 y:4096
Анализ: Как и в предыдущем листинге, для экономии места не были показаны выполнения объявленных функций, поскольку сами функции остались теми же, что и в листинге 14.5. В строке 16 объявляется массив pFuncArray, содержащий пять указателей на функции, которые возвращают void и принимают две ссылки на значения типа int.
В строках 18-30 пользователю предлагается установить последовательность вызова функций. Каждый член массива связывается с соответствующей функцией. Последовательный вызов функции осуществляется в строках 32-38, причем после каждого вызова на экран сразу выводится результат.
Передача указателей на функции в другие функции
Указатели на функции (или массивы указателей) могут передаваться в другие функции для вызова в них с помощью указателя нужной функции.
Листинг 14.5 можно усовершенствовать, передав указатель на выбранную функцию другой функции (кроме main), которая выведет исходные значения на печать, вызовет функцию и вновь напечатает измененные значения. Именно такой подход применен в листинге 14.8.
Листинг 14.8. Передана указателя на функцию другой функции
1: // Листинг 14.8. Передача указателя на функцию другой функции
2:
3: #include <iostream.h>
4:
5: void Square (int&,int&);
6: void Cube (int&, int&);
7: void Swap (int&, int &);
8: void GetVals(int&, int&);
9: void PrintVals(void (*)(int&, int&),int&, int&);
10:
11: int main
12: {
13: int val0ne=1, valTwo=2;
14: int choice;
15: bool fQuit = false;
16:
17: void (*pFunc)(int&, int&);
18:
19: while (fQuit == false)
20: {
21: cout << "(0)Quit (1)Change Values (2)Square (3)Cube (4)Swap: ";