Simple question: I have a class simple_fraction and want to overload operator "+". Complilator returns error "operator + local function definition is illegal.
#pragma once
#include <iostream>
class simple_fraction {
private:
int numerator; //числитель
int denominator; //знаменатель
public:
simple_fraction(int numerator, int denominator) {
//определение основных математических операций для простой дроби
double operator+ (double val) { return number + val; } //сложение
}}
int main()
{
simple_fraction fr(2, 3);
double sum = fr + 10; //сумма
}
what is wrong with that?
You have:
simple_fraction(int numerator, int denominator) {
//определение основных математических операций для простой дроби
double operator+ (double val) { return number + val; } //сложение
}}
which makes the operator+ function a local function inside the constructor, which is not allowed. You need to finish the constructor definition before the operator+ function. And you also need to correct the operand inside the operator+
simple_fraction(int numerator, int denominator) : numerator(numerator),
denominator(denominator){}
double operator+ (double val) { return numerator + val; }
PS
That implementation of operator+ does not sound right. Perhaps you meant:
double operator+ (double val) { return 1.0*numerator/denominator + val; }
Related
I am making a program which inputs fractions and puts them in order. I used struct to define a fraction type. I think I am making a type that initializing 2 variables(the numerator and the denominator of the fraction) and initializing the double type variable called value to a / b in this code:
struct fraction {
int a; // numerator
int b; // denominator
double value = a / b; // floating point value of fraction
bool operator > (const fraction &a) {
fraction ans;
return ans.value > a.value;
}
bool operator < (const fraction &a) {
fraction ans;
return ans.value < a.value;
}
};
int main() {
//---------logging-------
fraction ratio = {1,2};
cout << ratio.value;
//-----------------------
// outputs 0
// other things down here that is not included
}
but apparently, that is not the case because I also need to initialize value. I figured out why, but the problem is, how can I make the variable without initializing it at the creation of the fraction? Thanks!
How can I make the variable without initializing it at the creation of the fraction?
One could just write a member function double value() calculating and returning the floating-point value of the fraction, but first there are some issues in the posted code that need to be addressed (and may actually solve OP's problem).
The only in-class member variable initialization shown isn't correct.
double value = a / b; // floating point value of fraction
Beeing both a and b variables of type int, a / b is an integer division, yielding an int result that is only after assigned to a double variable. In OP's example, int(1)/int(2) == int(0).
To produce the expected value, we need to explicitly convert at least one of the terms into a double:
double value = static_cast<double>(a) / b;
Both the comparison operators are wrong.
bool operator > (const fraction &a) {
fraction ans; // This is a LOCAL, UNINITIALIZED varible.
return ans.value > a.value; // The result is meaningless.
}
The following snippet shows a possible implementation where value is calculated and not stored (which isn't necessary a good idea).
#include <iostream>
#include <numeric>
class fraction
{
int numerator_{};
int denominator_{1};
public:
fraction() = default;
fraction(int num, int den)
: numerator_{num}, denominator_{den}
{
if (auto divisor = std::gcd(num, den); divisor != 1)
{
numerator_ /= divisor;
denominator_ /= divisor;
}
}
bool operator > (fraction const& a) const noexcept {
return value() > a.value();
}
bool operator < (fraction const& a) const noexcept {
return value() < a.value();
}
auto numerator() const noexcept {
return numerator_;
}
auto denominator() const noexcept {
return denominator_;
}
double value() const noexcept {
return static_cast<double>(numerator_) / denominator_;
}
};
I think there are two solutions, either you initialize a and b with 0, or you compute a/b each time you need it.
...or you could write an exception like:
int a;
int b;
double val;
try() { val = a/b; }
catch(...){ val = 0; }
I don't think that's good tho because it's always gong to catch.
I just wanted to know can we assign a integer value to a object directly. Here I just want to assign a rational value(22/7) to object x;
#include<iostream>
class rational {
private:
int num = 22, den = 7;
public:
void assign(rational x) {
x = num / den;
}
};
int main() {
rational x;
x.assign(x);
return 0;
}
However doing so gives an error of
no operator "=" matches these operands -- operand types are: rational = int
You can write a converting constructor and an assignment operator:
class rational
{
public:
rational (int val)
{
// initialize as you want
}
rational& operator= (int val)
{
// Assign as you want
return *this
}
}
But it's not at all clear what you're trying to do here. There are other problems:
Your class contains a pair of ints, not a single int
x.assign(x) looks like an attempt to assign x into itself
assign will have no lasting effect on its parameter, since it's not passed by value
I have two classes Integer and Fraction and one abstract class Number. I am suppose to perform addtion operation by overloading + and also I need to check equality of values using overloading of == operator on these classes.
Operations to be performed
1. Add Integer + Integer = Integer
2. Add Fraction + Fraction = Fraction
3. Add Integer + Fraction = Fraction
I have been able to do 1st and 2nd operation but not able to do addition of integer and fraction.
Below is the code snippet:
Number.h
#pragma once
#include <iostream>
template<class T>
class Number
{
virtual const T operator+ (const T &) = 0;
virtual void display(std::ostream &) const = 0;
virtual bool operator==(const T& rhs) const = 0;
};
Integer.h
#pragma once
#include "Number.h"
#include "Fraction.h"
class Integer : public Number<Integer>
{
int intValue;
public:
void display(std::ostream &) const;
int getValue() const;
void setValue(int);
Integer() {}
Integer(int num);
const Integer operator+ (const Integer &);
virtual ~Integer() {}
bool operator==(const Integer&) const;
};
Integer.cpp
#include "Integer.h"
#include "Number.h"
#include <iostream>
#include <string>
// parameterized constructor
Integer::Integer(int num)
{
intValue = num;
}
// return integer value
int Integer::getValue() const
{
return this->intValue;
}
void Integer::setValue(int x)
{
this->intValue = x;
}
// operator "+" overloading
const Integer Integer::operator+(const Integer &secondNumber)
{
Integer temp = this->intValue + secondNumber.intValue;
return temp;
}
// operator "=" overloading
void Integer::display(std::ostream& stream) const
{
stream << this->intValue;
}
// comparasion operator overload
bool Integer::operator==(const Integer& rhs) const
{
return this->intValue == rhs.intValue;
}
Fraction.h
#pragma once
#include "Number.h"
#include "Integer.h"
class Fraction : public Number<Fraction>
{
Integer _numerator;
Integer _denominator;
public:
void display(std::ostream &) const;
Fraction() = delete;
Fraction(const int &, const int &);
const Fraction operator+ (const Fraction &);
int gcdCalculate(int val1, int val2);
int lcmCalculate(const int val1, const int val2);
virtual ~Fraction() {}
bool operator==(const Fraction& rhs) const;
};
Fraction.cpp
#include "Fraction.h"
#include <iostream>
// parameterised constructor
Fraction::Fraction(const int & num, const int & den)
{
_numerator.setValue(num);
_denominator.setValue(den);
}
// display the fraction value
void Fraction::display(std::ostream & stream) const
{
if (this->_denominator == 0)
std::cout << "Undefined: " << this->_numerator.getValue() << "/" << this->_denominator.getValue() << " (Divide By Zero Exception)";
else
stream << this->_numerator.getValue() << "/" << this->_denominator.getValue();
}
// "+" operator overloading
const Fraction Fraction::operator+(const Fraction &numberTwo)
{
int lcm = lcmCalculate(this->_denominator.getValue(), numberTwo._denominator.getValue());
int multiplier1 = 0;
if (this->_denominator.getValue())
multiplier1 = lcm / this->_denominator.getValue();
int multiplier2 = 0;
if (numberTwo._denominator.getValue())
multiplier2 = lcm / numberTwo._denominator.getValue();
return Fraction((this->_numerator.getValue() * multiplier1) + (numberTwo._numerator.getValue() * multiplier2), lcm);
}
// LCM Calculation
int Fraction::lcmCalculate(const int val1, const int val2)
{
int temp = gcdCalculate(val1, val2);
return temp ? (val1 / temp * val2) : 0;
}
// GCD Calculation
int Fraction::gcdCalculate(int val1, int val2)
{
for (;;)
{
if (val1 == 0) return val2;
val2 %= val1;
if (val2 == 0) return val1;
val1 %= val2;
}
}
// comparision operator overload
bool Fraction::operator==(const Fraction& rhs) const
{
Integer numCheck = this->_numerator;
Integer denCheck = this->_denominator;
if (rhs._numerator.getValue())
numCheck.setValue(numCheck.getValue() / rhs._numerator.getValue());
if (rhs._numerator.getValue())
denCheck.setValue(denCheck.getValue() / rhs._denominator.getValue());
if (numCheck == denCheck) {
return true;
}
return false;
}
QUESTION:
I am confused as how to add Integer + Fraction class.
Do I need to create another class which will inherit from Number class.
How to overload oprator+ present in Number Class.
Suppose I try to add Integer + Fraction = Fraction in the Integer class itself then I will have something like
Example
class Integer : public Number<Integer>
{
const Fraction operator+(const Fraction &);
}
const Fraction Integer::operator+(const Fraction &numberTwo)
{
^^ I will get error here
// Addition opeartion
}
Please help me.
For your first question, the solution is to not use member function overloads, but to create a non-member function overload, e.g.
Fraction operator+(Integer const& integer, Fraction const& fraction)
{
// Logic to add the integer and fraction here
// Perhaps something like...
Fraction f(integer.getValue(), 1); // Create fraction
return f + fraction;
}
The code above uses the Fraction::operator+ function to add the integer.
While you can add an Integer+Fraction operator to your current design like Joachim suggested, that's going to result in some code duplication or at least some unnecessary boilerplate.
I suggest an alternative design instead: Make Integer convertible to Fraction. After all, any integer can be represented by the Fraction type, right?
You can make Integer convertible in two ways: By adding a conversion function to Integer, or by adding a converting constructor to Fraction.
I recommend choosing the converting constructor approach, because Fraction already depends on Integer type and so the cast operator would result in a circular dependency, just like your member operator attempt. I'll leave the implementation as an exercise.
This design requires that the addition operator is implemented as a non-member overload:
Fraction operator+(Fraction const& left, Fraction const& right)
With the converting constructor, this function can handle any combination of (F + F), (F + I) and (I + F).
I'm currently trying to create a member function that adds an object, Fraction f, to the current object and returns a reference to the current object. my second function is a non-friend helper operator that adds two Fraction objects and returns a copy of the result. I'm not exactly sure how to go about doing this and was looking for some advice. Pretty much the object(s) are just fractions that have been simplified earlier within a previous member function. Essentially all I'm doing is adding simplified fractions. Here's what I have so far:
//header.h
class Fraction {
int num;
int den;
public:
Fraction();
Fraction(int, int);
Fraction& operator+=(const Fraction& f);
friend bool operator==(const Fraction&, const Fraction&);
void simplify();
void display() const;
};
Fraction operator+(const Fraction&, const Fraction&);
and the module:
//module.cpp
#include "Fraction.h"
#include <iostream>
Fraction::Fraction() {
num = 0;
den = 0;
}
Fraction::Fraction(int n, int d) {
num = n;
den = d;
simplify();
}
void Fraction::simplify() {
int temp = den;
int a = num;
int b = den;
int gcd;
if (b > a) {
b = num;
a = den;
}
while (temp != 0) {
temp = a % b;
a = b;
b = temp;
}
gcd = a;
num /= gcd;
den /= gcd;
}
void Fraction::display() const {
std::cout << num << "/" << den << std::endl;
}
//member function in question
Fraction& Fraction::operator+=(const Fraction& f) {
num += f.num;
den += f.den;
return *this;
}
//member function in question
Fraction operator+(const Fraction&, const Fraction&) {
}
EDIT: guess I wasn't as clear previously and that's partly due to the helper function not being revealed. I tried defining the member function and the above code is currently what I have at the moment. I'm not sure if it's logically sound or not as I am still going through the other definitions. the non friend helper operator is the one I am stumped on and do not know what to do. If I can get some help on whether the definition I have for the += member operator is correct and some advice on how to approach the non friend helper operator, that would be great. sorry for any confusion.
since you have the fractions simplified, all you have to do is to use this equation:
and the code will be as follows:
Fraction& Fraction::operator+=(const Fraction& f) {
num = num * f.den + f.num * den;
den *= f.den;
simplify();
return * this;
}
EDIT:
take a look at this question for more about operator overloading
I'm doing a Little rational class for my Project and I overload all aritmethic operators. Well, when I try to overload operator= I have a Little and now I don't know if is my problem (i don't know how it Works) or problem of my wroten code (i wrote it bad) here's the code:
class rational{
public:
double& operator=(double& d){
d= this->num/this->den;
return d;
}
double& operator=(rational& r){
double d= r.num/r.den;
return d;
}
double& operator=(){
double d= this->num/this->den;
return d;
}
}
Ok, what's wrong? what's right? (i think that all is wrong haha)
My goal is do that:
int main(){
rational r(4, 5);
double d= r;
}
Can I do it? if yes, how?
You don't want an assignment operator for this purpose - you should instead overload a conversion operator; e.g.
class rational {
private:
int num;
int den;
public:
// ...
operator double() { return double(num) / double(den); }
};
This will allow
rational r(4, 5);
double d = double(r); // d = 0.8
The assignment operators should be used for changing the state of an existing object, if that's something you want to allow. You probably would not want to allow assignment of a double to a rational there is no unambiguous meaning for such an operation. However, you might want to provide helpers for assigning an int, say, in addition to the usual one for assigning another rational:
rational &operator=(const rational &rhs)
{
num = rhs.num;
den = rhs.den;
return *this;
}
rational &operator=(int rhs)
{
num = rhs;
den = 1;
return *this;
}
Here I think a user-defined conversion operator would be more appropriate.
class rational {
public:
rational( int iNum, int iDen ) : num( iNum ), den( iDen ) {}
// ...
operator double() { return (double)num / (double)den; }
private:
int num;
int den;
};
int main()
{
rational r( 1, 2 );
double n = r;
std::cout << r << std::endl; // output 0.5
return 0;
}
Here is a little live example to illustrate this : http://ideone.com/I0Oj66
About the copy assignment operator= :
A copy assignment operator of class T is a non-template non-static member function with the name operator= that takes exactly one parameter of type T.
The operator= is used to change an existing object.
You can use it for example to copy the state of another object :
rational &operator=( const rational &rhs )
{
num = rhs.num;
den = rhs.den;
return *this;
}