Cascading for overloaded + operator - c++

Here's the current code:
const complex complex::operator+(const complex &right)
{
complex result;
result.realPart = realPart + right.realPart;
result.imPart = imPart + right.imPart;
return result;
}
How do i modify so that
a = b + c + d;
is allowed?

Make it a const member function:
const complex complex::operator+(const complex &right) const ...

Related

passing "const ..." as "this" argument discards qualifiers [-fpermissive]

I'm writing a header file to learn more about operator overloading in C++, and I got the following error while implementing the division method for two complex numbers.
Here is the source code:
#ifndef __COMP_H
#define __COMP_H
#include <iostream>
class Complex{
private:
double real;
double imag;
public:
//constructor
Complex(double r=0, double i=0){real = r; imag = i;}
//operator overloading
Complex operator + (Complex const &obj){
Complex res;
res.real = real + obj.real;
res.imag = imag + obj.imag;
return res;
}
Complex operator - (Complex const &obj){
Complex res;
res.real = real - obj.real;
res.imag = imag - obj.imag;
return res;
}
Complex operator * (Complex const &obj){
Complex res;
res.real = real*obj.real + (-1)*imag*obj.imag;
res.imag = real*obj.imag + imag*obj.real;
return res;
}
Complex operator * (double const i){
Complex res;
res.real = i*real;
res.imag = i*imag;
return res;
}
Complex operator / (Complex const &obj){
Complex conj(obj.real, (-1)*obj.imag);
Complex res = (*this)*obj; //numerator
Complex den = obj*conj; //denominator, it will be 0 as it's imaginary value
res = res*(1/den.real); //multiply it with a scalar value
return res;
}
void print(){
std::cout << real << " + " << imag << "j\n";
}
};
#endif
and the error looks as follows
In file included from main.cpp:2:
comp.h: In member function 'Complex Complex::operator/(const Complex&)':
comp.h:52:27: error: passing 'const Complex' as 'this' argument discards qualifiers [-fpermissive]
Complex den = obj*conj; //denominator, it will be 0 as it's imaginary value
^~~~
comp.h:32:13: note: in call to 'Complex Complex::operator*(const Complex&)'
Complex operator * (Complex const &obj){
^~~~~~~~
I've seen other answers on stackoverflow but did not understand it, what is meant by this error and how to fix it? Thanks!
This
Complex operator - (Complex const &obj) { ...
and others are non-const member functions. Member functions are non-const by default, meaning they are declared to modify this. You cannot call them on a const instance. Most of your operators do not modify this, hence should be declared as const:
Complex operator - (Complex const &obj) const { ...
// ^^

How to overload operator + with the parameters of a class? [duplicate]

This question already has answers here:
What are the basic rules and idioms for operator overloading?
(8 answers)
How to overload operator+
(3 answers)
Closed 2 years ago.
I am learning about overloading operators in c++ and I have done this code aboout the sum of two imaginary numbers, formed by the real part and the imaginary part.
#include<iostream>
using namespace std;
class Complex {
private:
int real, imag;
public:
Complex(int r, int i) {
real = r;
imag = i;
}
Complex operator + (Complex const &num1, Complex const &num2) {
Complex res;
res.real = num1.real + num2.real;
res.imag = num1.imag + num2.imag;
return res;
}
void print() {
cout << real << " + i" << imag << endl;
}
};
int main()
{
Complex c1(10, 5), c2(2, 4);
Complex c3 = c1 + c2;
c3.print();
}
Something should be wrong because it shows a lot of errors, notes and warnings :(
error: ‘Complex Complex::operator+(const Complex&, const Complex&)’ must take either zero or one argument
error: no match for ‘operator+’ (operand types are ‘Complex’ and ‘Complex’)
note: ‘Complex’ is not derived from ‘std::__cxx11::basic_string<_CharT, _Traits, _Alloc>’
A binary (2 parameter) operator can't be a class member, it needs to be a standalone function instead:
class Complex {
...
public:
...
friend Complex operator + (Complex const &lhs, Complex const &rhs);
...
};
Complex operator + (Complex const &lhs, Complex const &rhs) {
return Complex(
lhs.real + rhs.real,
lhs.imag + rhs.imag
);
}
Which can also be inlined:
class Complex {
...
public:
...
friend Complex operator + (Complex const &lhs, Complex const &rhs) {
return Complex(
lhs.real + rhs.real,
lhs.imag + rhs.imag
);
}
...
};
So, a statement like c1 + c2 gets processed as operator+(c1, c2).
A unary (1 parameter) operator, on the other hand, must be a class member that acts on this as the left-side value:
class Complex {
...
public:
...
Complex operator + (Complex const &rhs) const {
return Complex(
real + rhs.real,
imag + rhs.imag
);
}
...
};
Then a statement like c1 + c2 gets processed as c1.operator+(c2).
The way you have defined operator+ is fine, expect that it needs to be a friend function. Also, note that Complex res; will not compile because you don't have a default constructor.
You could define the function like this:
friend Complex operator + (Complex const &num1, Complex const &num2) {
return {num1.real + num2.real, num1.imag + num2.imag};
}
Here's a demo.
Note also, that I fixed the bug where you are adding the imaginary part of num1 twice.

How can i optimse this part of code:

I have class Complex, with defined friend Complex operators of +,-,*,/.
class Complex
{
private:
float Re;
float Im;
public:
friend Complex operator + (const Complex ,const Complex );
friend Complex operator * (const Complex ,const Complex );
friend Complex operator - (const Complex ,const Complex );
friend Complex operator / (const Complex ,const Complex );
};
Complex operator + (const Complex a,const Complex b)
{
Complex c(0,0);
c.Re=a.Re+b.Re;
c.Im=a.Im+b.Im;
return c;
}
Complex operator * (const Complex a,const Complex b)
{
Complex c(0,0);
c.Re=a.Re*b.Re;
c.Im=a.Im*b.Im;
return c;
}
Complex operator - (const Complex a,const Complex b)
{
Complex c(0,0);
c.Re=a.Re-b.Re;
c.Im=a.Im-b.Im;
return c;
}
Complex operator / (const Complex a,const Complex b)
{
if(b.Im && b.Re)
{
Complex c(0,0);
c.Re=a.Re/b.Re;
c.Im=a.Im/b.Im;
return c;
}
else
{
std::cout<<"Cannot divide, one of parametars is zero."<<std::endl;
}
}
What i want to optimse is instead of writing this all this so many times, and just changing the +,-,*,/ operator, i could write it once, and when in int main()
some of operators is beigned called(used) just read it and apply it to the function. Is it possible?
You can do something like this:
Add this template function into Complex:
template <typename OP>
static Complex apply(const Complex a, const Complex b, OP op) {
Complex c;
c.Re = op(a.Re, b.Re);
c.Im = op(a.Im, b.Im);
return c;
}
Then the implementation of the operators is a little bit smaller:
Complex operator + (const Complex a,const Complex b)
{
return Complex::apply(a, b, std::plus<float>());
}
Complex operator * (const Complex a,const Complex b)
{
return Complex::apply(a, b, std::multiplies<float>());
}
Complex operator - (const Complex a,const Complex b)
{
return Complex::apply(a, b, std::minus<float>());
}
Complex operator / (const Complex a,const Complex b)
{
if(b.Im && b.Re)
{
return Complex::apply(a, b, std::divides<float>());
}
else
{
std::cout<<"Cannot divide, one of parametars is zero."<<std::endl;
// Note: missing return value here
}
}
Note: multiplication and division aren't defined like this for complex numbers.
Note2: I don't think this can be much smaller, as you must define the operators one by one, as far as I know (there is no trickery to define them at once, at least not in C++17).

Why can't I pass this class as a reference when returned from arithmetic operators?

If I have a simple class like this:
template<typename T>
class coord
{
public:
coord() : x(0), y(0)
{
}
coord(T X, T Y) : x(X), y(Y)
{
}
T x;
T y;
coord& operator-=(const coord& rhs)
{
(*this).x -= rhs.x;
(*this).y -= rhs.y;
return *this;
}
coord& operator+=(const coord& rhs)
{
(*this).x += rhs.x;
(*this).y += rhs.y;
return *this;
}
};
Along with the following operators (they're not friends because there's no private members to access).
template<typename T = int>
inline coord<T> operator-(coord<T> lhs, const coord<T>& rhs)
{
lhs -= rhs;
return lhs;
}
template<typename T = int>
inline coord<T> operator+(coord<T> lhs, const coord<T>& rhs)
{
lhs += rhs;
return lhs;
}
Elsewhere in my code I have another class A with a method that looks like this:
void A::SetVarC(coord<int>& c)
{
m_c = c;
}
(assume there's a getter for m_c as well)
When I try to invoke this method using the addition and subtraction operators I overloaded:
int x = 1;
int y = 1;
A* a = new A();
coord c1(1,2);
a->SetVarC(c1 - a->GetVarC() + coord<int>(x,y));
I get an error that there's no known conversion from coord<int> to coord<int>&. I can see that my subtraction and addition operators aren't returning references, but I thought that wouldn't matter. I am using C++11... are move semantics coming into play here?
Temporary cannot be bind to non const reference, change SetVarC to
void A::SetVarC(const coord<int>& c)
{
m_c = c;
}
or
void A::SetVarC(coord<int> c)
{
m_c = std::move(c);
}
You are passing a temporary coord<int> object to A::SetVarC() which requires a non-const reference, which is not possible.
You should fix your code by changing A::SetVarC() to accept a const coord<int>&.
You're creating arithmetic operators with a side affect...
These operators shouldn't change the value of the arguments used.
And, to the answer your question, these methods return a temporary object, that can't be passed as reference to SetVarC.
template<typename T = int>
inline coord<T> operator-(const coord<T>& lhs, const coord<T>& rhs)
{
coord<T> res(lhs)
res -= rhs;
return res;
}
template<typename T = int>
inline coord<T> operator+(const coord<T>& lhs, const coord<T>& rhs)
{
coord<T> res(lhs)
res += rhs;
return res;
}

c++ Operator overloading,

Whats wrong with my code shown below? please somebody throw some light. Thanks for your time !
#include<iostream.h>
using namespace std;
struct mydata{
int mx;
mydata(int x = 0){}
mydata operator+(const mydata& rhs){
mydata temp(rhs);
return temp;
}
operator int() const{ return mx; }
operator double() const{ return mx; }
};
int main(){
mydata d;
mydata r = d + 5; // L1
5 + d; // L2
d + d; // L3
}
First, you haven't stated what the problem is, but presumably you want an operator+ that sums the mx values of two mydata objects:
mydata operator+(const mydata& rhs){
return mydata (mx + rhs.mx);
}
Next, I would suggest making this a non-member function, so that the LHS and RHS get treated in the same way, fixing the problem in L2:
mydata operator+(const mydata& lhs, const mydata& rhs){
return mydata (lhs.mx + rhs.mx);
}
Finally, you will have an ambiguous overload remaining, because the compiler cannot decide whether to use the built-in operator+(int,int) or your own operator+(const mydata&, const mydata&). You can fix this by removing the cast operators int() and double().
See demo here.
The problem (stated the comment) is that compiler doesn't know which + you want to execute:
(double)d + 5
or
(int)d + 5
In order to resolve this ambiguoity, you should point the type conversion, or replace one of these operators by a named function:
operator int() const{ return mx; }
operator double() const{ return mx; }
If you want instead use d + mydata(5) you should write so, because the above variants are more likely to be applied
You could provide a few non-member operator+ to enable operator+ with different data type:
mydata operator+(const mydata& lhs, const mydata& rhs){
return mydata (lhs.mx + rhs.mx);
}
mydata operator+(int mx, const mydata& rhs){
return mydata (rhs.mx+mx);
}
mydata operator+(const mydata& lhs, int mx){
return mydata(lhs.mx+mx);
}
You can't do 5 + d. 5 can not be converted to class object like this. For this you need to get the operator + definition out of the class method. (in my knowledge preferably friend).