Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > How to use operator overloading?

Reply
Thread Tools

How to use operator overloading?

 
 
Immortal Nephi
Guest
Posts: n/a
 
      01-16-2010
I try to write operator= and operator+ in class. The bult-in data
type will report "warning C4552: '+' : operator has no effect;
expected operator with side-effect" if my code shows this below.

int main()
{
int x = 0;
x + 1; // no effect
}

The C++ Compiler reports warning message. It is correct because I
should not write "x + 1;" However you will see user-defined type like
this below. I do not want "t + t2;". How can C++ Compiler report
error message? "t = t + t2;" and "t += t2" are acceptable.


class test
{
public:
test() {}
~test() {}

test& operator=( const test &r )
{
return *this;
}

test& operator+( const test &r )
{
return *this;
}
};

int main()
{
test t, t2;

t + t2; // ???
t = t + t2;

return 0;
}
 
Reply With Quote
 
 
 
 
osmium
Guest
Posts: n/a
 
      01-17-2010
"Immortal Nephi" wrote:

<elided stuff>

> test& operator+( const test &r )
> {
> return *this;
> }
> };


Shouldn't the code for a function that adds have a '+' someplace in the
code?

Is there an extra brace? Please post code that you compile, not simply code
produced by the same set of fingers. We call it "cut and paste".



 
Reply With Quote
 
 
 
 
Immortal Nephi
Guest
Posts: n/a
 
      01-17-2010
On Jan 16, 7:05*pm, "osmium" <(E-Mail Removed)> wrote:
> "Immortal Nephi" wrote:
>
> <elided stuff>
>
> > test& operator+( const test &r )
> > {
> > return *this;
> > }
> > };

>
> Shouldn't the code for a function that adds have a '+' someplace in the
> code?
>
> Is there an extra brace? *Please post code that you compile, not simply code
> produced by the same set of fingers. *We call it "cut and paste".


> > test& operator+( const test &r )
> > {
> > return *this;
> > }
> > };


I am asking. How can left object and right object be prevented from
doing addition. Only "left object += right object" and "left object =
left object + right object" are allowed.

Look at operator+ function below. I don't know how to write my code
in the operator+ function body. I do know how to do addition.

test& operator+=( const test &r )
{
this->x += r.x;
return *this;
}

test& operator+( const test &r )
{
this->x += r.x; // How to prevent addition?
return *this;
}

Another example does the same to string like below.

string s1 = "A", s2 = "B";
s1 + s2; // prevent from doing addition

s1 += s2; // s1 = "AB"
s1 = s1 + s2; // s1 = "ABB"

I hope I can explain clear. Thanks...
 
Reply With Quote
 
Immortal Nephi
Guest
Posts: n/a
 
      01-17-2010
On Jan 16, 7:30*pm, Immortal Nephi <(E-Mail Removed)> wrote:
> On Jan 16, 7:05*pm, "osmium" <(E-Mail Removed)> wrote:
>
>
>
>
>
> > "Immortal Nephi" wrote:

>
> > <elided stuff>

>
> > > test& operator+( const test &r )
> > > {
> > > return *this;
> > > }
> > > };

>
> > Shouldn't the code for a function that adds have a '+' someplace in the
> > code?

>
> > Is there an extra brace? *Please post code that you compile, not simply code
> > produced by the same set of fingers. *We call it "cut and paste".
> > > test& operator+( const test &r )
> > > {
> > > return *this;
> > > }
> > > };

>
> I am asking. *How can left object and right object be prevented from
> doing addition. *Only "left object += right object" and "left object =
> left object + right object" are allowed.
>
> Look at operator+ function below. *I don't know how to write my code
> in the operator+ function body. *I do know how to do addition.
>
> test& operator+=( const test &r )
> {
> this->x += r.x;
> return *this;
>
> }
>
> test& operator+( const test &r )
> {
> this->x += r.x; // How to prevent addition?
> return *this;
>
> }
>
> Another example does the same to string like below.
>
> string s1 = "A", s2 = "B";
> s1 + s2; // prevent from doing addition
>
> s1 += s2; // s1 = "AB"
> s1 = s1 + s2; // s1 = "ABB"
>
> I hope I can explain clear. *Thanks...- Hide quoted text -
>
> - Show quoted text -


