Reputation: 382
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
.
Upvotes: 3
Views: 247
Reputation: 44023
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.
Upvotes: 2