2013-11-26 3 views
2

У меня есть сотрудник классавозвращаемого типа перегрузка оператора + демонстрирует странное поведение

#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 объектов для сотрудников. Тип возврата перегруженного + оператора двойной.

Это мой вопрос

1) Почему employee C = A + B работа, когда я перегружен оператор + для возврата двойной, а не работник, не должен ли быть ошибка компилятора ??

2) что на самом деле происходит ???

ответ

5

При перегрузке operator+ для возврата двойной, компилятор будет смотреть на сможет ли она, что double к employee объекта. Поскольку у вас есть ctor, который принимает int, он делает неявное преобразование от double до int, а затем использует ваш 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.

5

Это работает, потому что вы задали этот конструктор:

employee(int); 

Хотя вы получите предупреждение о возможной потере данных при преобразовании из двойной Int. Поэтому, когда компилятор видит double, он проверяет наличие конструктора с двойным параметром. Для того, чтобы не работать указать ваш конструктор как явные:

explicit employee(int); 
Смежные вопросы