operator overloading in c++ - c++

suppose i have 2 objects of a class and it has one int data member.
i want to add those integer data to other object and store the output in the first obj's data member.I can overload the + operator and use the statement like below
X+Y //where X and Y are objects of one class.
if i have to add like below
X+10// here i want to add 10 to the data member of X.
for above also i can overload the operator +.
but if i have 10+X and i want to add 10 to the data member of X how could i do it?

The same way:
MyClass operator+(MyClass const& lhs, MyClass const& rhs);
MyClass operator+(MyClass const& lhs, int rhs);
MyClass operator+(int lhs, MyClass const& rhs);
(operator+ should not normally be a member.)
If you overload operator+, you'll also want to overload +=. One
frequent idiom involved implementing + in terms of +=. This can
be more or less automated (if you have a lot of classes
supporting operators) by defining something like:
template<typename DerivedType>
class ArithmeticOperators
{
public:
friend DerivedType operator+(
DerivedType const& lhs,
DerivedType const& rhs)
{
DerivedType result(lhs);
result += rhs;
return result;
}
// And so on for the other operators...
protected:
~ArithmeticOperators() {}
};
template<typename DerivedType, typename OtherType>
class MixedArithmeticOperators
{
public:
friend DerivedType operator+(
DerivedType const& lhs,
OtherType const& rhs)
{
DerivedType result(lhs);
result += rhs;
return result;
}
friend DerivedType operator+(
OtherType const& lhs,
DerivedType const& rhs)
{
DerivedType result(rhs);
result += lsh;
return result;
}
// And so on: non-commutative operators only have the
// first.
protected:
~MixedArithmeticOperators() {}
};
, then deriving from whatever is needed: in your case:
class MyClass : public ArithmeticOperators<MyClass>,
MixedArithmeticOperators<MyClass, int>

You have to create an overloaded operator as a free function with the correct parameter order:
// This will match "int + YourClass" additions
YourClass operator+(int Left, const YourClass & Right)
{
// If your addition operation is commutative, you can just call the other
// version swapping the arguments, otherwise put here your addition logic
return Right + Left;
}
If the operator needs to fiddle with the internals of your class you can make it friend.
As others pointed out, there are some best/common practices that you should follow if you implement operator+, I suggest you to have a look to the great C++-FAQ on operator overloading for more info about them.

Don't overload the operator + as a member function of the class.
You can either define a global function operator + with two parameters or make operator + a friend of your class (In that case you should be having a parameterized constructor to convert 10 to an object of your class-type).

Define a non-member stand-alone free function as:
sample operator+(int leftOperand, const sample & rightOperand)
{
//...
}

Although you can do that using a global operator+, I would advise not to do it.
Only use operator overloading for data types for which the operators are immediately clear, e.g.:
complex numbers
strings (+,- ok, but * probably doesn't make much sense here)
The risk with overloaded operators is that the compiler may perform unwanted conversions, especially if you didn't make the single-argument constructor explicit.

You should define a non-member friend function
YourClass operator+(const YourClass &a, const YourClass&b) {
// do the math here
}
it should be friend to get to the private members of YourClass. Also you should create constructor for YourClass that takes int.
In this way you've got one operator+ and for every other then int you just create another constructor.

Related

What is the proper way of returning a new instance of an immutable?

I would like to leave the two instances unchanged, and return a new one.
Currently I am doing it this way:
class myClass {
public:
myClass operator +(const myClass &obj) {
myClass ret = *this;
// some operation
return ret;
}
// functions...
};
It works, but I am not sure, if it is the correct way
Edit
The operator + is just an example. I'm just curious, how the immutable functions/methods should be written in C++
If myClass is supposed to be immutable under addition, you probably want to make operator+ a free function rather than a class member. (You might have to make it a friend function.)
myClass operator+(const myClass &lhs, const myClass &rhs) {
return myClass( /* some operation */ );
}
Note that both operands are taken by const reference, so you know you cannot accidentally change them (maintaining the immutability property). You're returning a new instance of myClass, which is now immutable. You construct and return the result in one step, because, if myClass really is immutable, you might not be able to default construct one and then set its value.
Here's a stupid example:
class myClass {
public:
explicit myClass(int x) : m_x(x) {}
friend myClass operator+(const myClass &lhs, const myClass &rhs);
private:
int m_x;
};
myClass operator+(const myClass &lhs, const myClass &rhs) {
return myClass(lhs.m_x + rhs.m_x);
}
If you really want to implement it as a class method, the method should be marked const to ensure the implementation doesn't accidentally mutate the left-hand instance.
Binary arithmetic operators (like operator+) are often defined in terms of the arithmetic self-assignment operators (like operator+=), which are obviously not immutable. If we add this method to myClass:
myClass &operator+=(const myClass &rhs) {
m_x += rhs.m_x;
return *this;
}
Then the common idiom for defining operator+ would be:
myClass operator+(const myClass &lhs, const myClass &rhs) {
myClass result = lhs;
result += rhs;
return result;
}
Now the implementation of operator+ doesn't require any of the private members of the class, so it no longer needs to be declared as a friend function.

What is meant by non-member operator overloading

I was recently going over an article on operator overloading in which it mentioned non-member operator overloading. I would appreciate it if someone could explain what is meant by non-member operator overloading with an example. I know what member operator overloading is (A method in a class which overloads an operator type (binary..etc) . I came across this post on SO which makes me believe that the purpose of non-member operator overloading is to handle operator overloading in which the first parameter is a not a class and is simply a native type. Any links or examples that explain what non-member operator overloading is would definitely be appreciated.
It means you can overload out-of-class:
struct X { int data; };
bool operator<(X const& a, X const& b)
{
return a.data < b.data;
}
This is useful for assymetrical overloading, where the left operand doesn't need to be your own type:
bool operator<(int a, X const& b)
{
return a < b.data;
}
A common idiom here is to combine it with in-class definition and friend declaration:
struct X
{
int data;
friend bool operator<(X const& a, X const& b) { return a.data<b.data; }
friend bool operator<(int a, X const& b) { return a<b.data; }
};
Here, operator< is still technically non-member.
Another useful side-effect of this, as pointed out by DrewDormann below, is that the (X const&, X const&) will apply to any operands that are implicitly convertible to X const&, not just expressions of that exact type.
the most common way is to overload operator<< that will be called on std::cout:
namespace X {
class MyClass {
...
};
}
std::ostream& operator<< (std::ostream&, const X::MyClass&);
this is called on std::ostream member so you don't define it inside your class.
however sometimes the functionality cannot be achieved via the public interfaces (because your operator needs access to data representation).

Overloading += operator in Polynom class for adding both Polynoms and constants

I am trying to overload += operator for my template Polynom class in a way so I would be able to use both Polynoms and constants as argument.
I wrote a constructor and following operator inside my class:
Polynom(const T& num = 0) {
coefs.push_back(num);
}
friend Polynom& operator += (Polynom& lhs, const Polynom& rhs) {
...
}
And it works fine, I am able to use: poly += 1;. When compiler runs into something likes that what does it do? It sees that there is no += operator that uses these arguments:
(Polynom<int>& lhs, const int)
But there is one for:
(Polynom<int>& lhs, const Polynom& rhs)
So, it tries to convert const int to const Polynom&? And it uses constructor for that, right? But then why doesn't this declaration work when adding a constant:
Polynom& operator += (Polynom& rhs) {
...
}
Compiler says "no match for operator +=".
When passing an int to a function taking a const Polynom&, the compiler is able to construct a temporary Polynom object from the int that is then bound to the const Polynom& parameter. However this doesn't happen with the Polynom& parameter because temporaries cannot be bound to non const references.
You need to show us the template code or your smallest compilable code that demonstrates the issue.
Try creating a method that accepts an integer parameter:
friend Polynom& operator+=(const Polynom& lhs, int constant);
I'm confused about your notation Polynom<int> which indicates your Polynom class is a template.

Overloading assignment operator

We can overload assignment operator as a normal function, but we cannot overload assignment operator as a friend function. Why?
Because the C++ Standard says so, Article 13.5.3/1:
An assignment operator shall be
implemented by a non-static member
function with exactly one parameter.
Because a copy assignment operator
operator= is implicitly declared for a
class if not declared by the user
(12.8), a base class assignment
operator is always hidden by the copy
assignment operator of the derived
class.
That's all you really need to know. A friend function is not a member function, so it cannot be used to overload the assignment operator.
If you would like to write:
MyClassObject = MyFriendObject;
Then you would want to implement a constructor that takes a const reference to the friend class as it's parameter.
The difference between overloading by friend function and overloading by member function is that the calling object must be the first operand in overloading by member function, while there is no restriction in overloading by friend function. This is the reason behind the standard. Similarly, some other operators requiring the first operand to be the calling function must be overloaded using member functions (examples: =, [], ->, and ( )).
You cannot "extend" the assignment operator with a "free function" outside the class, but you can design the class so it will allow it:
Data.h
class Data {
public:
Data& operator=(const Data& lhs) { /*...*/; return *this; }
template <typename T> Data& operator=(const T& lhs) {
return assign(*this, lhs); // Magic right here...
}
private:
// ...
};
Point.h
class Point {
public:
float x,y;
Point& operator=(const Point& lhs) { x = lhs.x, y = lhs.y; return *this; }
template <typename T> Point& operator=(const T& lhs) {
return assign(*this, lhs); // Magic right here...
}
};
Assignment.h
Data& assign(const Data& lhs, const Point& rhs) {
lhs["x"] = rhs.x;
lhs["y"] = rhs.y;
return lhs;
}
Point& assign(const Point& lhs, const Data& rhs) {
rhs.query("x", lhs.x) || rhs.query(0, lhs.x);
rhs.query("y", lhs.y) || rhs.query(1, lhs.y);
return lhs;
}

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.