Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лафоре Р. - Объектно-ориентированное программир...doc
Скачиваний:
49
Добавлен:
01.04.2025
Размер:
40.77 Mб
Скачать

Введите Ваше имя: Джек Восьмеркин

Ваше имя: Джек Восьмеркин

Введите Ваш псевдоним: Американец

Здравствуйте. Американец

Введите Ваш адрес в несколько строк

Окончание ввода символ '$'

123456. Россия

г. Урюпинск. ул. Канавная!

$

Ваш адрес:

123456. Россия

г. Урюпинск, ул. Канавная

Поиск объектов класса string

Класс string включает в себя различные методы для поиска строк и фрагментов строк в объектах класса string. В программе SSTRFIND показаны некоторые из них.

// sstrfind.cpp

// поиск подстрок

#include <iostream>

#include <string>

using namespace std;

///////////////////////////////////////////////////////////

int main()

{

string s1 = "В лесу родилась елочка, в лесу она росла.";

int n;

n = s1.find("елочка");

cout << "Елочка найдена: " << n << endl;

n = s1.find_first_of("умка");

cout << "Первый из умка: " << n << endl;

n = s1.find_first_not_of("абвгдАБВГД");

cout << "Первый не из: " << n << endl;

return 0;

}

Метод find() предназначен для поиска строки, используемой в качестве аргу- мента, в строке, для которой был вызван метод. Здесь мы ищем слово «елочка» в строке s1, которая содержит отрывок известной песенки. Оно найдено на позиции 16. Как в строковом типе, позиция самого левого символа нумерует- ся как 0.

Метод find_first_of() предназначен для поиска любого символа из группы и возвращает позицию первого найденного. Здесь ищем любой символ из груп- пы 'у', 'м', 'к', 'а'. Первым из них будет найден символ 'у' в слове 'лесу' на пози- ции 5.

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

ла, который является вторым символом в строке. Вывод программы SSTRFIND будет таким:

Елочка найдена: 16 Первый из умка: 5 Первый не из абвгдАБВГД: 1

У многих из этих методов существуют варианты, которые мы не будем де- монстрировать здесь, такие, как функция rfind(), переворачивающая строку, find_ last_of(), ищущая последний символ, совпадающий с группой заданных симво- лов и find_last_not_of(). Все эти функции возвращают -1, если цель не найдена.

Модификация объектов класса string

Существуют различные пути модификации объектов класса string. В нашем сле- дующем примере показаны методы erase(), replace() и insert() в работе.

// sstrchng.cpp

// изменение частей строки

#include <iostream>

#include <string>

using namespace std;

///////////////////////////////////////////////////////////

int main()

{

string s1("Все хорошо, прекрасная маркиза.");

string s2("принцесса");

string s3("Приветствую ");

s1.erase(0, 12); // убираем "Все хорошо, "

s1.replace(11, 7, s2); // заменяем "маркиза" на "принцесса"

s1.insert(0, s3); // вставляем "Приветствую, "

s1.erase(s1.size() - 1, 1); // убираем '.'

s1.append(3, '!'); // добавляем '!!!'

int x = s1.find(' '); // ищем пробелы

while(x < s1.size()) // цикл по всем пробелам

{

s1.replace(x, 1, "/"); // заменяем пробел на '/'

x = s1.find(' '); // ищем следующий пробел

}

cout << "s1: " << s1 << endl;

return 0;

}

Метод erase() удаляет фрагмент из строки. Его первым аргументом является позиция первого символа фрагмента, а вторым — длина фрагмента. В нашем примере удалено "Все хорошо," из начала строки. Метод replace() заменяет часть строки на другую строку. Его первым аргументом является позиция начала за- мены, вторым — количество символов исходной строки, которое должно быть заменено, а третьим аргументом является строка для замены. Здесь маркиза за- меняется на принцесса.

Метод insert() вставляет строку, определенную во втором аргументе, на место, определенное в первом аргументе. В нашем примере "Приветствую" вставлено в начало строки s1. При втором использовании метода erase() применен метод size(), который возвращает количество символов в объекте класса string. Выра- жение size()-1 — это позиция последнего символа фрагмента, который будет удален. Метод append() ставит три восклицательных знака в конце предложения. В этой версии метода первый аргумент — это количество символов, которое бу- дет добавлено, а второй аргумент — это символы, которые будут добавлены.

