C++ overloading `-` operator (as `* -1`) - c++

Say I have an int, like this:
int foo = 5;
I could then do this:
int bar = -foo; // -5
I want to be able to do the same with my class, so how do I overload the - operator, used as * -1? Do I have to overload the * operator to do so?

class MyClass
{
friend MyClass operator-(const MyClass& x);
};
or
class MyClass
{
MyClass operator-() const;
};
Take your pick (although I would go for the first).

Related

use operator between three object

I want to use the - operator between 3 objects but I can't.
Error:'A A::operator-(A, A)' must take either zero or one argument
I do not know what to do.
class A
{
private:
float x,y;
public:
void set(int a,int b){
x=a;
y=b;
}
void show(){
cout<<"x = "<<x<<" y = "<<y<<endl;
}
A() {}
A operator -(A &obj1){
A temp;
temp.x= x - obj1.x;
temp.y= y - obj1.y;
return temp;
}
};
A A::operator -(A obj1, A obj2);
int main() {
A ob1,ob2,ob,result;
ob1.set(5,7);
ob2.set(10,7);
ob.set(4,9);
result = ob - ob2 -ob1;
ob.show();
return 0;
}
There are 2 ways to overload an operator for a class:
class Foo {
public:
Foo operator -(const Foo &rhs) const { ... }
Foo operator +(const Foo &rhs) const;
};
Foo Foo::operator +(const Foo &rhs) const {
...
}
or
class Foo { ... };
Foo operator -(const Foo &lhs, const Foo &rhs) { ... }
The first is overloading the operator inside the class as a function of the class. It has this as the left hand side of the operator so you can only specify the right hand side as argument.
The second overloads the general operator outside of the class. It has 2 arguments, the left hand side and the right hand side. It is not a member of the class and won't have access to the private parts, unless you friend it.
You kind of mixed the two styles together and that is what the error is trying to tell you.
You do not need to implement anything to make a - b - c work as the compiler will transform that into temp = a - b; temp - c;.

How can I override the << operator for a class without it being in its namespace? [duplicate]

Is there a difference between defining a global operator that takes two references for a class and defining a member operator that takes only the right operand?
Global:
class X
{
public:
int value;
};
bool operator==(X& left, X& right)
{
return left.value == right.value;
};
Member:
class X
{
int value;
bool operator==( X& right)
{
return value == right.value;
};
}
One reason to use non-member operators (typically declared as friends) is because the left-hand side is the one that does the operation. Obj::operator+ is fine for:
obj + 2
but for:
2 + obj
it won't work. For this, you need something like:
class Obj
{
friend Obj operator+(const Obj& lhs, int i);
friend Obj operator+(int i, const Obj& rhs);
};
Obj operator+(const Obj& lhs, int i) { ... }
Obj operator+(int i, const Obj& rhs) { ... }
Your smartest option is to make it a friend function.
As JaredPar mentions, the global implementation cannot access protected and private class members, but there's a problem with the member function too.
C++ will allow implicit conversions of function parameters, but not an implicit conversion of this.
If types exist that can be converted to your X class:
class Y
{
public:
operator X(); // Y objects may be converted to X
};
X x1, x2;
Y y1, y2;
Only some of the following expressions will compile with a member function.
x1 == x2; // Compiles with both implementations
x1 == y1; // Compiles with both implementations
y1 == x1; // ERROR! Member function can't convert this to type X
y1 == y2; // ERROR! Member function can't convert this to type X
The solution, to get the best of both worlds, is to implement this as a friend:
class X
{
int value;
public:
friend bool operator==( X& left, X& right )
{
return left.value == right.value;
};
};
To sum up to the answer by Codebender:
Member operators are not symmetric. The compiler cannot perform the same number of operations with the left and right hand side operators.
struct Example
{
Example( int value = 0 ) : value( value ) {}
int value;
Example operator+( Example const & rhs ); // option 1
};
Example operator+( Example const & lhs, Example const & rhs ); // option 2
int main()
{
Example a( 10 );
Example b = 10 + a;
}
In the code above will fail to compile if the operator is a member function while it will work as expected if the operator is a free function.
In general a common pattern is implementing the operators that must be member functions as members and the rest as free functions that delegate on the member operators:
class X
{
public:
X& operator+=( X const & rhs );
};
X operator+( X lhs, X const & rhs )
{
lhs += rhs; // lhs was passed by value so it is a copy
return lhs;
}
There is at least one difference. A member operator is subject to access modifiers and can be public, protected or private. A global member variable is not subject to access modifier restrictions.
This is particularly helpful when you want to disable certain operators like assignment
class Foo {
...
private:
Foo& operator=(const Foo&);
};
You could achieve the same effect by having a declared only global operator. But it would result in a link error vs. a compile error (nipick: yes it would result in a link error within Foo)
Here's a real example where the difference isn't obvious:
class Base
{
public:
bool operator==( const Base& other ) const
{
return true;
}
};
class Derived : public Base
{
public:
bool operator==( const Derived& other ) const
{
return true;
}
};
Base() == Derived(); // works
Derived() == Base(); // error
This is because the first form uses equality operator from base class, which can convert its right hand side to Base. But the derived class equality operator can't do the opposite, hence the error.
If the operator for the base class was declared as a global function instead, both examples would work (not having an equality operator in derived class would also fix the issue, but sometimes it is needed).