I checked C++ Tutorial about operator+. The operator+ passes data by
value and operator+= passes data by reference. It does answer my
question about "s1 + s2;" instead of "s1 = s1 + s2;" I understand
now.

It is all I have now. Thanks...
 
Reply With Quote
 
osmium
Guest
Posts: n/a
 
      01-17-2010
Immortal Nephi wrote:

> On Jan 16, 7:05 pm, "osmium" <(E-Mail Removed)> wrote:
>> "Immortal Nephi" wrote:
>>
>> <elided stuff>
>>
>>> test& operator+( const test &r )
>>> {
>>> return *this;
>>> }
>>> };

>>
>> Shouldn't the code for a function that adds have a '+' someplace in
>> the code?
>>
>> Is there an extra brace? Please post code that you compile, not
>> simply code produced by the same set of fingers. We call it "cut and
>> paste".

>
>>> test& operator+( const test &r )
>>> {
>>> return *this;
>>> }
>>> };

>
> I am asking. How can left object and right object be prevented from
> doing addition. Only "left object += right object" and "left object =
> left object + right object" are allowed.
>
> Look at operator+ function below. I don't know how to write my code
> in the operator+ function body. I do know how to do addition.
>
> test& operator+=( const test &r )
> {
> this->x += r.x;
> return *this;
> }
>
> test& operator+( const test &r )
> {
> this->x += r.x; // How to prevent addition?
> return *this;
> }
>
> Another example does the same to string like below.
>
> string s1 = "A", s2 = "B";
> s1 + s2; // prevent from doing addition
>
> s1 += s2; // s1 = "AB"
> s1 = s1 + s2; // s1 = "ABB"
>
> I hope I can explain clear. Thanks...


I think you are trying to go too fast. For examaple, you had a destructor
in your earlier post, there is no reason at all to provide one. It makes me
wonder: Do you know what a destructor *does*? Do you understand shallow
copy, deep copy?

As far as I can tell, you expect the compiler to know how to add two
things - it doesn't work that way. First of all, provide some data to add.
And then tell the compiler, via code, how to add those things. Like this:

#include <iostream>
using namespace std;

class INT
{
public:
INT() {}
INT(int a) { datum = a;}
void show() {cout << "INT datum: " << datum << endl;}
INT operator+(INT rhs) { return datum + rhs.datum;}
private:
int datum;
};

int main()
{
INT a(7), b(5), c;
a.show();
b.show();
c = a + b; // default operator= is perfectly
// adequate for a shallow copy situation like this
c.show();
cin.get(); // crutch for my compiler
}

Get the fundamentals straight, THEN you can worry about const correctness,
reference vs. value, etc.


 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      01-17-2010
On Jan 17, 4:07 am, Immortal Nephi <(E-Mail Removed)> wrote:
> On Jan 16, 7:30 pm, Immortal Nephi <(E-Mail Removed)> wrote:


[...]
> I checked C++ Tutorial about operator+. The operator+ passes
> data by value and operator+= passes data by reference.


There's no such requirement in the standard, and in fact, it's
quite frequent that operator+ also passes data by (const)
reference.

If we're talking about design principles, instead of language
requirements, then a well designed operator+ should pass by
either value or const reference, and return a new value, whereas
a well designed operator+= should pass its first argument by
non-const reference, and modify it. But those are design
principles, and are not enforced in the language.

