Russian Qt Forum
Октябрь 02, 2024, 01:33 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Перегрузка оператора *  (Прочитано 12414 раз)
Даниил
Гость
« : Октябрь 09, 2011, 17:20 »

Здравствуйте.

Пишу класс, для работы с простыми дробями. Застрял на перегрузке операторов.
Стандартная ситуация: необходимо выполнять математический оператор и возвращать полученное значение.
Класс:
Код
C++ (Qt)
class TFrac
{
public:
   TFrac();
   TFrac(int a, int b);
   TFrac(QString drob);
 
   void operator =      (TFrac &other);
   TFrac& operator *      (TFrac &other);
 
private:
   int chislitel;
   int znamenatel;
};
 
Реализация:
Код
C++ (Qt)
void TFrac::operator =(TFrac &other)
{
   this->chislitel = other.chislitel;
   this->znamenatel = other.znamenatel;
}
TFrac& TFrac::operator *(TFrac const &other)
{
       this->chislitel *= this->chislitel;
       this->znamenatel *= this->znamenatel;
       return *this;
}
 

Main:
Код
C++ (Qt)
...
TFrac first(1,3);
TFrac second(2,3);
TFrac third;
third = first * second;
...
 
Внимание, вопрос: как осуществить умножение, не изменяя первый операнд?
Записан
Nimbus
Гость
« Ответ #1 : Октябрь 09, 2011, 17:29 »

>TFrac& operator *      (TFrac &other);
>TFrac& TFrac::operator *(TFrac const &other)
А оно вообще "конпелируется"?  Улыбающийся

Надо так:
Код
C++ (Qt)
//Declaration
TFrac& operator *      (const TFrac &other) const;
//Implementation
TFrac& TFrac::operator *(const TFrac  &other) const {
   return TFrac(chislitel * other.chislitel,
       znamenatel * other.znamenatel);
}
 
Если конечно твой конструктор TFrac(int a, int b) инициализирует числитель и знаменатель Подмигивающий
Записан
Даниил
Гость
« Ответ #2 : Октябрь 09, 2011, 17:36 »

>TFrac& operator *      (TFrac &other);
>TFrac& TFrac::operator *(TFrac const &other)
А оно вообще "конпелируется"?  Улыбающийся
Если конечно твой конструктор TFrac(int a, int b) инициализирует числитель и знаменатель Подмигивающий

Оно компилириуется, а вот так как ты указал - нет.
Код:
TFrac.cpp:194: ошибка: invalid initialization of non-const reference of type 'TFrac&' from a temporary of type 'TFrac'
Записан
Nimbus
Гость
« Ответ #3 : Октябрь 09, 2011, 17:41 »

Оно компилириуется, а вот так как ты указал - нет.
Код:
TFrac.cpp:194: ошибка: invalid initialization of non-const reference of type 'TFrac&' from a temporary of type 'TFrac'
Пардон. Убери из объявления возвращаемого значения ссылку (&), т. е.:
TFrac operator *      (const TFrac &other) const;
и
TFrac TFrac::operator *(const TFrac  &other) const
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4744



Просмотр профиля WWW
« Ответ #4 : Октябрь 09, 2011, 17:43 »

потому что в коде JC присутствует & - ссылка на временную переменную, что и сказано в ошибке. убирание амперсанда всё решит.

оператор присваивания тоже весело объявлен у тебя Улыбающийся
Код
C++ (Qt)
TFrac &TFrac::operator =(const TFrac &other)
{
   if (this != &other)
   {
       this->chislitel = other.chislitel;
       this->znamenatel = other.znamenatel;
   }
   return *this;
}
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Даниил
Гость
« Ответ #5 : Октябрь 09, 2011, 17:45 »

потому что в коде JC присутствует & - ссылка на временную переменную, что и сказано в ошибке. убирание амперсанда всё решит.

оператор присваивания тоже весело объявлен у тебя Улыбающийся
Код
C++ (Qt)
TFrac &TFrac::operator =(const TFrac &other)
{
   if (this != &other)
   {
       this->chislitel = other.chislitel;
       this->znamenatel = other.znamenatel;
   }
   return *this;
}