В конце программы мы показали идиому, которую вы можете использовать для перезаписи нескольких фрагментов в другой строке. Здесь в цикле while мы ищем символ пробела, используя метод find(), и заменяем каждый из них на слэш, используя функцию replace().

Мы начали с объекта s1, содержащего в себе строку «Все хорошо, прекрасная маркиза». После замены вывод программы SSTRCHNG будет таким:

s1: Приветствую/прекрасная/принцесса!!!

Сравнение объектов класса string

Можно использовать перегруженные операции или метод compare() для сравне- ния объектов класса string. Задача состоит в том, чтобы определить, являются ли строки идентичными или какая из них предшествует другой в алфавитном поряд- ке. В программе SSTRCOM показаны некоторые возможности.

// sstrcom.cpp

// сравнение строк

#include <iostream>

#include <string>

using namespace std;

///////////////////////////////////////////////////////////

int main()

{

string aName = "Иван";

string userName;

cout << "Введите Ваше имя: ";

cin >> userName;

if(userName == aName)

cout << "Привет, Иван\n";

else if(userName < aName)

cout << "Ваше имя идет до имени Иван\n";

else

cout << "Ваше имя идет после имени Иван\n";

int n = userName.compare(0, 2, aName, 0, 2);

cout << "Первые две буквы Вашего имени ";

if(n == 0)

cout << "совпадают ";

else if(n < 0)

cout << "идут до ";

else

cout << "идут после ";

cout << aName.substr(0, 2) << endl;

return 0;

}

В первой части программы операции == и < используются для определения того, является ли написанное пользователем имя идентичным имени Иван или оно предшествует или следует за ним в алфавитном порядке. Во второй части программы метод compare() сравнивает только первые две буквы слова «Иван» с первыми двумя буквами имени, напечатанного пользователем (userName). Аргу- ментами этой версии метода compare() являются начальная позиция userName, число символов, которые надо сравнить, строка, используемая для сравнения (aName), а также начальная позиция и количество символов в строке aName. Вот пример взаимодействия с программой SSTRCOM:

Введите Ваше имя: Алексей

Ваше имя идет до имени Иван

Первые две буквы Вашего имени идут до Ив

Первые две буквы имени «Иван» получают, используя метод substr(). Он воз- вращает фрагмент строки, для которой метод был вызван. Его первый аргу- мент — это позиция фрагмента, а второй — количество символов.

Доступ к символам в объектах класса string

Доступ к отдельным символам объектов класса string вы можете получить раз- ными способами. В нашем следующем примере мы покажем доступ с использо- ванием метода at(). Вы можете также использовать перегруженную операцию [], которая позволяет рассматривать объект класса string как массив. Однако опера- ция [] не предупредит вас, если вы попытаетесь получить доступ к символу, лежа- щему за пределами массива (например, после конца строки). Операция [] ведет себя здесь так, как обращается с настоящим массивом, и это более эффективно. Но это может привести к тяжелым для диагностики программным ошибкам. Безопасней использовать метод at(), который остановит программу, если вы ис- пользуете индекс, не входящий в допустимые границы. (Есть одно исключение, и мы обсудим его в главе 14 «Шаблоны и исключения».)

// sstrchar.cpp

// доступ к символам в строке

#include <iostream>

#include <string>

using namespace std;

///////////////////////////////////////////////////////////

int main()

{

char charray[80];

string word;

cout << "Введите слово: ";

cin >> word;

int wlen = word.length(); // длина строки

cout << "По одному символу: ";

for(int j = 0; j < wlen; j++)

cout << word.at(j); // тут будет проверка на выход за пределы строки

// cout << word[j]; // а тут проверки не будет

word.copy(charray, wlen, 0); // копируем строку в массив

charray[wlen] = 0;

cout << "\nМассив содержит: " << charray << endl;

return 0;

}

В этой программе мы использовали метод at() для вывода содержимого объ- екта класса string символ за символом. Аргумент метода at() — это местонахож- дение символа в строке.

Затем мы показали, как вы можете использовать метод copy() для копирова- ния объекта класса string в массив типа char, эффективно преобразовывая его в строковый тип. Вслед за копированием, после последнего символа строки дол- жен быть вставлен нулевой символ ('\0') для завершения преобразования к стро- ковому типу. Метод length() класса string возвращает то же число, что и метод size(). Приведем вывод программы SSTRCHAR:

