1

I have a class:

class Point3D : public Point{
    protected:
        float x;
        float y;
        float z;

    public:
        Point3D(){x=0; y=0; z=0;}
        Point3D(const Point3D & point){x = point.x; y = point.y; z = point.z;} 
        Point3D(float _x,float _y,float _z){x = _x; y = _y; z = _z;}

        inline const Point3D operator+(const Vector3D &);

        const Point3D & operator+(const Point3D &point){
            float xT = x + point.getX();
            float yT = y + point.getY();
            float zT = z + point.getZ();
            return Point3D(xT, yT, zT);
        }
...

When I use it that way:

Point3D point = Point3D(10,0,10);

Everything works fine.

When I write:

Point3D point = Point3D(10,0,10);
Point3D point2 = Point3D(0,0,0) + point();

Also it's ok (point2 = point). When I add something more than (0,0,0) it's also working.

But when I want just to:

Point3D point = Point3D(10,0,10);
someFunction( Point3D(0,0,0) + point ); //will get strange (x,y,z)

The function get value of some (in my opinion) random (x,y,z). Why?

What's even stranger, in that similar example everything will be working again:

Point3D point = Point3D(10,0,10);
Point3D point2 = Point3D(0,0,0) + point;
someFunction( point2 );  // will get (10,0,10)

What's the reason for that strange behaviour?

PolGraphic
  • 3,233
  • 11
  • 51
  • 108

3 Answers3

4

The operator+() is returning a dangling reference, the returned reference is referring to a Point3D instance that is destroyed when operator+() returns. Change to:

Point3D operator+(const Point3D &point) const {

so a copy is returned, and make it const as it has no reason to be changing anything.

hmjd
  • 120,187
  • 20
  • 207
  • 252
3

The typical pattern for classes that support arithmetic operators is

class Foo
{
public:
  Foo & operator+=(Foo const & rhs) { /* ... */ return *this; }
  Foo & operator-=(Foo const & rhs) { /* ... */ return *this; }
  Foo & operator*=(Foo const & rhs) { /* ... */ return *this; }
  Foo & operator/=(Foo const & rhs) { /* ... */ return *this; }
};

Foo operator+(Foo const & lhs, Foo const & rhs) { return Foo(lhs) += rhs; }
Foo operator-(Foo const & lhs, Foo const & rhs) { return Foo(lhs) -= rhs; }
Foo operator*(Foo const & lhs, Foo const & rhs) { return Foo(lhs) *= rhs; }
Foo operator/(Foo const & lhs, Foo const & rhs) { return Foo(lhs) /= rhs; }
MadScientist
  • 3,390
  • 15
  • 19
  • +1 operator + should be a free function implemented in terms of += member; though it's better to make it return const Foo so one cannot write nonsense like ( A + B ) = C; – stijn Jul 05 '12 at 09:08
2

You are returning a reference to a local variable from operator+ which will get invalidated once the function returns, you need to return a copy of the Point3D created.

Asha
  • 11,002
  • 6
  • 44
  • 66