How to use operator overloading?

Discussion in 'C++' started by Immortal Nephi, Jan 16, 2010.

  1. 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;
    }
     
    Immortal Nephi, Jan 16, 2010
    #1
    1. Advertising

  2. Immortal Nephi

    osmium Guest

    "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".
     
    osmium, Jan 17, 2010
    #2
    1. Advertising

  3. On Jan 16, 7:05 pm, "osmium" <> 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...
     
    Immortal Nephi, Jan 17, 2010
    #3
  4. On Jan 16, 7:30 pm, Immortal Nephi <> wrote:
    > On Jan 16, 7:05 pm, "osmium" <> 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...
     
    Immortal Nephi, Jan 17, 2010
    #4
  5. Immortal Nephi

    osmium Guest

    Immortal Nephi wrote:

    > On Jan 16, 7:05 pm, "osmium" <> 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.
     
    osmium, Jan 17, 2010
    #5
  6. Immortal Nephi

    James Kanze Guest

    On Jan 17, 4:07 am, Immortal Nephi <> wrote:
    > On Jan 16, 7:30 pm, Immortal Nephi <> 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
     
    James Kanze, Jan 17, 2010
    #6
  7. Immortal Nephi

    Öö Tiib Guest

    On Jan 17, 12:33 am, Immortal Nephi <>
    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.
     
    Öö Tiib, Jan 18, 2010
    #7
  8. On Jan 17, 6:07 pm, Öö Tiib <> wrote:
    > On Jan 17, 12:33 am, Immortal Nephi <>
    > 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.
     
    Immortal Nephi, Jan 18, 2010
    #8
  9. Am 18.01.2010 12:32, schrieb io_x:
    > "io_x" <> ha scritto nel messaggio
    > news:4b543a43$0$1114$...
    >> "osmium" <> 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::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.

    --
    Thomas
     
    Thomas J. Gritzan, Jan 18, 2010
    #9
  10. In message <hj23jv$h2j$>, Thomas J. Gritzan
    <> writes
    >Am 18.01.2010 12:32, schrieb io_x:
    >> "io_x" <> ha scritto nel messaggio
    >> news:4b543a43$0$1114$...
    >>> "osmium" <> 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
     
    Richard Herring, Jan 18, 2010
    #10
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. John Smith
    Replies:
    2
    Views:
    453
    Ivan Vecerina
    Oct 6, 2004
  2. Replies:
    11
    Views:
    770
    James Kanze
    May 16, 2007
  3. hurcan solter
    Replies:
    3
    Views:
    760
    Cholo Lennon
    Aug 29, 2007
  4. Replies:
    11
    Views:
    587
  5. Replies:
    2
    Views:
    337
Loading...

Share This Page