C ++中运算符重载的参数数量

时间:2013-03-15 20:34:40

标签: c++ operator-overloading

我正在学习C ++,我创建了两个简单的hello-world应用程序。在他们两个中我使用运算符重载,但这是问题所在。在第一个,我可以为重载运算符提供两个参数,这很好。

标题

enum Element {a,b,c,d,e};
Element operator + (Element x, Element y);
//more overloads for -, *, / here

来源:

Element operator + (Element x, Element y) {
    return ArrayOfElements[x][y];
}

但是在我的第二个应用程序(简单的复数计算器)中 - 这种方法不起作用。在谷歌搜索并弄清楚原因之后,我最终得到了这段代码:

标题

struct Complex {
        double Re;
        double Im;

        Complex (double R, double I) : Re(R), Im(I) { }

        Complex operator + (Complex &Number);
        //more overloads
    };

来源:

Complex Complex::operator + (Complex &Number)
    {
        Complex tmp = Complex(0, 0);
        tmp.Re = Re + Number.Re;
        tmp.Im = Im + Number.Im;
        return tmp;
    }

它现在正在运行,但我想知道,为什么在第一段代码中我被允许在operator重载中放入两个参数,但是第二个我被赋予了以下错误?

complex.cpp:5:51: error: 'Complex Complex::operator+(Complex, Complex)' must take either zero or one argument

每当我使用课程时都是一样的。我一直在寻找许多文档,第二种方式似乎更正确。也许是因为不同的论证类型?

使用-Wall -pedantic使用g++参数编译的两个源都使用相同的库。

5 个答案:

答案 0 :(得分:29)

假设你有一个这样的类:

class Element {
public:
    Element(int value) : value(value) {}
    int getValue() const { return value; }
private:
    int value;
};

定义二元运算符有四种方法,例如+

  1. 作为免费功能,只能访问班级的public成员:

    // Left operand is 'a'; right is 'b'.
    Element operator+(const Element& a, const Element& b) {
        return Element(a.getValue() + b.getValue());
    }
    

    e1 + e2 == operator+(e1, e2)

  2. 作为会员功能,可以访问班级的所有成员:

    class Element {
    public:
        // Left operand is 'this'; right is 'other'.
        Element operator+(const Element& other) const {
            return Element(value + other.value);
        }
        // ...
    };
    

    e1 + e2 == e1.operator+(e2)

  3. 作为friend函数,可以访问该类的所有成员:

    class Element {
    public:
        // Left operand is 'a'; right is 'b'.
        friend Element operator+(const Element& a, const Element& b) {
            return a.value + b.value;
        }
        // ...
    };
    

    e1 + e2 == operator+(e1, e2)

  4. 作为在类体外定义的friend函数 - 与#3的行为相同:

    class Element {
    public:
        friend Element operator+(const Element&, const Element&);
        // ...
    };
    
    Element operator+(const Element& a, const Element& b) {
        return a.value + b.value;
    }
    

    e1 + e2 == operator+(e1, e2)

答案 1 :(得分:4)

由于+是二元运算符,如果在结构/类中重载它,则只能提供一个操作数,原因是第一个操作数隐式地是调用对象。这就是为什么在第一种情况下,你有两个参数,因为它在你的类/结构的范围之外,而在第二种情况下,它被重载为成员函数。

答案 2 :(得分:3)

如果您希望operator+将两个操作数作为显式参数,则必须将其定义为自由(即非成员)函数:

class Complex {
    friend Complex operator+(const Complex& lhs, const Complex& rhs);
}

Complex operator+(const Complex& lhs, const Complex& rhs) {
    ...
}

如果左操作数是基本类型,或者是您不控制的类(因此无法添加成员函数),则 使用此表单。< / p>

答案 3 :(得分:1)

如果重载函数是类的成员函数,我们只传递一个参数,并且有一个隐藏参数( this 指针)指向执行二进制操作所需的其他对象,如& #39; +&#39 ;. 指针指向其中一个操作数并调用重载函数;而其他操作数作为参数传递。 例如:

class ExampleClass
{
public:
   int x;
   //a this pointer will be passed to this function
   ExampleClass& operator+(const ExampleClass& o){ return x+o.x; }
};



ExampleClass obj1, obj2, obj;
obj = obj1 + obj2; //the overloaded function is called as obj1.operator+(obj2) internally
                  //this pointer is passed to the function

当重载函数不是成员函数(自由函数或朋友函数)时,我们不会将 this 指针提供给重载函数。在这种情况下,编译器需要函数的两个参数作为操作数。

class ExampleClass
{
    public:
       int x;
       //this pointer will not be passed to this function
       friend ExampleClass& operator+(const ExampleClass& o1, const ExampleClass& o2){ return o1.x+o2.x; }
};



obj = obj1 + obj2; //the overloaded function is called as operator+(obj1, obj2) internally

答案 4 :(得分:0)

e1 + e2 == e1.operator +(e2)这意味着e1是一个对象,运算符+是一个成员而e2是一个变量.basicaly oops允许我们只写e1 + e2编译器自动理解为e1。操作者+(E1)