Модераторы: Poseidon

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [C++]Класс с перегруженными операциями, Создать класс(дробные числа) 
:(
    Опции темы
baldina
Дата 28.11.2013, 23:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 1
Всего: 101



управляемый код? ну да ладно... 
про устройство рациональных чисел вы что-то молчите...

PM MAIL   Вверх
DarkinRal
Дата 1.12.2013, 13:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


This_IS_300



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 27.11.2013
Где: Ukraine/Kremenchu k

Репутация: нет
Всего: нет



Цитата(baldina @  28.11.2013,  11:52 Найти цитируемый пост)
для этого нужно определить, какие данные будут в классе. думаю, это несложно: чем определяется рациональное число (дробь)?

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

PM MAIL WWW Skype   Вверх
baldina
Дата 1.12.2013, 18:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 1
Всего: 101



очень хорошо. давайте их обозначим p и q соответственно.
значит в реализации класса должны присутствовать два члена, в которых будут храниться значения p и q. надо определиться, какого они типа, и добавить их в класс - в приватную секцию (выше "public").

ими мы и будем манипулировать, реализуя методы класса.
PM MAIL   Вверх
DarkinRal
Дата 19.12.2013, 19:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


This_IS_300



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 27.11.2013
Где: Ukraine/Kremenchu k

Репутация: нет
Всего: нет



Код

#include<iostream>
class Frac {
private:
    int p,q;
 public:
   Frac& operator+=(const Frac&);
   Frac& operator-=(const Frac&);
   Frac& operator*=(const Frac&);
   Frac& operator/=(const Frac&);
   bool Frac::operator!=(const Frac& other) const {
       return !(*this == other);} // this - указатель на объект, к которому применяется функция-член класса
  bool operator==(const Frac& other) const {
      if (&other == this) return true;
      }
  
}
   std::string ToString() const; // функция константна, т.к. не меняет состояние самого объекта
   operator double() const;


Frac operator+(const Frac& lhs, const Frac& rhs) {
  Frac temp(lhs);
  temp += rhs; // используем Frac::operator+=()
  return temp;
}
Frac operator-(const Frac& lhs, const Frac& rhs) {
    Frac temp(lhs);
    temp -= rhs;
    return temp;
}
Frac operator*(const Frac& lhs, const Frac& rhs) {
    Frac temp(lhs);
    temp *= rhs;
    return temp;
}
Frac operator/(const Frac& lhs, const Frac& rhs) {
    Frac temp(lhs);
    temp /= rhs;
    return temp;
}


VS показует ошибки в функции константы.ToString() просит поставить ;
operator - функция преобразования должна быть нестатической функциией-членом



PM MAIL WWW Skype   Вверх
baldina
Дата 20.12.2013, 01:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 1
Всего: 101



функции-члены класса должны быть объявлены в теле класса. посчитайте скобочки.
определение класса должно заканчиваться точкой с запятой.

Данные класса p и q определены, прекрасно. Как будут устанавливаться их начальные значения? Для этого служат специальные функции-члены - конструкторы. Это функции одноименные с классом, вызываются в момент объявления переменной.

Код

class Foo {
  int data;
  public:
    Foo (int d) : data(d) {} // конструктор
};
...
Foo foo (5); // создается переменная foo, при этом вызывается конструктор Foo::Foo(5)

нам понадобится конструктор вида Frac (int p=0, int q=1)
параметры по умолчанию полезны тем, что мы сможем объявлять переменные не только как
Код

Frac f(1,2); // 1/2
но и так:
Код

Frac f1; // 0
Frac f2 = 5; // 5/1



теперь определение операций. давайте с легкого начнем. сумма двух рациональных чисел p1/q1+p2/q2= (p1*q2+p2*q1)/(q1*q2). значит функцию operator+= можно определить так:
Код

Frac& Frac::operator+= (const Frac& rhs) {
  p = p*rhs.q + rhs.p*q;
  q *= rhs.q;
  return *this;
}

Минус можно реализовать через плюс
Код

Frac& Frac::operator-= (const Frac& rhs) {
  return *this += Frac(-rhs.p, rhs.q);
}

остальные делаете аналогично. 

Как справитесь, поговорим о нормализации числа

PM MAIL   Вверх
DarkinRal
Дата 7.1.2014, 14:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


This_IS_300



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 27.11.2013
Где: Ukraine/Kremenchu k

Репутация: нет
Всего: нет



Код

#include<iostream>
class Frac {
private:
    int p,q;
public:
    Frac(int p=0,int q=1)
    {
     
    }

    Frac& Frac::operator+= (const Frac& rhs) {
   p = p*rhs.q + rhs.p*q;
   q *= rhs.q;
   return *this;
    }
    Frac& Frac::operator-= (const Frac& rhs) {
   return *this += Frac(-rhs.p, rhs.q);
    }
    Frac& Frac::operator/= (const Frac& rhs){
    p = p*rhs.q / rhs.p*q;
    q *= rhs.q;
    return *this;
    }
    Frac& Frac::operator*= (const Frac& rhs){
    p = p*rhs.q * rhs.p*q;
    q *= rhs.q;
    return *this;
    }

   Frac& operator+=(const Frac&);
   Frac& operator-=(const Frac&);
   Frac& operator*=(const Frac&);
   Frac& operator/=(const Frac&);
   bool Frac::operator!=(const Frac& other) const {
       return !(*this == other);} // this - указатель на объект, к которому применяется функция-член класса
   bool operator==(const Frac& other) const {
      if (&other == this) return true;
      }
  

   std::string ToString() const; // функция константна, т.к. не меняет состояние самого объекта
   operator double() const;

};

Frac operator+(const Frac& lhs, const Frac& rhs) {
  Frac temp(lhs);
  temp += rhs; // используем Frac::operator+=()
  return temp;
}
Frac operator-(const Frac& lhs, const Frac& rhs) {
    Frac temp(lhs);
    temp -= rhs;
    return temp;
}
Frac operator*(const Frac& lhs, const Frac& rhs) {
    Frac temp(lhs);
    temp *= rhs;
    return temp;
}
Frac operator/(const Frac& lhs, const Frac& rhs) {
    Frac temp(lhs);
    temp /= rhs;
    return temp;
}


Только не понял,что там в конструкторе надо объявить.
и надо ли там операции == и != ?

PM MAIL WWW Skype   Вверх
baldina
Дата 7.1.2014, 14:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 1
Всего: 101



DarkinRal, объявляя функцию в классе не надо писать Frac::
Этот префикс нужен только для определений вне класса, для указания к какому классу относится функция.
Вы бы хоть попробовали откомпилировать код.

Добавлено @ 14:37
Цитата(DarkinRal @  7.1.2014,  14:29 Найти цитируемый пост)
надо ли там операции == и !=

где там? все уже написано вроде как правильно.

в конструкторе надо проинициализировать значения членов класса p и q соответствующими аргументами конструктора. ну или хотя бы присвоить. арументам лучше дать другие имена, что бы не путать с членами класса. часто членам класса добавляют префиксы или суффиксы, что бы легче отличать. например, p_ и q_

Добавлено @ 14:39
т.е.

Код

class Frac {
 private:
   int p_, q_;
 public:
   Frac (int p, int q) : p_(p), q_(q) {}
   //или
   // Frac (int p, int q) { p_ = p; q_=q; }
   // но первая форма лучше
};


Это сообщение отредактировал(а) baldina - 7.1.2014, 14:40
PM MAIL   Вверх
baldina
Дата 7.1.2014, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 1
Всего: 101



для реализации операций понадобится функция нормализация числа: сокращение числителя и знаменателя на наибольший общий делитель, что бы числа, например, вида 4/8 приводить к 1/2 
для этого надо уметь находить НОД. существует алгоритм Евклида, который можно записать рекуррентным соотношением gcd (m, n) = gcd (n, m mod n) c с ограничением gcd (m, 0) = m
gcd - greatest common divisor
mod - операция получения остатка от деления, в C/C++ это операция %

в общем виде алгоритм можно реализовать простой рекурсивной функцией
Код

template <typename T>
T gcd (const T& m, const T& n) {
   if (n == 0)
      return m;
   else 
      return gcd (n, m % n);
}


Добавлено через 4 минуты и 10 секунд
в итоге должно получиться что-то вроде http://ideone.com/OHZ2ph
изучайте

Это сообщение отредактировал(а) baldina - 7.1.2014, 14:55
PM MAIL   Вверх
DarkinRal
Дата 26.2.2014, 18:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


This_IS_300



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 27.11.2013
Где: Ukraine/Kremenchu k

Репутация: нет
Всего: нет



Здраствуйте,спасибо за пример.Но когда запустил его через visual studio 2012 то выдало несколько ошибок:
Код

1>------ Построение начато: проект: ConsoleApplication1, Конфигурация: Debug Win32 ------
1>  Исходный код.cpp
1>d:\c-+\consoleapplication1\consoleapplication1\исходный код.cpp(57): error C2071: Frac::operator double: недопустимый класс хранения
1>d:\c-+\consoleapplication1\consoleapplication1\исходный код.cpp(100): error C2666: Frac::operator !=: для 2 перегрузок есть подобные преобразования
1>          d:\c-+\consoleapplication1\consoleapplication1\исходный код.cpp(48): может быть "bool Frac::operator !=(const Frac &) const"
1>          или       "встроенный оператор C++!=(double, int)"
1>          при попытке сопоставить список аргументов "(Frac, int)"
1>d:\c-+\consoleapplication1\consoleapplication1\исходный код.cpp(101): error C2666: Frac::operator !=: для 2 перегрузок есть подобные преобразования
1>          d:\c-+\consoleapplication1\consoleapplication1\исходный код.cpp(48): может быть "bool Frac::operator !=(const Frac &) const"
1>          или       "встроенный оператор C++!=(double, int)"
1>          при попытке сопоставить список аргументов "(Frac, int)"

PM MAIL WWW Skype   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.0877 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.