question on operator overloading.

M

Master of C++

Hello Group,

Please take a look at the following (simple) C++ code (at the end of
this post) that does operator overloading. It gives me the following
compile error:

complex.cpp: In function `int main()':
complex.cpp:59: no match for `cmplx& = cmplx' operator
complex.cpp:26: candidates are: cmplx& cmplx::eek:perator=(cmplx&)

I am guessing that the error has something to do with the way I have
defined operator=. But I am not sure what went wrong. I am passing all
arguments as references because in my actual code the objects that I am
dealing with a large and it would be inefficient to pass them as copies
to operator=(). I am guessing the C++ interprets the line,

c = a + b;

as

c.operator=(operator+(a, b));

which should work based on the definitions in the code listed below:

class cmplx
{
double real, imag;

public :
cmplx()
{
;
}
cmplx(double realP, double imagP)
{
real = realP;
imag = imagP;
}

cmplx(cmplx &another)
{
real = another.real;
imag = another.imag;
}

cmplx &operator=(cmplx &another)
{
real = another.real;
imag = another.imag;
return *this;
}

cmplx& operator+=(cmplx &another)
{
real += another.real;
imag += another.imag;
return *this;
}

void print(void)
{
printf("[%d + j %d]", real, imag);
}
};

cmplx operator+(cmplx &first, cmplx &second)
{
cmplx tmp(first);
tmp += second;
return tmp;
}

int main(void)
{
cmplx *a, b, c;

a = new cmplx(1, 1);
b = *a;

c = b + *a;

printf("a = "); a->print(); printf("\n");
printf("b = "); b.print(); printf("\n");
printf("c = "); c.print(); printf("\n");
delete a;
}

Thanks a lot !
-Vijay.
 
A

Alf P. Steinbach

* Master of C++:
Hm.


class cmplx

STYLE. Don't use silly abrvatns.

