Проблема в том, что ваш оператор вставки потока определен как
friend ostream& operator << (ostream &, COMPLEX &);
Принимает неконстантную ссылку на объект COMPLEX
в качестве второго параметра. Когда вы пытаетесь написать
cout << a + b << endl;
Значение a + b
представляет собой rvalue , а не lvalue , поскольку это значение, возвращаемое функцией operator +
. В C ++ вы не можете привязать ссылку к r-значению, так как тогда вы могли бы делать плохие вещи следующим образом:
COMPLEX& c = a + b; // This step isn't legal
c = 137; // Wait, what object did we just change?
Проблема здесь в том, что если мы можем связать ссылку c
с временным объектом, возвращаемым a + b
, то мы могли бы использовать ссылку для внесения изменений в этот объект. Но это не имеет никакого смысла - a + b
- это значение выражения, а не фактического объекта.
Это та же проблема, что и здесь. Ваша operator <<
функция не может принимать a + b
в качестве второго параметра, поскольку a + b
является значением.
Чтобы исправить это, вы можете изменить operator <<
на const
ссылку на КОМПЛЕКС:
friend ostream& operator<< (ostream& out, const COMPLEX& c);
Это работает, потому что в C ++ вы можете связывать константные ссылки с r-значениями. Это объясняется тем, что если у вас есть постоянная ссылка на временный объект, вы не можете вносить какие-либо изменения в этот временный объект, поэтому приведенный выше пример с привязкой ссылки к a + b
больше не является проблемой.
Как правило, любой перегруженный оператор, принимающий параметр, тип которого является другим экземпляром класса, который не изменяет этот экземпляр, должен принимать свой параметр по константной ссылке. Это относится к таким вещам, как operator =
, operator +
и т. Д., Поскольку позволяет избежать этой проблемы.