How to use operator overloading?

I

Immortal Nephi

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;
}
 
O

osmium

:

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".
 
I

Immortal Nephi

:



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".

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

Immortal Nephi

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...
 
O

osmium

Immortal said:
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.
 
J

James Kanze

On Jan 16, 7:30 pm, Immortal Nephi <[email protected]> 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.)
 
Ö

Öö Tiib

        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.
 
I

Immortal Nephi

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.
 
T

Thomas J. Gritzan

Am 18.01.2010 12:32, schrieb io_x:
#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::eek:perator-(intc& rhs)
{unsigned u=index;
v.datum=datum-rhs.datum;
++index; if(index==16) index=0;
return v;
}

[ 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.
 
R

Richard Herring

Thomas J. Gritzan said:
Am 18.01.2010 12:32, schrieb io_x:

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


Make it explicit:

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

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


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.
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top