#include
class three_d {
int x, y, z;
public:
three_d(int a, int b, int c) {x=a; y=b, z=c; }
three_d operator+(three_d op2);
friend ostream &operator<<(ostream &stream, three_d &obj);
operator int() {return x*y*z;}
};
ostream &operator<< (ostream &stream, three_d &obj)
{
stream << obj.x << ", ";
stream << obj.y << ", ";
stream << obj.z << endl;
return stream;
}
three_d three_d::operator+ (three_d op2)
{
x+=op2.x;
y+=op2.y;
z+=op2.z;
return *this;
}
int main()
{
three_d a(1, 2, 3), b(2, 3, 4);
cout << a << b;
cout << b+100 << endl; //31 line
cout << a+b << endl; // 32
system("pause");
return 0;
}
В 31 строчке объект b приводится к int, потому что справа значение int, но зачем в 32 строчке привидении работает после того как выполнился operator+? Ведь тут два объекта с обоих сторон, почему тогда вызывается функция преобразования или как оно там называется, да ещё и в конце?
Ответ
Проблема в том, что ваш объект суммы не lvalue. Для него нужно const
friend ostream &operator<<(ostream &stream, const three_d &obj);
Без const cout << a+b трактуется не как
operator<<(cout, a+b) // ostream &stream, three_d &obj
а как
operator<<(cout, (int)(a+b)) // ostream &stream, const int& i
Объект, не являющийся lvalue, не может быть использован с не-const-ссылкой.
Смотрите, что происходит.
Компилятор пытается понять, что же ему вызывать для выражения cout << a + b
Поскольку a + b -- не lvalue, то ostream &operator<< (ostream &stream, three_d &obj) отпадает. Раз так, компилятор смотрит, как он может преобразовать аргументы, чтобы другие функции подошли.
Компилятор пробует известные ему операторы <<. Когда он пробует ostream &operator<< (ostream &stream, const int &i), он видит, что можно использовать этот оператор, если преобразовать второй аргумент в int. Поскольку вы предоставили преобразование, этот вариант проходит.
Отдельно от темы: ваш оператор сложения -- ужас! Вы модифицируете первое слагаемое!
Представьте себе, если бы сложение чисел вело себя так:
int a = 5;
int b = 7;
int c = a + b;
// здесь внезапно a == 12
Ваш код ведёт себя именно так.
Вот как надо:
three_d three_d::operator+ (three_d op2)
{
return three_d(x + op2.x, y + op2.y, z + op2.z);
}
Комментариев нет:
Отправить комментарий