Overloading operator [ ] to use as a setter for Polynomial class - c++

I have created a Polynomial class but I want to overload indexing operator to be used as a setter, for example, myPolyObject[0] = 2.5 but It's giving me an error when trying to overload it.
class Polynomial
{
public:
Polynomial();
Polynomial(Polynomial&);
Polynomial(double* coefficient, int size);
~Polynomial() { delete [] polynomial ; }
double operator [] (int exponent) const;
friend ostream& operator << ( ostream& , const Polynomial&);
Polynomial& operator = (const Polynomial&);
double evaluate(double x) const;
int getSize() const;
double operator [] (int exponent, double coefficient);
Polynomial& operator + ( Polynomial& );
Polynomial& operator + ( double x );
Polynomial& operator - (Polynomial&);
Polynomial& operator - (double x);
Polynomial& operator * (Polynomial&);
Polynomial& operator * (double x);
private:
double* polynomial;
};
In this code, I want double operator [] (int exponent, double coefficient) to take an index (exponent) for the array and set the value at that index to the double coefficient value.

Your question seems to want two different things, the first bit is answered in the comments, return a reference. Here is an example for completeness,
struct example
{
double value_[10];
double& operator [] (int index) {
return value_[index];
}
};
int main() {
example e;
e[0] = 2.2;
std::cout << e.value_[0] << std::endl;
}
Demo
You then say..
I want double operator [] (int exponent, double coefficient) to take an index (exponent) for the array and set the value at that index to the double coefficient value.
You can't have operator[] with multiple arguments. A couple of options are;
accept a std::pair<int,double>, which has pretty clean syntax. for example..
struct example
{
double operator [] (const std::pair<int,double>& values) {
return 2.0;
}
};
int main() {
example e;
e[{1,2.2}];
//or
e[std::make_pair(1,2.2)];
}
Demo
Or if you really want the comma, you could make your own type for the exponent and overload the comma operator.
struct exponent
{
int exp_;
double coeff_;
exponent(int value) : exp_(value),coeff_(0){}
operator std::pair<int,double>() {
return std::make_pair(exp_,coeff_);
}
exponent& operator,(double coeff) {
coeff_ = coeff;
return *this;
}
};
struct example
{
double operator [] (const std::pair<int,double>& values) {
return 2.0;
}
};
int main() {
example e;
e[exponent(1), 3.3];
}
Demo
I'd personally go with something like the first option, or overload operator() instead.

Related

Why can't I use the right overloaded function Poly_Mult

I'm trying to write a class handling multiplication, division, etc of polynomials.
In my header file, I have my class definition, in which I have those public functions :
void Poly_Mult(const Polynomial& Poly);
void Poly_Divide(const Polynomial& Poly);
and also two friend functions :
friend Polynomial Poly_Mult(const Polynomial& Poly1, const Polynomial& Poly2);
friend Polynomial Poly_Divide(const Polynomial& Poly1, const Polynomial& Poly2);
I have defined both Poly_Mult functions with no problem and I try to use them to define the Poly_Divide ones.
For the friend function, I have no problem. However, in the member function :
bool Polynomial::Poly_Divide(const Polynomial& Poly)
{
if (Poly.m_Degree == 0)
return false;
Polynomial result;
result.m_Degree = this->m_Degree - Poly.m_Degree;
result.m_Variable = this->m_Variable;
Polynomial reduced(*this);
double GuidingFactor = Poly.m_Terms[Poly.size() - 1].Factor();
while (reduced.m_Degree >= Poly.m_Degree)
{
int exp = reduced.m_Degree - Poly.m_Degree;
double termFactor = reduced.m_Terms[reduced.size() - 1].Factor() / GuidingFactor;
//I get an error on this next line. The compiler doesn't seem to find to right overloaded function for Poly_Mult
reduced.Poly_Subtract(Poly_Mult(Poly, Polynomial(termFactor, Poly.m_Variable, exp)));
result.m_Terms.push_back(VarPower(termFactor, exp));
reduced.Simplify();
}
result.Simplify();
*this = result;
if(reduced.size() == 1 && reduced.m_Terms[0].Factor() == 0 && reduced.m_Terms[0].Exponent() == 0)
return true;
else
return false;
}
The code is functionally the same in the friend function and it works perfectly as intended, no errors.
instead of the whole detailed function since the friend function works fine, but again, the compiler doesn't seem to find to right overloaded function.
I really don't see the problem here, as the functions have different parameters so I see no ambiguity.
By simplifying the code, I get the same problem with this :
in my header file, I have my class definition :
class Polynomial
{
private:
int m_Degree;
public:
Polynomial(int degree)
: m_Degree(degree) {};
Polynomial(const Polynomial& Poly)
: m_Degree(Poly.m_Degree) {};
Polynomial& operator=(const Polynomial& Poly)
{
m_Degree = Poly.m_Degree;
}
void Multiply(const int& number);
friend Polynomial Multiply(const Polynomial& Object, const int& number);
void Divide(const int& number);
friend Polynomial Divide(const Polynomial& Object, const int& number);
};
Then, in my cpp file, I have the implementation of the functions :
#include "Polynomial.h"
void Polynomial::Multiply(const int& number)
{
m_Degree *= number;
}
Polynomial Multiply(const Polynomial& Object, const int& number)
{
return Polynomial(Object.m_Degree * number);
}
void Polynomial::Divide(const int& number)
{
Polynomial copy = *this;
Polynomial result = Multiply(copy, (1./number)); //This is where the problem is. The compiler doesn't find the right overloaded function
*this = result;
}
Polynomial Divide(const Polynomial& Object, const int& number)
{
Polynomial result = Multiply(Object, (1. / number));
return result;
}
I get those errors :
error C2660: 'Polynomial::Multiply': function does not take 2 arguments
no suitable constructor exists to convert from "void" to "Polynomial"

