| Topic: |
DEVELOP > c-Plus-Plus |
| User: |
"Master of C++" |
| Date: |
16 Jan 2005 05:54:13 PM |
| Object: |
question on operator overloading. |
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::operator=(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.
.
|
|
| User: "Alf P. Steinbach" |
|
| Title: Re: question on operator overloading. |
16 Jan 2005 06:30:03 PM |
|
|
* 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.
printf("b = "); b.print(); printf("\n");
printf("c = "); c.print(); printf("\n");
delete a;
}
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
.
|
|
|
| User: "Master of C++" |
|
| Title: Re: question on operator overloading. |
16 Jan 2005 07:00:03 PM |
|
|
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...
.
|
|
|
| User: "Gianni Mariani" |
|
| Title: Re: question on operator overloading. |
16 Jan 2005 08:19:16 PM |
|
|
Master of C++ wrote:
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::operator=(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_traits
basic_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;
}
.
|
|
|
| User: "Master of C++" |
|
| Title: Re: question on operator overloading. |
16 Jan 2005 09:47:31 PM |
|
|
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");
}
.
|
|
|
| User: "Dave Moore" |
|
| Title: Re: question on operator overloading. |
17 Jan 2005 02:21:54 AM |
|
|
"Master of C++" <masteroftensors@gmail.com> wrote in message
news:1105933651.942424.297170@f14g2000cwb.googlegroups.com...
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
.
|
|
|
|
| User: "Gianni Mariani" |
|
| Title: Re: question on operator overloading. |
17 Jan 2005 09:41:25 PM |
|
|
Master of C++ wrote:
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."
.
|
|
|
|
|
|
|
|

|
Related Articles |
|
|