Overloading operator+ in class - c++

Let's say I have a class Number
class Number
{
public:
int numb;
Number (int g)
{
numb = g;
}
int operator+(int h)
{
return this->numb+h;
}
};
And when I try to use my overloaded operator
cout << 3 + s; // doesn't work
cout << s + 3;
I understand why it doesn't work, but I don't know how to make it work for 3 + s
Of course, I can write operator+ with 2 arguments outside the class, but I want to have my operator overloaded in the class.
I've googled it, but didn't find any solution.

Easiest way to go: write another overload outside of your class
class Number
{
public:
int numb;
Number (int g)
{
numb = g;
}
int operator+(int h)
{
return this->numb+h;
}
};
int operator+(int h, Number& n)
{
return n.numb+h;
}
int main()
{
int s = 42;
std::cout << 3 + s;
std::cout << s + 3;
}
Live Example
This also works if your data is private (but make sure the outside function has access to those members)
class Number
{
int numb;
public:
Number (int g)
{
numb = g;
}
int operator+(int h)
{
return this->numb+h;
}
friend int operator+(int, Number&);
};
int operator+(int h, Number& n)
{
return n.numb+h;
}

Of course, I can write operator+ with 2 arguments outside the class, but I want to have my operator overloaded in the class.
This is like saying "Of course I could hammer in my nail with a hammer, but I want to use a screwdriver..."
Some other solutions suggested using both a member and a non-member, but that is redundant: if you add the non-member then you no longer need the member!
The proper way to overload operator+ is to use the non-member:
Number operator+(Number a, Number b)
{
return a.numb + b.numb;
}
Another way to write this is to use operator+= as a helper (then your class will support += too):
Number operator+(Number a, Number b)
{
return a += b;
}
with member function:
Number &operator+=(Number b)
{
numb += b.numb;
return *this;
}
You could either make operator+ return Number or int, your choice.

Just write an operator outside the class that calls the one in your class!
template<typename T> T operator+(T a, Number& n)
{
return n+a;
}

Related

Why does my operator overloading handle left versus right objects?