Введите слово: симбиоз По одному символу: симбиоз Массив содержит: симбиоз

(Вы можете также преобразовать объект класса string к строковому типу, исполь- зуя методы c_str() или data(). Однако для использования этих методов вам нуж- но изучить указатели, которые мы рассмотрим в главе 10.)

Другие методы класса string

Мы видели, что методы size() и length() возвращают число символов строки объ- екта класса string. Количество памяти, занятое строкой, обычно больше, чем в действительности это необходимо. (Хотя если строка не была инициализирова- на, то она использует для символов 0 байтов.) Метод capacity() возвращает дейст- вительное количество занятой памяти. Вы можете добавлять символы в строку, не добавляя памяти в нее до тех пор, пока этот лимит не будет исчерпан. Метод max_size() возвращает максимально возможный размер объекта класса string. Это количество будет на три байта меньше, чем максимальное значение переменной типа int в вашей системе. В 32-битной Windows системе это 4 294 967 293 байта, но размер памяти будет, возможно, ограничен этим количеством.

Многие из методов класса string, которые мы обсудили, имеют варианты, отличающиеся количеством и типом аргументов. Обратитесь к документации вашего компилятора для выяснения деталей.

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

Класс string — в действительности только один из возможных строковых классов, производных от класса-шаблона basic_string. Класс string основан на ти- пе char, но общий вариант использует тип wchar_t. Это позволяет классу basic_ string использоваться при работе с другими языками, имеющими больше симво- лов, чем в русском. Файлы помощи вашего компилятора могут содержать спи- сок функций класса string в классе basic_string.

Резюме

Массивы содержат набор данных одинакового типа. Этот тип может быть прос- тым типом, структурой или классом. Члены массива называются элементами. К элементам можно получить доступ, используя число, которое называется ин- дексом. Элементы могут быть инициализированы определенным значением при определении массива. Массив может иметь несколько размерностей. Двумерный массив — это массив массивов. Адрес массива может быть использован как аргу- мент функции; сам массив при этом не копируется. Массив может быть исполь- зован как переменная класса. Необходимо позаботиться о том, чтобы данные не были помешены за пределы массива.

Строковый тип представляет собой массив элементов типа char. Последний символ такой строки должен быть нулевым, '\0'. Строковая константа имеет специальную форму, она может быть записана удобным для нас способом: это текст, заключенный в двойные кавычки. Для работы со строками используются различные библиотечные функции. Массив строк — это массив массивов типа char. Создавая строковую переменную, нужно быть уверенным, что массив име- ет достаточный размер для помещения в него строки. Строки, используемые в качестве аргументов в библиотечных функциях, вы сможете найти в старых программах. Обычно такое использование строкового типа в современных про- граммах не рекомендуется.

Предпочтительнее использовать для работы со строками объекты класса string. Эти объекты могут работать с перегруженными операциями и методами класса. Пользователю не нужно заботиться об управлении памятью при исполь- зовании объектов класса string.

Вопросы

Ответы на эти вопросы вы сможете найти в приложении Ж.

1. Доступ к элементам массива осуществляется с помощью:

а) подхода FIFO;

б) операции точки;

в) имени элемента;

г) индекса элемента.

  1. Все элементы массива должны быть типа.

  2. Напишите выражение, которое определяет одномерный массив, именован- ный как double Array, типа double, содержащий 100 элементов.

  3. Элементы 10-элементного массива нумеруются начиная с и до .

  4. Напишите выражение, которое выводит j элемент массива double Array с по- мощью cout и операции <<.

  5. Какой по счету элемент массива double Array[7]?

а) шестой;

б) седьмой;

в) восьмой;

г) неизвестно.

  1. Напишите выражение, которое определяет массив coins типа int и ини- циализирует его значениями пенни: 5 центов, 10 центов, 25 центов, 50 цен- тов и 1 доллар.

  2. При доступе к многомерному массиву его индексы:

а) разделены запятыми;

б) заключены в квадратные скобки и разделены запятыми;

в) разделены занятыми и заключены в квадратные скобки;

