Мегаобучалка Главная | О нас | Обратная связь


Описание класса дробей



2019-11-13 407 Обсуждений (0)
Описание класса дробей 0.00 из 5.00 0 оценок




Опишем класс fraction, реализующий представление дробей, а также операторы, которые к ним можно применять

#include <iostream>

using namespace std;

class fraction{

public:

int numerator,denominator; //числительизнаменатель

fraction();                //конструкторпоумолчанию

fraction(int x, int y);    //конструктор по двум числам

fraction(int x);        //конструктор по одному числу

fraction(const fraction& op); //конструкторкопирования

const fraction operator+(const fraction& op); //сложение

const fraction operator=(const fraction& op); //присваивание

//вводивывод

friend ostream& operator<<(ostream& os, const fraction& op);

friend istream& operator>>(istream& is, fraction& op);//ввод

private:

fraction reduce();    //сокращениедроби

}

Конструкторы класса дробей

Конструктор, принимающий один аргумент — ссылку на константный объект такого же типа — называется конструктором копирования (copyconstructor). Такой конструктор должен инициализировать создаваемый объект таким образом, чтобы он стал копией оригинального объекта. Такой конструктор так же может быть сгенерирован автоматически, если это возможно и есть такая необходимость. Но реализация по умолчанию (использующая копирование всех объектов-членов) может быть неудовлетворительной. В этом случае можно самостоятельно определить конструктор копирования

//конструктор по умолчанию - реализация

fraction::fraction(){

numerator=0;

denominator=1;

}

//конструкторподвумцелымчислам - реализация

fraction::fraction(int x, int y){

numerator=x;

denominator=y;

reduce();

}

//конструкторпреобразования (поодномуцеломучислу) - реализация

fraction::fraction(int x, int y){

numerator=x;

denominator=1;

}

//конструкторкопирования - реализация

fraction::fraction(const fraction& op){

numerator=op.numerator;

denominator=op.denominator;

}

Приватный метод reduce() для класса fraction

Время от времени при проведении операций с дробями или при вводе значений необходимо выполнять сокращение дроби, которое производится взаимным сокращением числителя и знаменателя дроби на их наибольший общий делитель (НОД). Метод не будет вызываться извне, поэтому он описан в разделе private. Сам НОД найдем методом Евклида, описанном в задаче «Наибольший общий делитель» из главы «Циклы» предыдущей части.

fraction fraction::reduce(){

   int a=numerator,b=denominator;

do{             //находим НОД по методу Евклида

if(a>=b){a %=b;}

       else{b %= a;}

} while(a*b>0);

   numerator/=a+b;   //сокращаемчислитель

   denominator/=a+b; //сокращаемзнаменатель

   return *this;

}

Обратите внимание на использование указателя thisпри завершении функции. Он всегда ссылается на текущий объект класса, к которому был применён метод.

Арифметические действия с дробями

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

Во-первых, нужно понимать, что оператор – по сути та же функция (метод класса). Тоесть, когдамыкaдобавляемb, происходит

a.+(b)

Таким образом для функций –членов класса операнд в арифметическом действии должен быть один (второй). К первому мы эту арифметическую операцию применяем как метод.

Во-вторых, оба операнда правильно объявить как const, хотя и не обязательно. Это делается для того, чтобы не изменить значения операндов. Проще говоря, чтобы при вычислении a+bзначения самих aи bне изменились.

const fraction fraction::operator+(const fraction& p){

fraction r;

r.numerator=numerator*p.denominator+p.numerator*denominator;

  r.denominator=denominator*p.denominator;

r.reduce();

returnr;

}

//операторприсваивания - реализация

const fraction fraction::operator=(const fraction& op){

return fraction(op);

}

Перегрузка операций ввода/вывода для класса

Очень важно при создании нового класса, расширяющего возможности языка, чтобы программист мог пользоваться для вывода объектов новых типов привычными операциями, такими как >>и <<. Нам потребуются входные потоки istreamи потоковые операции вывода ostream.

Их удобно объявить как дружественные, т.е. не являющиеся членами класса, но имеющие доступ к его методам.

ostream& operator<<(ostream& os, const fraction& op){

os<<op.numerator<<'/'<<op.denominator;

return os;

}

istream& operator>>(istream& is, fraction& op){

string s;

is>>s;

op.numerator=0;

op.denominator=0;

int i;

for(i=0;s[i]!='/';i++){(op.numerator*=10)+=s[i]-’0’;}

for(++i;s[i]!='\0';i++){(op.denominator*=10)+=s[i]-’0’;}

op.reduce();

returnis;

}

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

int main(){

fractiona(2,8),b(a),c,d; //примерыконструкторов

fraction x=a+b,y=x;  //присваивание

cout<<a<<'+'<<b<<'='<<y<<"\nВведите 2 дроби:\n";

cin>>c>>d;      //ввод

cout<<"Сумма ="<<c+d; //вывод

}

При этом результаты её работы отобразятся так:

 

 

Основы олимпиадного программирования

Программирование - как любовь: одно слово, за которым может скрываться бесконечное множество занятий.

Фредерик Брукс, "Мифический человеко-месяц"



2019-11-13 407 Обсуждений (0)
Описание класса дробей 0.00 из 5.00 0 оценок









Обсуждение в статье: Описание класса дробей

Обсуждений еще не было, будьте первым... ↓↓↓

Отправить сообщение

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



©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (407)

Почему 1285321 студент выбрали МегаОбучалку...

Система поиска информации

Мобильная версия сайта

Удобная навигация

Нет шокирующей рекламы



(0.006 сек.)