Листинг 14.5. Указатели на функцию



1: // Листинг 14.5. Использование указателей на функции

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: void (* pFunc) (int &, int &);

14: bool fQuit = false;

15:

16: int val0ne=1, valTwo=2;

17: int choice;

18: while (fQuit == false)

19: {

20: cout << "(0)Quit (1)Change Values (2)Square (3)Cube (4)Swap";

21: cin >> choice;

22: switch (choice)

23: {

24: case 1: pFunc = GetVals; break;

25: case 2: pFunc = Square; break;

26: case 3: pFunc = Cube; break;

27: case 4: pFunc = Swap; break;

28: default : fQuit = true; break;

29: }

30:

31: if (fQuit)

32: break;

33:

34: PrintVals(valOne, valTwo);

35: pFunc(valOne, valTwo);

36: PrintVals(valOne, valTwo);

37: }

38: return 0;

39: }

40:

41: void PrintVals(int x, int y)

42: {

43: cout << "x: " << x << " y: " << y << endl;

44: }

45:

46: void Square (int & rX, int & rY)

47: {

48: rX *= rX;

49: rY *= rY;

50: }

51:

52: void Cube (int & rX, int & rY)

53: {

54: int tmp;

55:

56: tmp = rX;

57: rX *= rX;

58: rX = rX * tmp;

59:

60: tmp = rY;

61: rY *= rY;

62: rY = rY * tmp;

63: }

64:

65: void Swap(int & rX, int & rY)

66: {

67: int temp;

68: temp = rX;

69: rX = rY;

70: rY = temp;

71: }

72:

73: void GetVals (int & rValOne, int & rValTwo)

74: {

75: cout << "New value for ValOne: ";

76: cin >> rValOne;

77: cout << "New value for ValTwo: ";

78: cin >> rValTwo;

79: }

 

Результат:

(0)0uit (1)Change Values (2)Square (3)Cube (4)Swap: 1

x: 1 у: 2

New value for ValOne: 2

New value for ValTwo: 3

x: 2 y: 3

(0)Quit (1)Change Values (2)Square (3)Cube (4)Swap: 3

x: 2 y: 3

x: 8 y: 27

(0)Qult (1 )Change Values (2)Square (3)Cube (4)Swap: 2

x: 8 y: 27

x: 64 y: 729

(0)Quit (1)Change Values (2)Square (3)Cube (4)Swap: 4

x: 64 y: 729

x: 729 y: 64

(0)Quit (1)Change Values (2)Square (3)Cube (4)Swap: 0

 

Анализ: В строках 5—8 объявляются четыре функции с одинаковыми типами возврата и сигнатурами. Все эти функции возвращают void и принимают ссылки на значения типа int.

В строке 13 переменная pFunc объявлена как указатель на функцию, принимающую две ссылки на int и возвращающую void. Этот указатель может ссылаться на каждую из упоминавшихся ранее функций. Пользователю предлагается выбрать функцию, после чего она связывается с указателем pFunc. В строках 34—36 выводятся текущие значения двух целочисленных переменных, вызывается текущая функция и выводятся результаты вычислений.

 

Указатели на функции

Обращение к функции через указатель записывается так же, как и обычный вызов функции, на которую он указывает. Просто вместо имени функции используется имя указателя на эту функцию.

Чтобы связать указатель на функцию с определенной функцией, нужно просто присвоить ему имя функции без каких-либо скобок. Имя функции. как вы уже знаете, представляет собой константный указатель на саму функцию. Поэтому указатель на функцию используется так же, как и ее имя. При вызове функции через указатель следует задать все параметры. установленные для текущей функции. Пример:

long(*pFuncOne) (int,int);

long SomeFunction (int,int);

pFuncOne = SomeFunction;

pFuncOne (5,7);

Зачем нужны указатели на функции

 

В программе, показанной в листинге 14.5, можно было бы обойтись и без указателей на функции, однако с их помощью значительно упрощается и становится читабельнее код программы: достаточно только выбрать функцию из списка и затем вызвать ее.

В листинге 14.6 используются прототипы и объявления функций листинга 14.5, но отсутствуют указатели на функции. Оцените различия между этими двумя листингами.

Листинг 14.6. Видоизмененный вариант листинга 14.5 без использования указателей на функции

1: // Листинг 14.6. Видоизмененный вариант листинга 14.5 без использования

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: bool fQuit = false;

14: int valOne=1, valTwo=2;

15: int choice;

16: while (fQuit == false)

17: {

18: cout << << "(0)Quit (1)Change Values (2)Square (3)Cube (4)Swap";

19: cin >> choice;

20: switch (choice)

21: {

22: case 1:

23: PrintVals(valOne, valTwo);

24: GetVals(valOne, valTwo);

25: PrintVals(valOne, valTwo);

26: break;

27:

28: case 2:

29: PrintVals(valOne, valTwo);

20: Square(valOne,valTwo);

31: PrintVals(valOne, valTwo);

32: break;

33:

34: case 3:

35: PrintVals(valOne, valTwo);

36: Cube(valOne, valTwo);

37: PrintVals(valOne, valTwo);

38: break;

39:

40: case 4:

41: PrintVals(valOne, valTwo);

42: Swap(valOne, valTwo);

43: PrintVals(valOne, valTwo);

44: break;

45:

46: default:

47: fOuit = true;

48: break;

49: }

50:

51: if (fQuit)

52: break;

53: }

54: return 0;

55: }

56:

57: void PrintVals(int x, int y)

58: {

59: cout << "x: " << x << " y: " << y << endl;

60: }

61:

62: void Square (int & rX, int & rY)

63: {

64: rX *= rX;

65: rY *= rY;

66: }

67:

68: void Cube (int & rX, int & rY)

69: {

70: int tmp;

71:

72: tmp = rX;

73: rX *= rX;

74: rX = rX * tmp;

75:

76: tmp = rY;

77: rY *= rY;

78: rY = rY * tmp;

79: }

80:

81: void Swap(int & rX, int & rY)

82: {

83: int temp;

84: temp = rX;

85: rX = rY;

86: rY = temp;

87: }

88:

89: void GetVals (int & rValOne, int & rValTwo)

90: {

91: cout << "New value for ValOne: ";

92: cin >> rValOne;

93: cout << "New value for ValTwo: ";

94: cin >> rValTwo;

95: }

 

Результат:

(0)Quit (1)Change Values (2)Square (3)Cube (4)Swap: 1

х. 1 у. 2

New value for ValOne: 2

New value for ValTwo: 3

(0)Quit (1)Change Values (2)Square (3)Cube (4)Swap: 3

x: 2 y: 3

x: 8 y: 27

(0)Quit (1 )Change Values (2)Square (3)Cube (4)Swap: 2

x: 8 y: 27

x: 64 y: 729

(0)Quit (1)Change Values (2)Square (3)Cube (4)Swap: 4

x: 64 y: 729

x: 729 y: 64

(0)Quit (1)Change Values (2)Square (3)Cube (4)Swap: 0

 

Анализ: Функции работают так же, как и в листинге 14.5. Информация, выводимая программой на экран, также не изменилась. Но размер программы увеличился с 22 до 46 строк. Причина в том, что вызов функции PrintVals() приходится повторять для каждого блока с оператором case.

Заманчивым может показаться вариант размещения функции PrintVals() вверху и внизу цикла while, а не в каждом блоке с оператором case. Но тогда функция PrintVals() будет вызываться даже в случае выхода из цикла, чего быть не должно.

 


Дата добавления: 2019-02-12; просмотров: 222; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!