Класи С ++ можуть створюватися для опису найнесподіваніших сутностей реального світу. Створіть клас «геометрична прогресія», об'єкти якого:
- відображали б геометричну прогресію із заданим початковим членом і знаменником;
- по індексації дозволяли отримати значення члена прогресії з будь-яким порядковим номером;
- дозволяли отримати суму початкових N-членів прогресії;
 
перезарядка Klass, возможно, іншими корисними властивостями.
Рішення:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | #include <iostream> #include <cstdlib> #include <map> using namespace std; class  progression : protected pair<double, double> { private:  double power(unsigned n) {  switch (n) {  case 0:  return 1.;  case 1:  return second;  default: {  double a2 = power(n / 2);  a2 *= a2;  return n & 1 ? second * a2 : a2;  }  }  } public:  progression(double first, double denominator) {  this->first = first;  second = denominator;  }  ~progression(void) {}  progression(const progression& p) {  first = p.first;  second = p.second;  }  progression& operator =(const progression& p) {  first = p.first;  second = p.second;  return *this;  }  void set(double first, double denominator = 0) {  this->first = first;  if (denominator != 0) second = denominator;  }  double operator [](int n) {  return first * power(n);  }  double summa(int n) {  double ret = first / second, sum = 0.0;  while (--n >= 0)  sum += (ret *= second);  return sum;  }  void put(double *array, int size) {  double ret = first / second;  while (--size >= 0)  *array++ = (ret *= second);  }  friend ostream& operator <<(ostream& out, progression& obj) {  return out << "<" << obj.first << "|"                            << obj.second << ">";  } }; int main(int argc, char* argv[]) {  unsigned n = argc > 1 ? atoi(argv[1]) : 7;  double *test = new double[n];  progression prg(1, 2);  setlocale(LC_ALL, "rus");  while (true) {  int i = 0;  for (unsigned i = 0; i < n; i++)  test[i] = prg[i];  for (unsigned i = 0; i < n; i++)  cout << test[i] << " | ";  cout << endl;  cout << "сколько членов суммировать?: ";  cin >> i;  cout << prg << " : сумма " << i << " членов = "                      << prg.summa(i) << endl;  double first, divisor;  cout << "новые параметры прогрессии "                      << "(начало знаменатель): ";  cin >> first >> divisor;  if (0 == first || 0 == divisor) break;  prg = progression(first, divisor);  }  delete[] test; } | 
Можна було б, звичайно, як класу геометричній прогресії зберігати необхідну кількість початкових членів ряду. Але це а). вкрай марнотратно і б). при такому поданні незрозуміло, яке число членів ряду зберігати? Показане ж рішення компактне і ефективне:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | $ ./progression 1 | 0.5 | 0.25 | 0.125 | 0.0625 | 0.03125 | 0.015625 | сколько членов суммировать?: 10 <1|0.5> : сумма 10 членов = 1.99805 новые параметры прогрессии (начало знаменатель): 1 .3 1 | 0.3 | 0.09 | 0.027 | 0.0081 | 0.00243 | 0.000729 | сколько членов суммировать?: 5 <1|0.3> : сумма 5 членов = 1.4251 новые параметры прогрессии (начало знаменатель): 1 1.1 1 | 1.1 | 1.21 | 1.331 | 1.4641 | 1.61051 | 1.77156 | сколько членов суммировать?: 20 <1|1.1> : сумма 20 членов = 57.275 новые параметры прогрессии (начало знаменатель): 1 -.5 1 | -0.5 | 0.25 | -0.125 | 0.0625 | -0.03125 | 0.015625 | сколько членов суммировать?: 20 <1|-0.5> : сумма 20 членов = 0.666666 новые параметры прогрессии (начало знаменатель): 1 -1.2 1 | -1.2 | 1.44 | -1.728 | 2.0736 | -2.48832 | 2.98598 | сколько членов суммировать?: 15 <1|-1.2> : сумма 15 членов = 7.45774 новые параметры прогрессии (начало знаменатель): 1 -1.2 1 | -1.2 | 1.44 | -1.728 | 2.0736 | -2.48832 | 2.98598 | сколько членов суммировать?: 16 <1|-1.2> : сумма 16 членов = -7.94928 новые параметры прогрессии (начало знаменатель): ^C | 
Особливістю рішення є те, що при виконанні операції індексації (вилучення члена прогресії) робиться швидке рекурсивне (алгоритм Хоара) піднесення до степеня знаменника.
Параметром командного рядка можна перевизначити довжину тестового масиву, куди переписуються члени прогресії:
| 1 2 3 4 5 | $ ./progression 12 1 | 0.5 | 0.25 | 0.125 | 0.0625 | 0.03125 | 0.015625 | 0.0078125 | 0.00390625 | 0.00195312 | 0.000976562 | 0.000488281 | сколько членов суммировать?: 12 <1|0.5> : сумма 12 членов = 1.99951 ... | 
йди ти нахуй зі своєю геометричною прогресією