重载的运算符不适用于为其定义的类

时间:2019-09-09 22:49:26

标签: c++ class operator-overloading

我已经重载了运算符“-”来获取一个类的两个对象并输出一个新的对象,但是当我使用它时,例如。 obj3 = obj1-obj2,我收到一条错误消息,说没有运算符与这些操作数匹配。

vctmath.h内部的名称空间声明:

#ifndef VCTMATH
#define VCTMATH
namespace vctmath {
    Vect operator -(Vect a, Vect b);
}
#endif

主vctmath文件中的定义;

#include "Vect.h"
#include "vctmath.h"
Vect vctmath::operator -(Vect a, Vect b) {
    Vect output(0);
    output.SetX(a.GetX() - b.GetX());
    return output;
}

这是Vect.h文件中的类声明

#ifndef VECT
#define VECT

class Vect {
private:
    float x;
public:
    Vect(float);
    const float GetX(void);
    void SetX(float a);
};
#endif

这是Vect.cpp中Vect的定义:

#include "Vect.h"
#include "vctmath.h"

Vect::Vect(float a): x(a) {}
const float Vect::GetX(void) { return x; };
void Vect::SetX(float a) {
    x = a;
}

main函数创建Vect类的两个对象,然后尝试使用新近重载的-运算符:

#include "Vect.h"
#include "vctmath.h"
int main() {
    Vect vect1(0);
    Vect vect2(1);
    Vect vect3 = vect1 - vect2; //this is where the problem is
    return 0;
}

错误是E0349;没有运算符“-”与这些操作数匹配, 操作数类型为Vect-Vect。

2 个答案:

答案 0 :(得分:2)

Argument-dependent lookup不会在随机名称空间中搜索全局名称空间中类型的运算符重载。

Vectvctmath名称空间之间没有关系,因此编译器无法找到您要使用的重载。

您可以:

  • 在使用运算符之前先打开名称空间:using namespace vctmath
  • Vect移至名称空间
  • 将运算符定义为成员方法Vect::operator-

答案 1 :(得分:-1)

不清楚如何定义Vect。显然,在代码中,您表明问题出在名称空间内名称的可见性上。建议您在使用命名空间中定义的类时明确使用命名空间名称。

我建议您更改Vector.h(以及相应的.cpp):

... 
namespace vctmath {
    class Vect {
    ...
    };       
} // namespace vctmath
....

main.cpp

int main() {
    vctmath::Vect vect1(0);
    vctmath::Vect vect2(1);
    Vect vect3 = vect1 - vect2;
    return 0;
}

如果由于某种原因您不想将Vect放入命名空间,则可以使用其他选项: a)明确地呼叫接线员:

Vect vect3 = vctmath::operator-(vect1, vect2);

b)使用适配器设计模式:

Vect operator -(Vect& a, Vect& b) {
    return vctmath::operator-(a, b);
}

int main() {
    Vect vect1(0);
    Vect vect2(1);
    Vect vect3 = vect1 - vect2;
    return 0;
}