重载运算符时遇到的疑惑

为class重载运算符时出现的一些疑惑


#include <iostream>
using namespace std;

class Vector{
    private:
        double x;
        double y;
    public:
        Vector(double a = 0, double b = 0): x{a}, y{b} {}
        void print();
        double getx() const {return x;}
        double gety() const {return y;}
        
};

void Vector::print() {
    cout << "(" << x << "," << y << ")" << endl;
}

Vector operator+(const Vector& v1, const Vector& v2) {
    return Vector(v1.getx()+v2.getx(), v1.gety()+v2.gety());
}

以上代码创建了向量这种变量,并重载运算符+为向量加法
但是进行数字+向量 / 向量+数字的加法时,仍然可以调用只重载了向量+向量的加法运算
比如:

int main() {
  Vector u(1,2), v;
  v = u+3;
  v.print(); // 输出是:(4,2)
  return 0;
}

按理来说不应该会由于没有匹配的运算符而报错吗?为什么能正常运行呢?
希望得到解释,提前谢谢答者!

补:漏了一个关键信息,非常对不起。在我给构造函数加上默认值之前是会报错的,但是加上默认值之后就能正常运行了。

进行u + 3的计算时,编译器不会报错,因为已经在该行上实现了隐式类型转换。

如果在类中没有定义适当的运算符重载函数,则编译器将尝试使用隐式类型转换将一个数字转换为类对象。

因此,进行数字+向量 / 向量+数字的加法时,编译器将使用只重载了向量+向量的加法运算,并且结果是有效的。

如果禁止这种情况,则可以在类中定义适当的运算符重载函数,以在不合法的情况下抛出编译错误。

class Vector{
    private:
        double x;
        double y;
    public:
        Vector(double a = 0, double b = 0): x{a}, y{b} {}
        void print();
        double getx() const {return x;}
        double gety() const {return y;}
        Vector operator+(const Vector &rhs) const;
};
 
Vector Vector::operator+(const Vector &rhs) const {
    return Vector(x + rhs.x, y + rhs.y);
}

Vector operator+(double lhs, const Vector &rhs) {
    return Vector(lhs + rhs.getx(), lhs + rhs.gety());
}


你没贴全吧 没看到对operator +的重载啊

额,所以说你哪里重载了运算符呢?

在代码中仅实现了向量加向量的运算,而没有实现向量与数字的运算。因此,在代码 v = u + 3; 中,运算符不能识别 3,编译器会产生错误信息。要实现向量与数字的加法,需要实现相应的运算符重载,例如

Vector operator+(const Vector& v, double d) {
    return Vector(v.getx() + d, v.gety() + d);
}

在没有相应的运算符重载的情况下,代码是不能正常运行的,应该会因为没有匹配的运算符而报错。

以下答案引用自GPT-3大模型,请合理使用:

示例

这里的疑惑是运算符重载是如何匹配的?明明只重载了向量+向量的加法运算而不是数字+向量的加法运算,为什么还是能够通过?

其实C++的运算符重载是按照类型来匹配的,也就是说,当你重载了一个运算符时,C++会通过你的类型来匹配相应的运算符,如果有多个类型能够匹配,C++就会选择其中一个。

所以在上面的代码中,当我们调用v = u+3时,C++先通过Vector类型来匹配运算符+,然后再通过数字3来匹配运算符+,这样就能够成功的将向量u和数字3相加了。

如果你想要让C++选择其中一个类型来匹配,可以使用operator overload resolution(运算符重载解析)这个函数来控制,比如:

int main() {
  Vector u(1,2), v;
  // 这里的类型u和v都是Vector类型
 // 但是我们想要C++只选择向量+向量的加法运算
 v = u+3;
 // 使用operator overload resolution函数来控制
 using operator overload resolution = false;
 // 现在再调用v = u+3
 v = u+3;
}

这里的operator overload resolution = false表示只使用向量+向量的加法运算,也就是说,C++只选择向量+向量的加法运算来匹配运算符+。