3

I want to overload + for Point+Point and Point+vector

class Vector
{
public:
    double x;
    double y;
    double z;
};

class  PointBase
{
public:

    double x;
    double y;
    double z;

        PointBase operator+(const Vector &vec) const
        {
            PointBase b;
            b.x=vec.x+this->x;
            b.y=vec.y+this->y;
            b.z=vec.z+this->z;
            return b;

        }
};

class  Point:public PointBase
{
public:
    PointBase operator+(const Point &point) const
    {
        PointBase b;
        b.x=point.x+this->x;
        b.y=point.y+this->y;
        b.z=point.z+this->z;
        return b;
    }
    Point(PointBase& base)
    {
    }
    Point()
    {
    }
};

int main()
{
    Point  p;
    Vector v;
    p=p+v;
    return 0;
}

PointBase operator+(const Point &point) const hides PointBase operator+(const Vector &vec) const, why? I expect that 2 overloads work correctly: point+vector and point +point.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
jalal sadeghi
  • 362
  • 4
  • 19
  • 1
    What's the point of the `PointBase` class? A class like `Point` does not sound like it should derive from anything. – Christian Hackl Feb 22 '15 at 10:06
  • Consider putting the operator into the surrounding namespace instead of making it a member function. This is also the only way to implement operators where the left operand is a builtin type, like e.g. `operator*` for `float` and `Vector`. – Ulrich Eckhardt Feb 22 '15 at 10:27

1 Answers1

2

The operator+ in Point hides the one inherited from PointBase. To make it available, use

class  Point:public PointBase
{
public:
  using PointBase::operator+;  // <-- here

  PointBase operator+(const Point &point) const

  // rest as before

Note, however, that the next problem you'll run into is that

p=p+v

attempts to use an operator= that takes a Point on the left and a PointBase on the right and that does not exist.

The reason that the operator+ in the derived class hides the one in the base class is the way name lookup works in C++: The compiler goes outward in layers (concrete class -> base class -> base base class -> ..., and for non-member functions called from a member function continues through the surrounding namespaces1) until it finds a matching name, tries to apply it, and fails if that doesn't work. You can see the same mechanism at work in this non-compiling piece of code:

void foo(char const *) { }

namespace bar {
  void foo(int) { }

  void baz() {
    // does not compile: bar::foo hides ::foo
    foo("hello");
  }
}

In the case of your classes, the compiler looks in Point, finds a matching name, tries to apply it, and complains when it fails. It does not continue to look in the surrounding scope (PointBase), but it would continue to look if it had not found the operator+ in Point.

1 There's an asterisk for class templates that inherit other class templates here, where different mechanisms come into play. See Why do I have to access template base class members through the this pointer? for details, although none of that comes into play in your case.

Wintermute
  • 42,983
  • 5
  • 77
  • 80