0
class point
{
private:
    double x,y;
public:
    point(double x=0.0, double y=0.0)
    {
        this->x=x;
        this->y=y;
    }

    point operator++()
    {
        this->x=this->x+1.0;
        this->y=this->y+1.0;
        return *this;
    }

    point& operator++(int)
    {
        point p=point(this->x, this->y);
        ++(*this);
        return p;

    }

    ostream& operator<< (ostream& o)
    {
        o << "X: " << this->x << endl << "Y: " << this->y;
        return o;
    }

    friend ostream& operator<< (ostream& o,point p)
    {
        o << "X: " << p.x << endl << "Y: " << p.y;
        return o;
    }
};


int main()
{
  point p = point();
  p++ << cout << endl; // first output
  cout << p++ << endl;// second output
}

I don't understand why the first output is incorrect (X: 6.95333e-310 Y: 6.95322e-310), while the second one is correct (X: 1 Y: 1).

And why this problem is solved by removing & at the end of the return value of the post-increment operator?

KelvinS
  • 2,870
  • 8
  • 34
  • 67
Angelo
  • 334
  • 4
  • 14
  • 3
    Because `p` goes out of scope and is destroyed resulting undefined behavior when you attempt to access the not dead referenced object. [Get a good book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) and read it while I search for a dupe. – Captain Obvlious Aug 31 '17 at 19:42
  • 2
    Because `point operator++()` should be `point & operator++()` and `point & operator++(int )` should be `point operator++(int )` and much more... Turn on compiler's warnings. – pmaxim98 Aug 31 '17 at 19:46
  • 3
    As noted prior, the problem is your code invoking *undefined behavior*. The actual *solution* is to *not* do that (duh), but a likely helpful solution than that will be found in the frequently sited general post on this site about [The Basic Rules and Idioms about operator overloading](https://stackoverflow.com/questions/4421706/what-are-the-basic-rules-and-idioms-for-operator-overloading), specifically the note on common unary operators such as pre and post increment/decrement. Maybe take a look at that. – WhozCraig Aug 31 '17 at 19:55
  • @WhozCraig thank you , I wanted to know why with the other signature I don t have the undefined behavior (ok even if it is incorrect) – Angelo Aug 31 '17 at 20:10
  • @pmaxim98 thank you but I use CLion and it didn't warn me. – Angelo Aug 31 '17 at 20:17

1 Answers1

4

When you return a reference to a local variable, using that reference is undefined behavior.

Your compiler should be warning you about it. If it is not, increase your compiler warning level, and pay attention to the warnings.

point& operator++()
point operator++(int)

are the correct return values.

The rest of your code appears fine.

I would remove using namespace std;, and change the implementation of ++ to be:

    ++x;
    ++y;
    return *this;
Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
  • 1
    @neo yes, that is undefined behavior. – Yakk - Adam Nevraumont Aug 31 '17 at 20:27
  • thank you . My 'silly- question' is due to the fact the even if it is undefined behavior the output was correct.(PS: the code mentioned above is : int& foo(int x) { int c=3; return c; } void main(){cout< – Angelo Aug 31 '17 at 20:31
  • @Neo not so silly, but the answer may not be all that helpful. That the output was correct is of no significance. Once your code invokes undefined behavior *anything* is possible, and *anything* includes something that appears correct. That it is *not* guaranteed to be so is the very meat of undefined behavior, because in fact, it isn't guaranteed to do *anything*. It may work, it may not. Don't confuse observed behavior with defined behavior. The latter always leads to the former, but they are not synonymous, and assuming the former means the latter is *never* a good idea. – WhozCraig Aug 31 '17 at 21:54
  • @WhozCraig thank you , the output correct as well as being not helpful is misleading – Angelo Aug 31 '17 at 23:43