Operator Overloading: How to add and compare data of two class "Integer" and "Fraction"

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).

operator= in c++ (11) working direction

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;
}

How to Overload operator+ with Polynomial Class and What Types to Return

I'm having trouble overloading the + operator, and I can't figure out what the cause is. The + operator returns a Polynomial (called C) but it returns it by value, where as the assignment operator is expecting a Polynomial object as a parameter passed by reference. To make C=A+B work, do I need to have a second assignment operator function that takes a Polynomial passed by value as an argument? Thanks!
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
void line(int lines);
class Polynomial
{
private:
int degree;
int* coeffs;
public:
//constructors
Polynomial() {degree=0;coeffs=new int[1];}
Polynomial(int deg) {degree=deg;coeffs=new int[deg+1];}
Polynomial(const Polynomial& A);
//mutators
void GetCoeffs(istream& in);
void EditCoeff(int deg);
void ResetCoeffs();
int Coeff(int deg);
void Randomize(int max);
//accessors
void Show(ostream& out);
int Degree() {return degree;}
//operators
friend Polynomial operator+(Polynomial& A, Polynomial& B);
void operator =(Polynomial A);
};
int main()
{
Polynomial A(5);
Polynomial B(5);
A.Randomize(5);
B.Randomize(5);
A.Show(cout);
line(2);
B.Show(cout);
line(2);
Polynomial C(5);
C=A+B;
C.Show(cout);
return 0;
}
void Polynomial::Randomize(int max)
{
for (int i=degree; i>=0; i--)
{
coeffs[i]=rand()%(max+1) + 1;
if ((rand()%(101) + 1)%2 == 0)
coeffs[i]*=-1;
}
}
void Polynomial::operator =(Polynomial A)
{
if (degree==A.degree)
{
for (int i=degree; i>=0; i--)
{
coeffs[i]=A.coeffs[i];
}
}
}
Polynomial Polynomial::operator+(Polynomial& A, Polynomial& B)
{
Polynomial C;
if (A.degree>=B.degree)
{
C=A;
for (int i=B.degree; i>=0; i--)
{
C.coeffs[i]=A.coeffs[i]+B.coeffs[i];
}
C.Show(cout);
return C;
}
else
{
C=B;
for (int i=A.degree; i>=0; i--)
{
C.coeffs[i]=A.coeffs[i]+B.coeffs[i];
}
C.Show(cout);
return C;
}
}
int Polynomial::Coeff(int deg)
{
return coeffs[deg];
}
void line(int lines)
{
for (int i=0; i<lines; i++)
cout << endl;
}
void Polynomial::GetCoeffs(istream& in)
{
for (int i=degree; i>=0; i--)
{
in >> coeffs[i];
}
in.ignore();
}
void Polynomial::Show(ostream& out)
{
for (int i=degree; i>=0; i--)
{
if (coeffs[i]>=0)
{
if (i!=degree)
out << " + ";
out << coeffs[i];
}
else
{
if (coeffs[i]<0)
out << " - ";
out << 0-coeffs[i];
}
if (i>1)
out << "x^" << i;
else if (i==1)
out << "x";
}
}
Polynomial::Polynomial(const Polynomial& A)
{
coeffs=new int[A.degree+1];
degree=A.degree;
for (int i=A.degree; i>=0; i--)
{
coeffs[i]=A.coeffs[i];
}
}
This issue here is you have mixed up the global(Outside class definitions) operator+ and the member class definition of operator+.
(static) Polynomial operator+(Polynomial& A, Polynomial& B); This operator is used globally, so outside of a class.
Inside the class you need to use the following signature.
Polynomial& operator+(const Polynomial& other);
Here is an example.
Polynomial p;
Polynomial q;
p = p + q;
The code for this if the operator is define in the class is:
p = p.operator+(q); //only needs one parameter.
The code for this if the operator is define globally is:
p = ::operator+(p, q); //needs both parameter
NOTE:
To use it as a non member function remove Polynomial operator+(Polynomial& A, Polynomial& B); from your definition Polynomial Polynomial::operator+(Polynomial& A, Polynomial& B){/**/} should be move above the main function and it now becomes:
static Polynomial operator+(Polynomial& A, Polynomial& B){/**/}
Normally you would overload operator+ in one of two ways:
Polynomial operator+(const Polynomial &other) const;
or as a non-member function,
Polynomial operator+(Polynomial a, const Polynomial &b);
You don't normally need the friend qualifier for the latter since the implementation will likely be in terms of another overloaded operator already defined in the class:
Polynomial operator+=(const Polynomial &other);
Then your non-member implementation will just be:
Polynomial operator+(Polynomial a, const Polynomial &b)
{
a+=b;
return a;
}
If you insist on using the function as defined in your code, then you will need to make it a
friend if you need access to private members:
Polynomial operator+(Polynomial &a, Polynomial &b)
{
Polynomial p;
// add them as needed
return p;
}