г) заключены в квадратные скобки.

  1. Напишите выражение для доступа к 4-му элементу 2-го подмассива дву- мерного массива twoD.

  2. Истинно ли следующее утверждение: в C++ возможна реализация четы- рехмерного массива?

  3. Для двумерного массива flarr типа float запишите выражение, которое объявляет массив и инициализирует его первый подмассив значениями 52, 27, 83; второй — значениями 94, 73, 49; третий — значениями 3, 6, 1.

  4. Имя массива, используемое в файлах кода, представляет собой

массива.

  1. При передаче имени массива в функцию она:

а) работает с тем же массивом, с которым работает и вызывающая функ- цию программа;

б) работает с копией массива, переданной программой;

в) ссылается на массив, используя то же имя, которое используется в вы- зывающей программе;

г) ссылается на массив, используя другое имя, чем то, которое использу- ется в вызывающей программе.

  1. Что определяет это выражение?

employee emplist[1000];

  1. Напишите выражение для доступа к переменной salary структуры, кото- рая является 17-м элементом массива emplist.

  2. Данные, помещенные в стек первыми:

а) не имеют индексного номера;

б) имеют индекс, равный 0;

в) будут первыми извлечены из стека;

г) будут извлечены из стека последними.

  1. Напишите выражение, которое определяет массив manybirds, содержащий в себе 50 объектов типа bird.

  2. Истинно ли следующее утверждение: компилятор будет протестовать, ес- ли вы попытаетесь получить доступ к 14 элементу массива в 10-элемент- ном массиве?

  3. Напишите выражение, которое вызывает метод cheep() для объекта класса bird, являющегося 27-м элементом массива manybirds.

  4. Строка в C++ — это типа .

  5. Напишите выражение, которое определяет строковую переменную city, содержащую строку длиной до 20 символов (это небольшая хитрость).

  6. Напишите выражение, которое определяет строковую константу dextrose, имеющую значение «C6H1206 - H20».

  7. Истинно ли следующее утверждение: операция >> прекращает считыва- ние строки при обнаружении пробела?

  8. Вы можете считывать ввод, который содержит несколько строк или текст, используя:

а) обыкновенную комбинацию cout <<;

б) метод cin.get() с одним аргументом;

в) метод cin.get() с двумя аргументами;

г) метод cin.get() с тремя аргументами;

д) метод cin.get() с одним аргументом.

  1. Напишите выражение, которое использует библиотечную функцию для копирования строки name в строку blank.

  2. Напишите объявление класса dog, который содержит две переменных: строку breed и переменную age типа int (методов класс не имеет).

  3. Истинно ли следующее утверждение: предпочтительнее использовать стро- ковый тип вместо стандарного класса string в своих программах?

  4. Объекты класса string:

а) заканчиваются нулевым символом;

б) могут быть скопированы с операцией присваивания;

в) не требуют управления памятью;

г) не имеют методов класса.

  1. Напишите выражение, которое осуществляет поиск строки «кот» в стро- ке s1.

  2. Напишите выражение, которое вставляет строку «кот» в строку s1 на по- зицию 12.

Упражнения

Решения к упражнениям, помеченным знаком *, можно найти в приложении Ж. *1. Напишите функцию reversit(), которая переворачивает строку (массив типа char). Используйте цикл for, который меняет местами первый и последний символы, затем следующие и т. д. до предпоследнего. Строка должна пере- даваться в функцию reversit() как аргумент.

Напишите программу для выполнения функции reversit(). Программа долж- на принимать строку от пользователя, вызывать функцию reversit(), а за- тем выводить полученный результат. Используйте метод ввода, который позволяет использовать внутренние пробелы. Протестируйте программу на примере фразы «Аргентина манит негра».

*2. Создайте класс employee, который содержит имя (объект класса string) и но- мер (типа long) служащего. Включите в него метод getdata(), предназна- ченный для получения данных от пользователя и помещения их в объект, и метод putdata(), для вывода данных. Предполагаем, что имя не может иметь внутренних пробелов.

Напишите функцию main(), использующую этот класс. Вам нужно будет создать массив типа employee, а затем предложить пользователю ввести данные до 100 служащих. Наконец, вам нужно будет вывести данные всех служащих.

*3. Напишите программу, вычисляющую среднее значение до 100 интервалов, введенных пользователем. Создайте массив объектов класса Distance, как это было сделано в примере ENGLARAY этой главы. Для вычисления сред- него значения вы можете позаимствовать метод add_dist() из примера ENGLCON главы 6. Вам также понадобится метод, который выделяет целую часть из значения Distance. Вот одна из возможностей:

