返回类型的重载操作符+表现出奇怪的行为

时间:2013-11-26 09:37:24

标签: c++ class debugging operator-overloading

我有一名班级员工

#include <iostream>
#include <string>
using namespace std;

class employee
{
    public:

            double operator + (employee);
            employee(int);
            double getSalary();

    private:

           double salary;

};

int main()
{  
  employee A(400);
  employee B(800);

  cout<<A+B;

  employee C = A+B;

  cout<<C.getSalary();

}

employee::employee(int salary)
{
    this->salary = salary;
}


double employee::operator + (employee e)
{
    double total;

    total = e.salary + this->salary;

    return total;    
}


double employee::getSalary()
{
    return this->salary;
}

我已经重载了运算符+,因此它增加了2个员工对象的工资。重载+运算符的返回类型是double。

这是我的问题

1)为什么employee C = A + B在我重载了运算符+以返回一个double而不是一个雇员时才有效,不应该有编译器错误?

2)实际发生了什么???

2 个答案:

答案 0 :(得分:5)

它有效,因为您已指定此构造函数:

employee(int);

虽然从double转换为int时会收到有关可能丢失数据的警告。因此,当编译器看到double时,它会检查是否有任何构造函数采用double参数。为了使它不起作用,请将构造函数指定为显式:

explicit employee(int);

答案 1 :(得分:5)

当您重载operator+以返回double时,编译器将查看它是否可以将double转换为employee对象。由于您的ctor采用int,因此会执行从doubleint的隐式转换,然后使用您的ctor从int转换为employee

所以不,这不应该生成编译器错误。

与此同时,它没有多大意义。现在,您已将employee的工资成员定义为double,但只允许用户指定int来初始化它。您可能希望允许使用double进行初始化。

就目前而言,您的operator+也有不对称行为:它可以对右操作数进行隐式转换,但不能在左侧进行,因此a + 1可以正常工作,但是1 + a没有。

您可以通过制作转换构造函数(即可以使用单个参数调用的所有内容)explicit来消除所有隐式转换。相反,您可以通过将重载实现为自由函数来允许对左操作数或右操作数进行隐式转换:

employee operator+(employee const &a, employee const &b) { 
    return employee(a.salary + b.salary);
}

由于salary是私有的,您将/必须将此运算符声明为该类的朋友才能使其工作。

您通常想要做这些或其中之一。如果隐式转换有意义,那么您可能希望在两个操作数上支持它们。如果它们没有意义,那么你可能想要完全禁止它们。中间地带 - +可以转换一个操作数而不是另一个操作数很少有意义。

然后再说一遍,我认为支持员工的补充无论如何都没有意义。对我(或者我认为大多数读者)来说,添加两个employee s会产生第三个employee对象,其中包含两个employee s'工资的总和,这一点不会立即显现出来,其余数据无效。事实上,我认为你可能根本不应该允许创建这样一个无效的employee对象。