C++ 运算符重载或重新定义?

C++ operator overloading or redefine?

我想为 Point+Point 和 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隐藏了PointBase operator+(const Vector &vec) const,为什么?我希望 2 个重载可以正常工作:point+vectorpoint +point.

Point中的operator+隐藏了继承自PointBase的那个。要使其可用,请使用

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

  PointBase operator+(const Point &point) const

  // rest as before

但是请注意,您将 运行 遇到的下一个问题是

p=p+v

尝试使用一个 operator=,它在左边有一个 Point,在右边有一个 PointBase,但不存在。

派生 class 中的 operator+ 隐藏了基础 class 中的 class 的原因是名称查找在 C++ 中的工作方式:编译器分层向外(具体class -> base class -> base base class -> ...,对于从成员函数调用的非成员函数,继续通过周围的命名空间1 ) 直到找到匹配的名称,尝试应用它,如果不起作用则失败。您可以在这段非编译代码中看到相同的机制:

void foo(char const *) { }

namespace bar {
  void foo(int) { }

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

对于您的 classes,编译器会查找 Point,找到一个匹配的名称,尝试应用它,并在失败时抱怨。它不会继续在周围范围 (PointBase) 中查找,但如果在 Point.

中没有找到 operator+,它会继续查找

1 这里有一个星号表示 class 模板继承了其他 class 模板,其中不同的机制发挥作用。有关详细信息,请参阅 Why do I have to access template base class members through the this pointer?,但其中 none 会在您的案例中发挥作用。