With regards to your initial question: a compiler is free to
warn about whatever it feels like, and no warning is ever
required. So if you're unhappy about the warnings you're
getting (and I suspect most of us are, from time to time), the
only thing you can do is complain to your compiler implementor.
(If it makes you feel any better, I sort of agree with you, and
I think a compiler could warn about such things. But I'm not a
compiler implementor, so my feelings on the question don't have
much weight. And there are concrete reasons, related to the way
compilers are implemented, why compilers don't do this.)

--
James Kanze
 
Reply With Quote
 
Öö Tiib
Guest
Posts: n/a
 
      01-18-2010
On Jan 17, 12:33*am, Immortal Nephi <(E-Mail Removed)>
wrote:
> * * * * I try to write operator= and operator+ in class. *The bult-in data
> type will report "warning C4552: '+' : operator has no effect;
> expected operator with side-effect" if my code shows this below.
>
> int main()
> {
> * * * * int x = 0;
> * * * * x + 1; // no effect
>
> }
>
> * * * * The C++ Compiler reports warning message. *It is correct because I
> should not write "x + 1;" *However you will see user-defined type like
> this below. *I do not want "t + t2;". *How can C++ Compiler report
> error message? *"t = t + t2;" and "t += t2" are acceptable.
>
> class test
> {
> public:
> * * * * test() {}
> * * * * ~test() {}
>
> * * * * test& operator=( const test &r )
> * * * * {
> * * * * * * * * return *this;
> * * * * }
>
> * * * * test& operator+( const test &r )
> * * * * {
> * * * * * * * * return *this;
> * * * * }
>
> };
>
> int main()
> {
> * * * * test t, t2;
>
> * * * * t + t2; // ???
> * * * * t = t + t2;
>
> * * * * return 0;
>
>
>
> }


I understand you want to make compiler to warn about usage of your
overloaded operators.
Compiler does not know how your operators are well-used. Compilers
must produce good executables quickly as their main goal.

Developer can sometimes use some special trick to detect the issue
runtime but it is time-consuming (detect if your return value from +
operator has been used for something before it was destroyed).

Better way is to use static code analyzing tools that check for such
and other issues that compilers ignore. For example in your case that
line of code has no side-effects. If you do not find a tool that
checks that particular issue (or more likely that particular issue
checking tool is too expensive to buy) then you may take an open
source static C++ code analyzing tool, implement such a check for it
and provide you patch to its maintainers.
 
Reply With Quote
 
Immortal Nephi
Guest
Posts: n/a
 
      01-18-2010
On Jan 17, 6:07*pm, Öö Tiib <(E-Mail Removed)> wrote:
> On Jan 17, 12:33*am, Immortal Nephi <(E-Mail Removed)>
> wrote:
>
>
>
>
>
> > * * * * I try to write operator= and operator+ in class. *The bult-in data
> > type will report "warning C4552: '+' : operator has no effect;
> > expected operator with side-effect" if my code shows this below.

>
> > int main()
> > {
> > * * * * int x = 0;
> > * * * * x + 1; // no effect

>
> > }

>
> > * * * * The C++ Compiler reports warning message. *It is correct because I
> > should not write "x + 1;" *However you will see user-defined type like
> > this below. *I do not want "t + t2;". *How can C++ Compiler report
> > error message? *"t = t + t2;" and "t += t2" are acceptable.

>
> > class test
> > {
> > public:
> > * * * * test() {}
> > * * * * ~test() {}

>
> > * * * * test& operator=( const test &r )
> > * * * * {
> > * * * * * * * * return *this;
> > * * * * }

>
> > * * * * test& operator+( const test &r )
> > * * * * {
> > * * * * * * * * return *this;
> > * * * * }

>
> > };

>
> > int main()
> > {
> > * * * * test t, t2;

>
> > * * * * t + t2; // ???
> > * * * * t = t + t2;

>
> > * * * * return 0;

>
> > }

>
> I understand you want to make compiler to warn about usage of your
> overloaded operators.
> Compiler does not know how your operators are well-used. Compilers
> must produce good executables quickly as their main goal.
>
> Developer can sometimes use some special trick to detect the issue
> runtime but it is time-consuming (detect if your return value from +
> operator has been used for something before it was destroyed).
>
> Better way is to use static code analyzing tools that check for such
> and other issues that compilers ignore. For example in your case that
> line of code has no side-effects. If you do not find a tool that
> checks that particular issue (or more likely that particular issue
> checking tool is too expensive to buy) then you may take an open
> source static C++ code analyzing tool, implement such a check for it
> and provide you patch to its maintainers.- Hide quoted text -


Thank you for explaining about operator overloading. Operator+ should
always return data by value. operator+= and operator= always return
data by reference.

After "C = B + A;" is read by C++ Compiler, operator+ is called and
data is returned by value before operator= is called and pass data by
value from operator+ and return it by reference.

You did post your words to state that operator+ should use data by
value only or do both data by value and data by reference on depend of
object design. Not a problem.

I know the difference between shadow copy and deep copy. Deep copy is
used if you create dynamic data array at run-time. Shadow copy should
be avoided because both objects cannot share dynamic data array or
memory leak will happen.

I read a book. The book is excellent. It explains everything like
you stated earlier. The title name is Objects, Abstraction, Data
Structures and Design using C++. Arthor's name Elliot B. Koffman and
Paul A.T. Wolfgang. ISBN 0-471-46755-3.

 
Reply With Quote
 
Thomas J. Gritzan
Guest
Posts: n/a
 
      01-18-2010
Am 18.01.2010 12:32, schrieb io_x:
> "io_x" <(E-Mail Removed)> ha scritto nel messaggio
> news:4b543a43$0$1114$(E-Mail Removed). ..
>> "osmium" <(E-Mail Removed)> ha scritto nel messaggio
>>
>> what about this?

>
> #include <iostream>
> using namespace std;
>
> class intc{
> public:
> int datum;


While it depends on class design and purpose, your member variables
should normally be private to ensure encapsulation.

> intc() {}
> intc(int a){datum=a;}


Make it explicit:

explicit intc(int a) { datum = a; }

You don't want your ints to be converted into intc instances by accident.

> void show() {cout << "intc datum: " << datum << endl;}
> // intc operator+(intc rhs) {return datum+rhs.datum;}
> intc& operator+(intc& rhs);
> intc& operator-(intc& rhs);
> intc& operator*(intc& rhs);
> intc& operator/(intc& rhs);
> friend ostream& operator<<(ostream& ost, intc& b)
> {ost << b.datum << flush; return ost;}


Don't flush the stream after every output of a value. It negates the
effect of buffering and kills performance.

> };
>
> unsigned index=0;
> intc v[16];
>
> intc& intc:perator-(intc& rhs)
> {unsigned u=index;
> v[u].datum=datum-rhs.datum;
> ++index; if(index==16) index=0;
> return v[u];
> }

[ same for operator+, *, / ]

What's wrong with the simple and standard approach?

intc operator+(intc const& rhs) const
{
return intc(datum + rhs.datum);
}
intc operator-(intc const& rhs) const
{
return intc(datum + rhs.datum);
}
/* [...] */

I expect return-by-value to be much faster in this case. It's easier to
understand and maintain than your code. And it is thread-safe.

--
Thomas
 
Reply With Quote
 
Richard Herring
Guest
Posts: n/a
 
      01-18-2010
In message <hj23jv$h2j$(E-Mail Removed)>, Thomas J. Gritzan
<(E-Mail Removed)> writes
>Am 18.01.2010 12:32, schrieb io_x:
>> "io_x" <(E-Mail Removed)> ha scritto nel messaggio
>> news:4b543a43$0$1114$(E-Mail Removed). ..
>>> "osmium" <(E-Mail Removed)> ha scritto nel messaggio
>>>
>>> what about this?

>>
>> #include <iostream>
>> using namespace std;
>>
>> class intc{
>> public:
>> int datum;

>
>While it depends on class design and purpose, your member variables
>should normally be private to ensure encapsulation.
>
>> intc() {}
>> intc(int a){datum=a;}

>
>Make it explicit:
>
>explicit intc(int a) { datum = a; }
>
>You don't want your ints to be converted into intc instances by accident.
>
>> void show() {cout << "intc datum: " << datum << endl;}
>> // intc operator+(intc rhs) {return datum+rhs.datum;}
>> intc& operator+(intc& rhs);
>> intc& operator-(intc& rhs);
>> intc& operator*(intc& rhs);
>> intc& operator/(intc& rhs);
>> friend ostream& operator<<(ostream& ost, intc& b)
>> {ost << b.datum << flush; return ost;}

>
>Don't flush the stream after every output of a value. It negates the
>effect of buffering and kills performance.


Besides, operator<< isn't the place to terminate lines. It should
follow the model of operator<<(ostream&, int) and do the minimum
necessary to stream a representation of the value. Layout issues like
newlines, other whitespace and punctuation are the responsibility of the
caller, and shouldn't be pre-empted by this operator.

--
Richard Herring
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
Equivalence in use of bitwise | operator and + operator Ioannis Vranos C++ 8 11-14-2008 11:03 PM
operator*(Foo) and operator*(int) const: ISO C++ says that these are ambiguous: Alex Vinokur C++ 4 11-26-2004 11:46 PM
Operator overloading on "default" operator John Smith C++ 2 10-06-2004 10:22 AM
Q: operator void* or operator bool? Jakob Bieling C++ 2 03-05-2004 04:27 PM



Advertisments