#преобразование #cpp
#includeusing namespace std; 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+? Ведь тут два объекта с обоих сторон, почему тогда вызывается функция преобразования или как оно там называется, да ещё и в конце?
Ответы
Ответ 1
Проблема в том, что ваш объект суммы не 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); }
Комментариев нет:
Отправить комментарий