C++ two-way operators, is it possible?

For example, we have this class:
class my_class
{
public:
friend my_class operator* (const my_class&, int a);
friend my_class operator* (int a, my_class&);
};
my_class operator* (int a, my_class&)
{
// do my_class * a
}
my_class operator* (int a, my_class&)
{
// do a * my_class
}
is it possible to do just one operator* to do what these two do?
Thanks!
You cannot do that. However, you can implement one and simply call it from the other one:
my_class operator *(const my_class &l, int r) {
// implement the actual operator here.
}
my_class operator *(int l, const my_class &r) {
return r * l;
}
(Note that you cannot implement the latter function as part of the class. You have to do it externally. The first function can be implemented as an instance method, because its first argument is of the class type.)
You can implement one by using the other:
my_class operator*(int lhs, const my_class& rhs)
{
return rhs * lhs;
}
if the operation itself is commutative. This is not always the case, so be careful.
There are also libraries to help you with certain operators. If you have
my_class mc, a, b;
a = mc * 1;
b = 1 * mc;
you probably also want to be able to do something like
mc *= 1;
In that case you only implement
my_class& my_class::operator*=( int v );
and you can use Boost.Operators or df.operators to generate the other operators automatically.
Example:
struct my_class
: df::commutative_multipliable< my_class, int >
{
// ...
my_class& operator*=( int v )
{
// ... implement me!
return this;
}
// ...
};
In this example you again only implement one operation and the rest is generated using a common schema.

simple c++: How to overload the multiplication operator so that float*myClass and myClass*float works

class MyClass;
int main()
{
float a = 5;
MyClass c1;
MyClass c2 = a*c1;
MyClass c3 = c1*a;
}
How can I overload the multiply operator so that both a*c1 and c1*a work?
Like so:
MyClass operator* (float x, const MyClass& y)
{
//...
}
MyClass operator* (const MyClass& y, float x)
{
//...
}
The second one can also be a member function:
class MyClass
{
//...
MyClass operator* (float x);
};
The first 2 options work as declarations outside of class scope.

C++ multiple operator overloads for the same operator

I know I can answer this question easily for myself by generatin the code and see if it compiles. But since I couldn't find a similar question, I thought it's knowledge worth sharing.
Say I am overloading the + operator for MyClass. Can I overload it multiple times. Different overload for different types. Like this:
class MyClass{
...
inline const MyClass operator+(const MyClass &addend) const {
cout<<"Adding MyClass+MyClass"<<endl;
...//Code for adding MyClass with MyClass
}
inline const MyClass operator+(const int &addend) const {
cout<<"Adding MyClass+int"<<endl;
...//Code for adding MyClass with int
}
...
};
int main(){
MyClass c1;
MyClass c2;
MyClass c3 = c1 + c2;
MyClass c4 = c1 + 5;
}
/*Output should be:
Adding MyClass+MyClass
Adding MyClass+in*/
The reason I want to do this is that I am building a class that I want to be as optimized as possible. Performance is the biggest concern for me here. So casting and using switch case inside the operator + overloaded function is not an option. I f you'll notice, I made both the overloads inline. Let's assume for a second that the compiler indeed inlines my overloads, then it is predetermined at compile time which code will run, and I save the call to a function (by inlining) + a complicated switch case scenario (in reality, there will be 5+ overloads for + operator), but am still able to write easily read code using basic arithmetic operators.
So, will I get the desired behavior?
Yes.
These operator functions are just ordinary functions with the special names operator#. There's no restriction that they cannot be overloaded. In fact, the << operator used by iostream is an operator with multiple overloads.
The canonical form of implementing operator+() is a free function based on operator+=(), which your users will expect when you have +. += changes its left-hand argument and should thus be a member. The + treats its arguments symmetrically, and should thus be a free function.
Something like this should do:
//Beware, brain-compiled code ahead!
class MyClass {
public:
MyClass& operator+=(const MyClass &rhs) const
{
// code for adding MyClass to MyClass
return *this;
}
MyClass& operator+=(int rhs) const
{
// code for adding int to MyClass
return *this;
}
};
inline MyClass operator+(MyClass lhs, const MyClass& rhs) {
lhs += rhs;
return lhs;
}
inline MyClass operator+(MyClass lhs, int rhs) {
lhs += rhs;
return lhs;
}
// maybe you need this one, too
inline MyClass operator+(int lhs, const MyClass& rhs) {
return rhs + lhs; // addition should be commutative
}
(Note that member functions defined with their class' definition are implicitly inline. Also note, that within MyClass, the prefix MyClass:: is either not needed or even wrong.)
Yes, you can overload operators like this. But I'm not sure what "switch case" you are referring to. You can live with one overload if you have a converting constructor
class MyClass{
...
// code for creating a MyClass out of an int
MyClass(int n) { ... }
...
inline const MyClass MyClass::operator+(const MyClass &addend) const {
cout<<"Adding MyClass+MyClass"<<endl;
...//Code for adding MyClass with MyClass
}
...
};
No switch is needed at all. This is eligible if "MyClass" logically represents a number.
Notice that you should overload these operators by non-member functions. In your code 5 + c1 would not work, because there is no operator that takes an int as left hand side. The following would work
inline const MyClass operator+(const MyClass &lhs, const MyClass &rhs) {
// ...
}
Now if you keep the converting constructor you can add the int by either side with minimal code overhead.