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

Com*_*erd 2 c++ debugging class 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;
}
Run Code Online (Sandbox Code Playgroud)

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

这是我的问题

1)为什么employee C = A + B在我重载操作符+返回双重而不是员工时工作,不应该有编译器错误?

2)究竟发生了什么?

ben*_*alj 5

它的工作原理是因为你指定了这个构造函数:

employee(int);
Run Code Online (Sandbox Code Playgroud)

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

explicit employee(int);
Run Code Online (Sandbox Code Playgroud)


Jer*_*fin 5

当您重载operator+以返回double时,编译器将查看它是否可以将其转换doubleemployee对象.既然你有一个构造函数,它接受一个int,它从隐式转换doubleint,然后使用您的男星,从转换intemployee.

所以不,那不应该生成编译器错误.

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

就目前看来,你operator+也有不对称的行为:它可以对右操作数进行隐式转换,但不能在左边进行,因此a + 1有效,但1 + a不行.

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

employee operator+(employee const &a, employee const &b) { 
    return employee(a.salary + b.salary);
}
Run Code Online (Sandbox Code Playgroud)

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

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

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