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+vector
和 point +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 会在您的案例中发挥作用。
我想为 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+vector
和 point +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 会在您的案例中发挥作用。