error C2593: 'operator +' is ambiguous

If I have the following files, I get this error (c2593 in VC9).
If I un-comment the prototype in main.cpp, the error disappears. I need to maintain the same functionality while keeping the class out of main.cpp. How can I do that?
Thanks.
main.cpp:
#include "number.h"
//const Number operator + (const Number & lhs, const Number & rhs);
int main(void)
{
Number n1(2); // n1 = 2
Number n2(9,3); // n2 = 3
Number n3 = n1+n2; // n3 = 5
}
number.h:
struct Number
{
int num;
Number(int n=0,int d=1) {num = n/d;}
operator int() {return num;}
operator double() {return num*1.0;}
};
number.cpp:
#include "Number.h"
const Number operator + (const Number & lhs, const Number & rhs)
{
Number tmp;
tmp.num = lhs.num + rhs.num;
return tmp;
}
Try putting the prototype in the Number header file:
number.h:
struct Number
{
int num;
Number(int n=0,int d=1) {num = n/d;}
operator int() {return num;}
operator double() {return num*1.0;}
};
const Number operator + (const Number & lhs, const Number & rhs);
number.cpp:
#include "Number.h"
const Number operator + (const Number & lhs, const Number & rhs)
{
Number tmp;
tmp.num = lhs.num + rhs.num;
return tmp;
}
main.cpp:
#include "number.h"
int main(void)
{
Number n1(2); // n1 = 2
Number n2(9,3); // n2 = 3
Number n3 = n1+n2; // n3 = 5
}
You never declare operator + in number.h, you only define it in number.cpp - therefore, when you include number.h in main.cpp, it doesn't know where to go to find operator +.
You must put the declaration of operator + in number.h, outside of the class, then define it in number.cpp
That commented line should go in number.h
EDIT: in number.h but as a free function.
One other thing to note with your code before you go back to us with a very similar question: Better remove the operator int and operator double functions. They will cause you major headache. Let's make a few examples:
Number a, b;
1 + b;
// ambiguous: operator+(int, int) or
// operator+(Number, Number) ?
// did you intend to use those for this case?
float x = a;
// ambiguous: from int -> float or
// double -> float ?
In the original situation you had, your addition was ambiguous, because there were operator+(double, double) and operator+(int, int) builtin operators considered and they were equally well. Others solved that problem. But before you start and run into these other problems, better remove the conversion functions and insert explicit functions like asDouble or something similar.
Apart from other's answers to declare operator+ in the header file, I suggest you to have operator+= in your struct as well.
struct Number
{
// your other declarations.
Number& operator+=(const Number& other)
{
this->num += other.num;
return *this;
}
};
const Number operator+(const Number& lhs, const Number& rhs)
{
Number ret(lhs);
ret += rhs;
return ret;
}
This way it is efficient to call x += y; instead of x = x + y;
Personally I like it better to declare the operators inside the class:
struct Number
{
int num;
Number(int n=0,int d=1) {num = n/d;}
operator int() {return num;}
operator double() {return num*1.0;}
Number operator+(const Number &arg) const;
};
and then:
Number Number::operator+(const Number &arg)
{
...
}