Лять ... из-за тебя еще и оператор != перегружать  Смеющийся
Да, кстати такой код работает ТОЛЬКО в таком виде:
Код
C++ (Qt)
...
TFrac third = first * second;
...
 
А так, как у меня написано:
Код
C++ (Qt)
...
TFrac fhird();
third = first * second;
...
 
Вываливается ошибка:
Код:
main.cpp:13: ошибка: no match for 'operator=' in 'third = first.TFrac::operator*(((const TFrac&)((const TFrac*)(& second))))'
« Последнее редактирование: Октябрь 09, 2011, 17:49 от Даниил » Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4744



Просмотр профиля WWW
« Ответ #6 : Октябрь 09, 2011, 17:49 »

там сравнение указателей Подмигивающий
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Nimbus
Гость
« Ответ #7 : Октябрь 09, 2011, 17:56 »


Код
C++ (Qt)
...
TFrac third = first * second;
...
 

Логично, потому что это дефолтный конструктор копирования вызывается.
Записан
Даниил
Гость
« Ответ #8 : Октябрь 09, 2011, 17:59 »

Логично, потому что это дефолтный конструктор копирования вызывается.
Спасибо, за справку.
А как недефолтный сделать?  Подмигивающий
Записан
Nimbus
Гость
« Ответ #9 : Октябрь 09, 2011, 18:02 »

А как недефолтный сделать?  Подмигивающий
Перегрузи, если ещё не перегружен. И реализуй его так же как operator=. Только там не нужно проверять адрес и возвращать значение.
И вообще, это незачем, если нет нужды в глубоком копировании.
Проблема в чём-то другом. Почему он указал ((const TFrac&)((const TFrac*)(& second))), в частности звёздочку - вот это интересно. И почему там second, а не other? Подмигивающий
« Последнее редактирование: Октябрь 09, 2011, 18:06 от JC » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Октябрь 09, 2011, 19:21 »

Возвращение ссылки лучше оставить для оператора *= а умножение (и др. арифметику) сделать так 
Код
C++ (Qt)
class TFrac
{
public:
..  
friend TFrac operator * ( const TFrac & f1, const TFrac & f2 )  { return TFrac(f1.a * f2.a, f1.b * f2.b); }
...
int a, b;
};

Также
Код
C++ (Qt)
   int chislitel;
   int znamenatel;
 
Обычно члены таких классов float или double, ну да ладно. А вот длина имен совершенно неподходящая, при интенсивном обращении Вы быстро устанете их писать. В данном конкретном случае короткие имена лучше, из одной буквы - еще лучше. Также нечего стесняться сделать все public - нет правил без исключений
Записан
Даниил
Гость
« Ответ #11 : Октябрь 09, 2011, 19:52 »

Собственно проблему не решает, по прежнему ругается на присваивание:
Код:
main.cpp:13: ошибка: no match for 'operator=' in 'third = operator*(((const TFrac&)((const TFrac*)(& first))), ((const TFrac&)((const TFrac*)(& other))))'
Записан
Nimbus
Гость
« Ответ #12 : Октябрь 10, 2011, 04:18 »

Собственно проблему не решает, по прежнему ругается на присваивание:
Код:
main.cpp:13: ошибка: no match for 'operator=' in 'third = operator*(((const TFrac&)((const TFrac*)(& first))), ((const TFrac&)((const TFrac*)(& other))))'
Выложи уже свой код полностью
Записан
Даниил
Гость
« Ответ #13 : Октябрь 10, 2011, 06:35 »

Выложи уже свой код полностью
Не думаю, что вы там что-то новое увидите.
Записан
Nimbus
Гость
« Ответ #14 : Октябрь 10, 2011, 07:04 »

Не думаю, что вы там что-то новое увидите.
То-то и оно, что проблема в operator=, потому что ты оставил свой вариант, а не сделал как посоветовал kambala тут
Он должен возвращать TFrac&, а у тебя он void возвращает Подмигивающий
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.229 секунд. Запросов: 22.