void Distance::div_dist(Distance d2, int divisor)

{

float fltfeet = d2.feet + d2.inches / 12.0;

float temp = fltfeet /= divisor;

feet = int(fltfeet);

inches = (temp - feet) * 12.0;

}

4. Начните с программы, которая позволяет пользователю вводить целые чис- ла, а затем сохранять их в массиве типа int. Напишите функцию maxint(), которая, обрабатывая элементы массива один за другим, находит наиболь- ший. Функция должна принимать в качестве аргумента адрес массива и количество элементов в нем, а возвращать индекс наибольшего элемента. Программа должна вызвать эту функцию, а затем вывести наибольший элемент и его индекс. (Смотрите программу SALES этой главы.)

    1. Начните с класса fraction из упражнений 11 и 12 главы 6. Напишите функцию main(), которая получает случайные дробные числа от пользова- теля, сохраняет их в массиве типа fraction, вычисляет среднее значение и выводит результат.

    2. В игре бридж каждому из игроков раздают 13 карт, таким образом коло- да расходуется полностью. Модифицируйте программу CARDARAY этой главы так, чтобы после перемешивания колоды она делилась на четыре части по 13 карт каждая. Каждая из четырех групп карт затем должна быть выведена.

    3. Одним из недостатков C++ является отсутствие для бизнес-программ встроенного типа для денежных значений, такого, как $173 698 001.32. Такой денежный тип должен иметь возможность для хранения числа с фиксированной десятичной точкой точностью около 17 знаков, которого было бы достаточно для хранения национального долга в долларах и цен- тах. К счастью, встроенный тип C++ long double имеет точность 19 цифр, поэтому мы можем использовать его как базисный для класса money, даже используя плавающую точку. Однако нам нужно будет добавить возмож- ность ввода и вывода денежных значений с предшествующим им знаком доллара и разделенными запятыми группы по три числа: так проще читать большие числа. Первым делом при разработке такого класса напишем ме- тод mstold(), который принимает денежную строку, то есть строку, пред- ставляющую собой некоторое количество денег типа

"$1 234 567 890 123.99"

в качестве аргумента и возвращает эквивалентное ее значению число типа long double.

Вам нужно будет обработать денежную строку как массив символов и, просматривая ее символ за символом, скопировать из нее только цифры (0-9) и десятичную точку в другую строку. Игнорируется все остальное, включая знак доллара и запятые. Затем вы можете использовать биб- лиотечную функцию _atold() (заметим, что здесь название функции на- чинается с символа подчеркивания — заголовочные файлы STDLIB.H или MATH.H) для преобразования новой строки к числу типа long double. Пред- полагаем, что денежное значение не может быть отрицательным. Напи- шите функцию main() для проверки метода mstold(), которая несколько раз получает денежную строку от пользователя и выводит соответству- ющее число типа long double.

    1. Другим недостатком C++ является отсутствие автоматической проверки индексов массива на соответствие их границам массива (это делает дей- ствия с массивами быстрыми, но менее надежными). Мы можем исполь- зовать класс для создания надежного массива, который проверяет индек- сы при любой попытке доступа к массиву.

Напишите класс safearay, который использует массив типа int фиксиро- ванного размера (назовем его LIMIT) в качестве своей единственной пере- менной. В классе будет два метода. Первый, putel(), принимает индекс и значение типа int как аргументы и вставляет это значение в массив по за- данному индексу. Второй, getel(), принимает индекс как аргумент и воз- вращает значение типа int, содержащееся в элементе с этим индексом.

safearay sa1; // описываем массив

int temp = 12345; // описываем целое

sa1.putel(7, temp); // помещаем значение temp в массив

temp = sa1.getel(7); // получаем значение из массива

Оба метода должны проверять индекс аргумента, чтобы быть уверенны- ми, что он не меньше 0 и не больше, чем LIMIT-1. Вы можете использовать этот массив без опаски, что запись будет произведена в другие части па- мяти.

Использование методов для доступа к элементам массива не выглядит так наглядно, как использование операции []. В главе 8 мы увидим, как перегрузить эту операцию, чтобы сделать работу нашего класса safearay похожей на работу встроенных массивов.

    1. Очередь — это устройство для хранения данных, похожее на стек. Отли- чие в том, что в стеке последний сохраненный элемент будет первым извлеченным, тогда как в очереди первый сохраненный элемент будет первым извлеченным. То есть в стеке используется подход «последний вошел — первый вышел» (LJFO), а в очереди используется подход «пер- вый вошел — первый вышел» (FIFO). Очередь похожа на простую оче- редь посетителей магазина: первый, кто встал в очередь, будет обслужен первым.

