Упражнения

  1. (*2) Определите итератор для класса string. Определите операцию конкатенации + и операцию "добавить в конец" +=. Какие еще операции над string вы хотели бы осуществлять?
  2. (*1.5) Задайте с помощью перегрузки () операцию выделения подстроки для класса строк.
  3. (*3) Постройте класс string так, чтобы операция выделения подстроки могла использоваться в левой части присваивания. Напишите сначала версию, в которой строка может присваиваться подстроке той же длины, а потом версию, где эти длины могут быть разными.
  4. (*2) Постройте класс string так, чтобы для присваивания, передачи параметров и т.п. он имел семантику по значению, то есть в тех случаях, когда копируется строковое представление, а не просто управляющая структура данных класса sring.
  5. (*3) Модифицируйте класс string из предыдущего примера таким образом, чтобы строка копировалась только когда это необходимо. То есть, храните совместно используемое представление двух строк, пока одна из этих строк не будет изменена. Не пытайтесь одновременно с этим иметь операцию выделения подстроки, которая может использоваться в левой части.
  6. (*4) Разработайте класс string с семантикой по значению, копированием с задержкой и операцией подстроки, которая может стоять в левой части.
  7. (*2) Какие преобразования используются в каждом выражении следующей программы:
8. struct X {9. int i;10. X(int);11. operator+(int);12. };13. struct Y {14. int i;15. Y(X);16. operator+(X);17. operator int();18. };19. X operator* (X,Y);20. int f(X);21. X x = 1;22. Y y = x;23. int i = 2;24. main()25. {26. i + 10;27. y + 10;28. y + 10 * y;29. x + y + i;30. x * x + i;31. f(7);32. f(y);33. y + y;34. 106 + y;35. }

Определите X и Y так, чтобы они оба были целыми типами. Измените программу так, чтобы она работала и печатала значения всех допустимых выражений.

  1. (*2) Определите класс INT, который ведет себя в точности как int. Подсказка: определите INT::operator int().
  2. (*1) Определите класс RINT, который ведет себя в точности как int за исключением того, что единственные возможные операции - это + (унарный и бинарный), - (унарный и бинарный), *, /, %. Подсказка: не определяйте $ (R?)INT::operator int().
  3. (*3) Определите класс LINT, ведущий себя как RINT за исключением того, что имеет точность не менее 64 бит.
  4. (*4) Определите класс, который реализует арифметику с произвольной точностью. Подсказка: вам надо управлять памятью аналогично тому, как это делалось для класса string.
  5. (*2) Напишите программу, доведенную до нечитаемого состояния с помощью макросов и перегрузки операций. Вот идея: определите для INT + чтобы он означал - и наоборот, а потом с помощью макроопределения определите int как INT. Переопределение часто употребляемых функций, использование параметров ссылочного типа и несколько вводящих в заблуждение комментариев помогут устроить полную неразбериху.
  6. (*3) Поменяйтесь со своим другом программами, которые у вас получились в предыдущем упражнении. Не запуская ее попытайтесь понять, что делает программа вашего друга. После выполнения этого упражнения вы будете знать, чего следует избегать.
  7. (*2) Перепишите примеры с comlpex (#6.3.1), tiny (#6.3.2) и string (#6.9) не используя friend функций. Используйте только функции члены. Протестируйте каждую из новых версий. Сравните их с версиями, в которых используются функции друзья. Еще раз посмотрите Упражнение 5.3.
  8. (*2) Определите тип vec4 как вектор их четырех float. Определите operator[] для vec4. Определите операции +, -, *, /, =, +=, -=, *=, /= для сочетаний векторов и чисел с плавающей точкой.
  9. (*3) Определите класс mat4 как вектор из четырех vec4. Определите для mat4 operator[], возвращающий vec4. Определите для этого типа обычные операции над матрицами. Определите функцию, которая производит исключение Гаусса для mat4.
  10. (*2) Определите класс vector, аналогичный vec4, но с длиной, которая задается как параметр конструктора vector::vector(int).
  11. (*3) Определите класс matrix, аналогичный mat4, но с размерностью, задаваемой параметрами конструктора matrix::matrix(int,int).

*1 В некоторых системах компоновщик настолько "умен", что ругается, даже если не определена неиспользуемая функция. В таких системах этим методом воспользоваться нельзя. (прим автора)


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: