Overloading Operators Twice With Different Arguments - c++

I want to overload the * operator for a class, one which is in case it is multiplied by a real number double and the other is when multiplied by the same class type.
Below is my code:
class Vector2D {
...
friend Vector2D operator* (const Vector2D&);
friend Vector2D operator* (const double); // getting error here
};
The error I'm getting is: 'Vector2D operator*(double)' must have an argument of class or enumerated type
Is it possible to overload operators more than once, and if so, why am I getting an error?

class Vector2D {
...
friend Vector2D operator* (const Vector2D&);
That is overloading unary operator* (i.e. dereference operator) as a free function, not overloading the multiplication of two vectors. You cannot overload operators that apply only to non-class types, and that is the error for:
friend Vector2D operator* (const double);
You probably meant to write:
friend Vector2D operator*(const Vector2D&,const Vector2D&);
friend Vector2D operator*(const Vector2D&,double);

The problem is that you're overloading unary operator*, not binary. Your friend declarations are not member functions.
Either remove the friend (if you want to overload the operators as member functions), or else add a first parameter of type const Vector2D& or Vector2D& (if you want to overload as free functions). The latter is usually preferable, since then you get implicit conversion on both arguments -- member operator overloads will implicitly convert the right hand side but not the left.
The reason you might not want a reference as the first argument to binary operator*, is so that you can implement it like this:
Vector2D operator*(Vector2D lhs, const Vector2D &rhs) {
lhs *= rhs;
return lhs;
}
The same would apply to addition (and addition of two vectors makes sense to me in a way that multiplication of two vectors does not).

You are not allowed to override the operators for built-in types. In this case you're providing a declaration for a unary * operator for type double which isn't allowed.
I think you want to remove the friend declaration and make these member functions instead.

Related

Operator Overloading as member function

Why is it giving the error.
class Complex{
int real,imaginary;
public:
Complex():real(0),imaginary(0){};
Complex(int real, int imaginary):real(real),imaginary(imaginary){};
int getreal()const{return real;}
int getimaginary()const{return imaginary;};
Complex &operator=(const Complex& );
Complex operator*(){
return Complex(real,-imaginary);
}
Complex operator+(const Complex &a, const Complex &d){
return Complex (d.getreal()+a.getreal(),a.getimaginary()+d.getimaginary());
}
};
When trying to overload the assingment operator.
Eroor says: too many parameter
What operators can we overload as member function and what not
When overriding operators that have left and right parameters, you should just pass the right parameter and declare it like this:
Complex operator+(const Complex &d){
return Complex(d.getreal() + getreal(), getimaginary() + d.getimaginary());
}
When doing that, when you call getreal() or directly access that variable without specifing the parameter, it will use the left parameter of the operator.
Some of the operators that cannot be overloaded are scope (::), ternary (:), sizeof, member access (.) and some others.
When defining an overloaded operator as a member function, the object pointed at by the this pointer is implicitly the first argument. So your operator overload needs to look like:
class Complex {
// ...
Complex operator+(const Complex &d) const {
return Complex (real + d.real, imaginary + d.imaginary);
}
};
Note that you don't need the getter functions, since you already have access to the data members inside the class.
Outside the class, i.e. as a non-member function, your overloaded operator is perfectly fine.

How to define correctly unary operator- in C++

Suppose we have this class definition:
class A{
public:
int a;
A(int i): a(i){}
A operator-() const { return A(- a); } # first operator- function
};
A operator-(const A& o) { return A(- o.a); } # second operator- function
Now, in the main function, if I write:
A a1(10);
A a2 = -a1; # Here the first operator- function (method) is called!
However, if I remove the first definition of operator- in the class, the second function is called.
I would llike to know why the compiler prefers the first definition when both of them are provided.
I would like to know also why the compiler accept to call the first function (method). Because I think that the method is synonym to a1- and not -a1 : The object on which the method is applied comes before (at the left of) the operator.
From the C++ standard, unary minus operator shall be defined like this:
T T::operator-() const;
inside class definition, and like this:
T operator-(const T &a);
outside class definition.
Now, you have both definition types in your class, so there member lookup comes in a play as specified here:
two separate lookups are performed: for the non-member operator
overloads and for the member operator overloads (for the operators
where both forms are permitted). Those sets are then merged with the
built-in operator overloads on equal grounds as described in overload
resolution. If explicit function call syntax is used, regular
unqualified name lookup is performed
So, basically, member lookup finds A operator-() const;, non-member lookup finds A operator-(const A& o);. Overload resolution selects A operator-() const;.

operator overloading with friend and member function

With in a class if we are using both member function and friend function to overload + operator its giving an error that ambiguous overload for ‘operator+’ how to resolve
I would suggest implementing it as a non-member function. That way, you can overload the function with other combinations. As an example, let's say you have a class Point and another class Vector (a gometric vector, not the std::vector).
You can overload
Point operator+(Point const&, Vector const&);
Point operator+(Vector const&, Point const&);
If you implement it as a member function, you implement only one of them in a class. To implement both, you'll have to implement the first one as a member function of Point and the second one as a member function of Vector.
You could have a member and non-member overload of operator+, if you really wanted to.
Foo a, b;
a.operator+(b); //call member function
operator+(a, b); //call non-member function
It ruins the whole point of operators, though, since you have to actually write out the method call.
Side note: non-member operator+ doesn't need to be a friend function. It's easily written as:
Foo operator+ (Foo lhs, const Foo& rhs)
{
return lhs += rhs;
}

Implements complex operator+(double,complex) as a member function

I've read the section 13.5 of the working draft N3797 and I've one question. Let complex be a class type which represents complex numbers. We can define the following operator function:
complex operator+(double d, complex c)
{
return *new complex(d+c.get_real(),c.get_imagine());
}
But how this operator function can be implements as a complex member function? Or must I to declare this operator function in every module which I've intend to use them?
There are two ways to define a binary operator overload, such as the binary + operator, between two types.
As a member function.
When you define it as member function, the LHS of the operator is an instance of the class. The RHS of the operator is the argument to the function. That's why when you define it as member function, it can only have one argument.
As a free function.
These functions must have two arguments. The first argument is the LHS of the operator and the second argument is the RHS of the operator.
Since double is not a class, you have to define operator+ overload between double as LHS and complex as RHS as a free function, with double const& or double as the first argument type and complex const& or complex as the second argument type.
What you're looking for is this:
inline complex operator +(double d, const complex& c)
{
return complex(d+c.get_real(), c.get_imagine());
}
This cannot be a member function if you want the operator to handle a left-side of the operator as a double. It must be a free function, possibly friended if access to anything besides the public interface of complex is needed.
If you want the right side of the add-op to be a double, a member function can be crafted:
complex operator +(double d) const
{
return complex(d+get_real(), get_imagine());
}
Note this is assuming this definition is within the body of the complex class definition. But in the interest of clarity I would recommend both be inline free functions.
Implicit Construction
Lined up with the usual suspects, what you're at-least-appearing to try to do is generally done with an implicit conversion constructor and a general free-function. By providing this:
complex(double d) : real(d), imagine()
{
}
in the class definition a double can implicitly construct a temporary complex where needed. This allows this:
inline complex operator +(const complex& lhs, const complex& rhs)
{
return complex(lhs.get_real() + rhs.get_real(),
lhs.get_imagine() + rhs.get_imagine());
}
to be used as a general solution to all sensible manifestations of what you appear to want.
In C++, operator overloading requires class types. You cannot overload the + operator for the basic type double.
Also, except in certain circumstances (short-lived programs or throwaway code), the pointer resulting from a call to the new operator should be captured, so that it can be later released with delete, preventing a situation known as a memory leak.
For it to be a member, the first parameter must be of the class type(though it is not explicitly specified). But you are sending a double as first argument. If you need this to work either make it friend function or just non-member function which can work only using public interface of the Complex class. And as others pointed out, you are leaking memory.

overloaded 'operator+' must be a unary or binary operator error

Following the advice given in this answer, I have overloaded the + operator in my simple Point class as follows (the += overload works fine).
Point operator+ (Point p1, const Point& p2)
{
return std::move(p1 += p2);
}
But I get an error saying
overloaded 'operator+' must be a unary or binary operator (has 3 parameters)
What is wrong?
It sounds like you have declared your operator as a member function. A member function takes an implicit first parameter, meaning your operator now takes three parameters. You can fix this by making it a non-member function.
In any case, it is preferable to declare it as a non-member, to ensure symmetry between the LHS and the RHS of the operation.
As for std::move, it is in the <utility> header. Although I can't see the reason to use it here.
You want to do either:
// Member function, performs (*this + right)
Point operator+ (Point & right)
or
// Free function, performs (left + right)
Point operator+ (const Point &left, const Point& right)
You made the operator a member function, meaning it actually has three parameters when you include the implicit first this parameter.
Either:
Use *this rather than p1 and get rid of that first parameter, or
Make the operator overload a free function (instead of a member) — this is preferred.