-1

I'm trying to build a class complex,
and in the method conjugate I want the return statement to return the same object as the local variable res and not a copy of it.

#include <iostream>
#include <math.h>
using namespace std;

class complex
{
    float x, y;
    public: 
    complex(float x, float y);
    complex(float x) :complex(x, 0){}
    complex() :complex(0, 0){}
    complex(const complex &z) : complex(z.x, z.y) {}
    ~complex();

    complex &conjugate();

    friend ostream& operator<<(ostream&, const complex&);
};

ostream& operator<<(ostream& out, const complex& z){
    out << z.x << "+" << z.y << "i";
    return out;
}

complex::complex(float x, float y){
    cout << "complex number created.\n";
    this->x = x;
    this->y = y;
}

complex &complex::conjugate(){
    complex res;
    res.x = this->x;
    res.y = -this->y;
    cout << "res val: " << res << endl;
    cout << "res addr: " << &res << endl;
    return res;
}

int main(){ 
    complex a(1, 2);
    complex* c = &(a.conjugate());
    cout << "c val= " << *c << endl;
    cout << "c addr= " << c << endl;

    getchar();
    return 0;
}

Output:

complex number created.
complex number created.
res val: 1+-2i
res addr: 002CFA0C
c val: -1.07374e+008+-1.07374e+008i
c addr: 002CFA0C

*c and the local variable res have the same address but not the same value.

Could anyone explain to me why?

melpomene
  • 84,125
  • 8
  • 85
  • 148
user3870075
  • 141
  • 1
  • 3
  • 10

2 Answers2

0

You are returning a reference to a local variable that is about to be destroyed at the end of the function scope. That will not end well. Basically, the reference is useless since it refers to a destroyed object and using it is undefined - anything could happen, the code is broken.

melpomene
  • 84,125
  • 8
  • 85
  • 148
Jesper Juhl
  • 30,449
  • 3
  • 47
  • 70
0

res disappears after conjugate returns. You made what is called a dangling reference/pointer which is an error in the program. After you call conjugate again it makes a new variable res that happens to have the same address, but not the same value.

To solve this issue you can make res a static variable (static complex res;) so its lifetime persists past the end of the function.

nwp
  • 9,623
  • 5
  • 38
  • 68
  • 3
    On the other hand, it means that you have to copy out the result of the `conjugate` method before calling it again, so you're copying after all. Better would be to just return a copy and rely on RVO to optimize out the copy. – Raymond Chen Jul 02 '16 at 13:24