Перепишите программу STAKARAY из этой главы, включив в нее класс queue вместо класса stack. Кроме того, класс должен иметь два метода: один, называемый put(), для помещения элемента в очередь; и другой, на- зываемый get(), для извлечения элемента из очереди. Эти методы эквива- лентны методам push() и pop() класса stack.

Оба класса, stack и queue, используют массив для хранения данных. Одна- ко вместо одного поля top типа int, как в классе stack, вам понадобятся два поля для очереди: одна, называемая head, указывающая на начало очере- ди; и вторая, tail, указывающая на конец очереди. Элементы помещаются в конец очереди (как посетители банка, становящиеся в очередь), а извле- каются из начала очереди. Конец очереди перемещается к началу по мас- сиву по мере того, как элементы добавляются и извлекаются из очереди. Такие результаты добавляют сложности: если одна из двух переменных

head или tail примут значение конца массива, то следует вернуться на на- чало. Таким образом, вам нужно выражение типа

if(tail == MAX - 1) tail = -1;

для возврата переменной tail и похожее выражение для возврата перемен- ной head. Массив, используемый в очереди, иногда называют круговым буфером, так как начало и конец очереди циркулируют по нему вместе с ее данными.

    1. Матрица — это двумерный массив. Создайте класс matrix, который пре- доставляет те же меры безопасности, как и класс из упражнения 7, то есть осуществляет проверку индексов массива на вхождение их в границы массива. Полем класса matrix будет массив 10 на 10. Конструктор должен позволять программисту определить реальный размер массива (допустим, сделать его меньше, чем 10 на 10). Методам, предназначенным для досту- па к членам матрицы, теперь нужны два индекса: по одному для каждой размерности массива. Вот фрагмент функции main(), которая работает с таким классом:

matrix m1(3, 4); // описываем матрицу

int temp = 12345; // описываем целое

ml.putel(7, 4, temp); // помещаем значение temp в матрицу

temp = m1.getel(7, 4); // получаем значение из матрицы

11. Вернемся к обсуждению денежных строк из упражнения 6. Напишите ме- тод ldtoms() для преобразования числа типа long double в денежную строку, представляющую это число. Для начала вам нужно проверить, что значе- ние long double не очень большое. Мы предполагаем, что вы не будете пы- таться преобразовать число, больше чем 9 999 999 999 999 990.00. Затем преобразуем long double в строку (без знака доллара и запятых), храня- щуюся в памяти, используя объект ostrstream, как рассматривалось ранее в этой главе. Получившаяся отформатированная строка может быть поме- щена в буфер, называющийся ustring.

Затем вам нужно будет создать другую строку, начинающуюся со знака доллара, далее копируем цифру за цифрой из строки ustring, начиная сле- ва и вставляя запятые через каждые три цифры. Также вам нужно подав- лять нули в начале строки. Например, вы должны вывести $3 124.95, а не $0 000 000 000 003 124.95. Не забудьте закончить строку нулевым симво- лом '\0'.

Напишите функцию main() для тестирования этой функции путем много- кратного ввода пользователем чисел типа long double и вывода результата в виде денежной строки.

  1. Создайте класс bMoney. Он должен хранить денежные значения как long double. Используйте метод mstold() для преобразования денежной строки, введенной пользователем, в long double, и метод ldtoms() для преобразова- ния числа типа long double в денежную строку для вывода (см. упражне- ния 6 и 10). Вы можете вызывать для ввода и вывода методы getmoney()

и putmoney(). Напишите другой метод класса для сложения двух объектов типа bMoney и назовите его madd(). Сложение этих объектов легко произ- вести: просто сложите переменную типа long double одного объекта с та- кой же переменной другого объекта. Напишите функцию main(), которая просит пользователя несколько раз ввести денежную строку, а затем вы- водит сумму значений этих строк. Вот как может выглядеть определение класса:

class bMoney {

private:

long double money; public: bMoney();

bMoney(char s[]);

void madd(bMoney m1, bMoney m2);

void getmoney();

void putmoney();

};