I had a question on operator overloading. Below is my the example code. If you can read through it and my question is below.
//class definition
class example
{
private:
int a ; // Defined in FeetInches.cpp
public:
void seta(int f)
{
a = f;
}
example operator + (const example &); // Overloaded +
int geta()
{
return a;
}
};
example example::operator + (const example &right)
{
example temp;
temp.a = a + right.a;
return temp;
}
//main
#include "header" //this is the class definition above
#include <iostream>
using namespace std;
int main()
{
example r;
r.seta(1);
example s;
s.seta(1);
example t;
t = r + s;
t = r + 1; //if included it won't compile
t = 1 + r; //if included it won't compile
int x = t.geta();
cout << x;
cin.get();
return 0;
}
I understand that when you attempt to add to objects together using operator overloading they should be the same.
Here is the question:
I recently saw when the object was on one side of the operator it compiled but when it was on the other it didn't. Such as:
t = r + 1; it compiled.
t = 1 + r; it didn't.
(Also I know in my example it doesn't work either way but was just easier to frame question with code.)
How does operator overloading compile when the object is on one side of the operator but not compile when it is on the other.
Thanks
If you rewrite the offending statement verbosely, it looks like:
t.operator=(1.operator+(r));
Which doesn't make a lot of sense and confuses the compiler.
Being confused, it can either convert the number 1 to an instance of example or convert the variable r to an integer. Unfortunately, you don't supply enough information in your class to do either.
If you provide a constructor for your class that takes an integer, things may come out less confusing:
class example
{
public:
example(int new_value) : a(new_value)
{ ; }
};
Now you have provided the compiler with a method convert integers into examples.
Another alternative is to provide a casting or conversion operator:
class example
{
public:
int operator int (const example& e)
{
return e.a;
}
};
There are other alternatives, such as creating an addition method that takes an integer.
Edit 1:
If you are designing a units class beware of constants. You have no idea what unit the constant is in, such as feet or inches. The compiler won't be able to help, since numerical constants don't have units associated with them.
It's really simple, when you overloading operator you can do it in two ways:
First is like you do it. You inserted overloaded operator for your class in it. This way the left argument must be the object of this class. Why? Because when you call this operator you can do it as call of every function in your class. You can't do it other way, because you can't call this function by other type.
Second, you made overloaded operator as friend to your class.
In your class you put this line:
friend example& operator + (const example &left, const example &right);
And after your class definition you put this:
example& operator + (const example &left, const example &right){...}
So if you want to add integer or other types you must just modify your operator to add it like this:
example& operator + (const example &left, const int right){...}
or this:
example& operator + (const int left, const example &right){...}
Choose one or both if you want to add int from left or rigth side of the opearator.
t = r + 1; means t = r.operator+(1); if r defines a matching operator+() method, otherwise it means t = operator+(r, 1); instead. It does not compile because you did not define any + operator that takes an example on the left and an int on the right, eg:
// as a class method:
class example
{
...
public:
...
example operator + (int right) const;
};
example example::operator + (int right) const
{
example temp;
temp.seta(a + right);
return temp;
}
Or:
// as a global operator:
class example
{
...
public:
...
friend example operator + (const example& left, int right);
};
example operator + (const example& left, int right)
{
example temp;
temp.seta(left.a + right);
return temp;
}
If you had defined a contructor that takes an int as input, the compiler could have created a temp example when you pass an int value to the example::operator+(const example&) method, eg:
class example
{
...
public:
example (int f);
...
example operator + (const example& right);
};
example::example::(int f)
: a(f)
{
}
example example::operator + (const example& right)
{
example temp;
temp.a = a + right.a;
return temp;
}
Likewise, t = 1 + r; means t = operator+(1, r); (since 1 is not a class type). It does not compile because you did not define a global + operator that takes an int on the left and an example on the right:
class example
{
...
public:
...
friend example operator + (int left, const example& right);
};
example operator + (int left, const example& right)
{
example temp;
temp.a = left + right.a;
return temp;
}

C++ overloaded operator with reverse order of associativity

It was very hard to come up with a title... (I'm not a native English speaker.)
struct A
{
int value;
A operator+(int i) const
{
A a;
a.value=value+i;
return a;
};
};
int main(){
A a;
a.value=2;
a=a+2;
return 0;
}
This code compiles/works as expected, but when I change a=a+2 to a=2+a, it won't compile anymore.
GCC gives me this error:
no match for ”operator+” in ”2 + a”
Is there any way to somehow make 2+a work just like a+2?
You need a free function, defined after the class
struct A
{
// ...
};
A operator+(int i, const A& a)
{
return a+i; // assuming commutativity
};
also, you might consider defining A& operator+=(int i); in A an implement both versions of operator+ as free functions. You might also be interested in Boost.Operators or other helpers to simplify A, see my profile for two options.
Sure, define the inverse operator outside the class:
struct A
{
int value;
A operator+(int i) const
{
A a;
a.value=value+i;
return a;
};
};
//marked inline to prevent a multiple definition
inline A operator+(int i, const A& a)
{
return a + i;
}
The other answers here work fine. However, another option you have is to create a constructor for a single int like this:
struct A
{
int value;
A(int i) {
value = i;
}
};
This allows integers to get implicitly converted, and allows you to only overload operators for your struct instead:
A operator+(const A& other) const
{
// All you need to do is work with an A, and associativity works fine
};
Of course, this does allow all integers to get implicitly converted to As, which may or may not be desirable.

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

OOP C++ first compiler error

Please help this newbie, here's my code:
#include <iostream>
using namespace std;
class Complex {
private:
float r, i;
public:
Complex(float rr, float ii) : r(rr), i (ii) {}
float GiveRe () { return r; }
float GiveIm () { return i; }
void Setit (float rr, float ii) {
r = rr;
i = ii;
}
};
Complex a(10, 20);
Complex sumit (Complex &ref) {
static Complex sum (0, 0);
sum.Setit(sum.GiveRe() + ref.GiveRe(), sum.GiveIm() + ref.GiveIm());
return sum;
}
int main () {
Complex sumvalue = sumit (a);
cout << sumvalue << endl;
return 0;
}
error: no match for 'operator<<' in 'std::cout << sumvalue'.
The program should output the sum of a complex number.
cout can't tell what you want to output, you need to specify the operator<< in the class or make it possible to implicitly convert your class to a compatible type.
http://www.cplusplus.com/reference/iostream/ostream/operator%3C%3C/
Rudolf Mühlbauer's code as implemented in your class:
Add this somewhere within the class header:
friend ostream& operator<<(ostream& out, const Complex& compl);
and this below the header:
ostream& operator<<(ostream& out, const Complex& compl)
{
return out << compl.r << "/" << compl.i;
}
Implementation should be changed to suit your exact needs.
Complex doesn't have an operator <<
ostream& Complex::operator << ( ostream& os )
{
// use os << field/method here to out put
return os;
}
Also if complex can be displayed to console in different ways, then you should think of using methods to display instead of cout <<
void Complex::DisplayToConsole()
{
std::cout << r << " " << i << '\n';
}
You have to overload the "<<" operator for Complex type.
#include <iostream>
using namespace std;
class Complex {
private:
float r, i;
public:
Complex(float rr, float ii) : r(rr), i (ii) {}
float GiveRe () { return r; }
float GiveIm () { return i; }
void Setit (float rr, float ii) {
r = rr;
i = ii;
}
};
ostream& operator<<(ostream& os, Complex& c)
{
float i;
os<<c.GiveRe();
if(c.GiveIm() < 0){
os<<"-j"<<c.GiveIm()*(-1);
}else{
os<<"+j"<<c.GiveIm();
}
return os;
}
Complex a(10, 20);
Complex sumit (Complex &ref) {
static Complex sum (0, 0);
sum.Setit(sum.GiveRe() + ref.GiveRe(), sum.GiveIm() + ref.GiveIm());
return sum;
}
int main () {
Complex sumvalue = sumit (a);
cout << sumvalue << endl;
return 0;
}
A complete minimal example:
#include <iostream>
using namespace std;
class C {
public:
int r, l;
// if the operator needs access to private fields:
friend ostream& operator<< (ostream&, const C&);
};
ostream& operator << (ostream& stream, const C& c) {
stream << c.r << "--" << c.l;
return stream;
}
int main() {
C c;
c.l = 1;
c.r = 2;
cout << c << endl;
}
C++ allows you to define operators. The STL uses the << operator for output, and the whole istream/ostream class hierarchy uses this operator to input/output.
Operators are implemented as functions, but always follow a very specific syntax. As in the example, ostream& operator << (ostream&, const MYTYPEHERE&) is the way to define ostream << operators.
When C++ encounters a statement, it has to deduce the types of all operands, and find (quite magically, indeed) a solution to the question: given my operands and operators, can i find a typing such that the statement gets valid?
These ofstream operators are defined for all basic types somewhere in <iostream>, so if you write cout << 10, the compiler finds an operator ostream& operator<< (ostream&, int).
If you want to be able to use userdefined types in this game, you have to define the operators. otherwise, a statement cout << sometype will not be valid. This is also the reason for the harsh compiler errors sometimes found in C++: "Well, i have some operators << defined, but none is compatible with your type!".
Because sometimes it is not favourable to implement operators for your types (if you only output them once, e.g.), i suggested to write:
cout << sum.re << "--" << sum.im << endl; // or similar
This way, you write less code, and you are flexible in the output format. Who knows if you want you complex number formatted differently next time? But this is another discussion.
Why complicating that much? Because C++ can be awfully complicated. It it very powerfull, but crammed with special syntax and exceptions to those. In the end, the difference to C lies exactly here: C++ does a much better job with type inference (needed for templates), often resulting in WTF?
On how to implement it in your code, i think the other answers provide nice solutions!
sumit(a) returns an object of type Complex, which cout was not defined to handle.

Binary Operator Overloading C++

I'm trying to overload the following operators to sort a string array using a Quick Sort or possibly Merge Sort algorithm. I'm have all my functions in a single class but I'm getting a "too many parameters for this operator function" error. Indeed, it will only accept one parameter. I looked up the problem and in a forum someone said that you can only use one parameter when overloading an operator inside a class. This doesn't make much sense to me. I'm trying to compare strings so I need the two parameters for the overloading. Am I supposed to overload the operators outside the class, and how would this work?
Here's my code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class Preprocessing
{
public:
void readFile(string list[], int size);
void quickSort(int list[], int lowerBound, int upperBound);
void swapItem(int &a, int &b);
//These are the overloading functions I'm trying to implement
bool operator<=(string a, string b);
bool operator<(string a, string b);
bool operator>(string a, string b);
};
void Preprocessing::readFile(string list[], int size)
{
ifstream myFile;
myFile.open("words.txt");
for (int i = 0; i < size; i++)
{
myFile >> list[i];
}
myFile.close();
}
void Preprocessing::quickSort(int list[], int lowerBound, int upperBound)
{
int i, j, pivot;
i = lowerBound;
j = upperBound;
pivot = list[(i + j) / 2];
while (i <= j)
{
while(list[i] < pivot)
{
i = i + 1;
}
while (list[j] > pivot)
{
j = j - 1;
}
if (i <= j)
{
swapItem(list[i], list[j]);
i = i + 1;
j = j - 1;
}//end if
}//end outter while
if (lowerBound < j)
{
quickSort(list, lowerBound, j);
}
if (i < upperBound)
{
quickSort(list, i, upperBound);
}//end recursive if
}//end function
void Preprocessing::swapItem(int &a, int &b){
int tmp;
tmp = a;
a = b;
b = tmp;
}
bool Preprocessing::operator<=(string a, string b)
{
if (a.compare(b) > 0)
return false;
else if (a.compare(b) == 0)
return true;
else
return true;
}
bool Preprocessing::operator<(string a, string b)
{
if (a.compare(b) > 0)
return false;
else if (a.compare(b) == 0)
return true;
else
return true;
}
bool Preprocessing::operator>(string a, string b)
{
if (a.compare(b) > 0)
return false;
else if (a.compare(b) == 0)
return true;
else
return true;
}
The signatures for the operators are incorrect:
bool operator<=(string a, string b);
bool operator<(string a, string b);
bool operator>(string a, string b);
When you overload an operator - and you implement it as a member function, it should only accept one argument (the other thing to compare to)
If non-member function (i.e. friend), then you can provide two arguments, however it cannot match an exiting operator (there is one already defined for std::string), and typically should accept your class as lhs and rhs for testing.
An operator inside a class, whatever it is, has the special meaning of applying that operator to an instance of that class and optionally to parameters.
In your example the operator<= is supposed to compare an instance of the Preprocessing class with a string.
class Preprocessing
{
public:
bool operator<=(string a);
private:
string aStringField;
}
Typically you use this inside the operator method body to compare the instance with the parameter:
bool Preprocessing::operator<=(string a)
{
return this->aStringField.length() <= a.length();
}
And you call it with:
Preprocessing p;
if ( p <= "a string" )
// ...
Which is equivalent to:
Preprocessing p;
if ( p.operator<=("a string") )
// ...
If you want to provide an operator that doesn't need the "point syntax" to be called, then you're looking for friend operators that exist outside your class.
class Preprocessing
{
public:
friend ostream& operator<<(ostream&, const Preprocessing&);
private:
string aStringField;
}
It only takes one argument because the left hand side is passed as the this pointer.
To overload an operator, the operator needs to be a method of the lefthand operand. C++ chooses functions (and operators) based on the types of the arguments (operands). Within a class, the lefthand operand is an instance of the class, available as the this pointer, so only the righthand operand may be specified as an argument to the operator.
In your example, you could do this:
class Preprocessing {
public:
bool operator<=(string b);
};
which would define a <= operator for comparing Preprocessing objects to strings. If you need to overload string comparison operators, you need to modify the std::string class, which is beyond my knowledge.