{
double real, imag;

STYLE. Use systematic indentation.

public :
cmplx()
{
;

STYLE. Don't use superflous semicolons.
STYLE. Use systematic indentation.


STYLE. Do use blank lines between functions.

cmplx(double realP, double imagP)
{
real = realP;

STYLE. Use systematic indentation.
imag = imagP;
}

STYLE. Use initializer lists.
STYLE. Use systematic indentation.

cmplx(cmplx &another)

DESIGN ERROR. Use const argument.
{
real = another.real;
imag = another.imag;
}

STYLE. Use initializer lists.
STYLE. Use systematic indentation.

cmplx &operator=(cmplx &another)

DESIGN ERROR. Use const argument.
{
real = another.real;

STYLE. Use systematic indentation.
imag = another.imag;
return *this;
}

STYLE. Use systematic indentation.

cmplx& operator+=(cmplx &another)

DESIGN ERROR. Use const argument.
{
real += another.real;

STYLE. Use systematic indentation.
imag += another.imag;
return *this;
}

void print(void)

DESIGN ERROR. Don't do i/o in a data handling class.
STYLE. Don't use 'void' argument list (C-ism).

{
printf("[%d + j %d]", real, imag);

STYLE. As a newbie, do not use C library i/o, use typesafe C++ i/o.
ERROR. Because you failed to do that you have an error here.
STYLE. Use systematic indentation.

STYLE. Use systematic indentation.

cmplx operator+(cmplx &first, cmplx &second)


DESIGN ERROR. Use const argument.
{
cmplx tmp(first);


STYLE. Use systematic indentation.
tmp += second;
return tmp;
}

int main(void)

STYLE. Don't use 'void' argument list (C-ism).
{
cmplx *a, b, c;

STYLE. Use systematic indentation.
STYLE. As a newbie, don't use raw pointers. Use e.g. std::auto_ptr.
a = new cmplx(1, 1);


b = *a;

c = b + *a;

printf("a = "); a->print(); printf("\n");

STYLE. As a newbie, do not use C library i/o, use typesafe C++ i/o.
 
M

Master of C++

Hello Mr. Steinbach,

Thanks for your suggestions. I normally use most of the design and
style guidelines that you have suggested (Google Groups removed all the
indentation I used when I copied and pasted the code - and pressed the
post button). I wrote this piece of code in a bit of a hurry to
illustrate my problem - and it does gives the same compile error.

I removed the operator=() function from my original listing and the
code compiled properly. I am not able to explain why this happens
though. What else is wrong with my implementation of the operator=()
function ? (other than style errors and fact that I forgot to include
'const' before the arguments).

Thanks,
Vijay.

BTW, please ignore my nickname ("Master of C++" - somehow crossed my
mind when I subscribed to this group). I am neither a newbie, nor an
expert - but somewhere in the middle...
 
G

Gianni Mariani

Master said:
Hello Mr. Steinbach,

Thanks for your suggestions. I normally use most of the design and
style guidelines that you have suggested (Google Groups removed all the
indentation I used when I copied and pasted the code - and pressed the
post button). I wrote this piece of code in a bit of a hurry to
illustrate my problem - and it does gives the same compile error.

I removed the operator=() function from my original listing and the
code compiled properly. I am not able to explain why this happens
though. What else is wrong with my implementation of the operator=()
function ? (other than style errors and fact that I forgot to include
'const' before the arguments).

Show us your new code.

The "const" is significant.

These are seen as two separate functions.
void f( const int & );
void f( int & );


The compiler auto generates a copy constructor, yet you
provided one:

cmplx(cmplx &another)
{
real = another.real;
imag = another.imag;
}


cmplx.cpp:63: error: no match for 'operator=' in 'c = operator+(cmplx&,
cmplx&)(((cmplx&)a))'
cmplx.cpp:29: note: candidates are: cmplx& cmplx::eek:perator=(cmplx&)

It seems like the compiler didn't like to pass a temporary as a
non-const to the '=' operator.

Adding "const" to operator= then gets this error message:

cmplx.cpp:63: error: no matching function for call to `cmplx::cmplx(cmplx)'
cmplx.cpp:21: note: candidates are: cmplx::cmplx(cmplx&)

Now we're missing the constructor that takes a const - fix that and it
will compile.

Anyhow - when you're done, it would look somthing like this:

#include <iostream>

class cmplx
{
double m_real, m_imag;

public :

cmplx()
{
}

cmplx(double realP, double imagP)
: m_real( realP ),
m_imag( imagP )
{
}

cmplx(const cmplx &another)
: m_real( another.m_real ),
m_imag( another.m_imag )
{
}

cmplx & operator=(const cmplx &another)
{
m_real = another.m_real;
m_imag = another.m_imag;
return *this;
}


cmplx & operator+=(cmplx &another)
{
m_real += another.m_real;
m_imag += another.m_imag;
return *this;
}

double real() const
{
return m_real;
}

double imag() const
{
return m_imag;
}
};

const cmplx operator+( const cmplx &first, const cmplx &second )
{
return cmplx(
first.real() + second.real(),
first.imag() + second.imag()
);
}

namespace std {

template<
typename w_char_type,
class w_traitsbasic_ostream<w_char_type, w_traits>& operator << (
basic_ostream<w_char_type, w_traits> & o_ostream,
const cmplx & value
) {

o_ostream << "[" << value.real() << " + j " << value.imag() << "]";
return o_ostream;
}

} // namespace std



int main(void)
{
cmplx *a, b, c;

a = new cmplx(1, 1);
b = *a;

c = b + *a;

std::cout << "a = " << * a << "\n";
std::cout << "b = " << b << "\n";
std::cout << "c = " << c << "\n";

delete a;
}
 
M

Master of C++

Dear Mr. Mariani,

Thanks for the suggestion ! Adding the 'const' keyword did work. But I
am surprised. I thought that the 'const' keyword is just a matter of
style if I am 100% sure that I will not be modifying the object that is
referenced using the pointer that is sent as an argument. It appears
that there is more significance to the keyword than I thought it had.
Thanks for pointing this to me.

Here is the modified code in which I commented out the operator=() part
and retained the copy constructor (I hope this time Google Groups does
not remove the indents when I post this message). I have another
question though. How does the compiler auto-generate a copy constructor
? (This class was simple, what about a more complex class that requires
complicated copy operations).

Thanks,
-Vijay.

class cmplx
{
double real, imag;

public :
cmplx()
{
;
}
cmplx(double realP, double imagP)
{
real = realP;
imag = imagP;
}

cmplx(cmplx &another)
{
real = another.real;
imag = another.imag;
}

/*
cmplx& operator=(const cmplx &another)
{
real = another.real;
imag = another.imag;
return *this;
}
*/

cmplx& operator+=(cmplx &another)
{
real += another.real;
imag += another.imag;
return *this;
}

void print(void)
{
printf("[%.2f + j %.2f]", real, imag);
}
};

cmplx operator+(cmplx &first, cmplx &second)
{
cmplx tmp(first);
tmp += second;
return tmp;
}

int main(void)
{
cmplx a(1, 1), b(2, 2), c;


c = b + a;

printf("a = "); a.print(); printf("\n");
printf("b = "); b.print(); printf("\n");
printf("c = "); c.print(); printf("\n");
}
 
D

Dave Moore

Master of C++ said:
Dear Mr. Mariani,

Thanks for the suggestion ! Adding the 'const' keyword did work. But I
am surprised. I thought that the 'const' keyword is just a matter of
style if I am 100% sure that I will not be modifying the object that is
referenced using the pointer that is sent as an argument.

No ... const-ness is an integral and extremely important concept in C++ that
should be considered even at the earliest stages of design. I think it is
reasonable to say that code that is not const-correct is not correct at all.
It appears that there is more significance to the keyword than I
thought it had. Thanks for pointing this to me.

You should really look deeper into this ... pick up a copy of a good C++
book for more detailed examples .. I suggest Herb Sutter's "Exceptional
C++", or Scott Meyer's "Effective C++". Actually, a nice worked example of
const-correctness is on Herb Sutter's website at:
http://www.gotw.ca/gotw/006.htm

HTH,

Dave Moore
 
G

Gianni Mariani

Master said:
Dear Mr. Mariani,
....

I have another
question though. How does the compiler auto-generate a copy constructor
? (This class was simple, what about a more complex class that requires
complicated copy operations).

The compiler will generate a "default" copy constructor and assignment
that basically does a member-wise copy (or assignment) of all the elements.

If you need to do somthing else, you had better provide one. You
probably need to read-up on the "rule of three".

"Any class that has an explicitly defined destructor, copy constructor
or assignment operator generally needs all three."
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top