Страницы

Поиск по вопросам

среда, 5 февраля 2020 г.

Когда вызывается оператор преобразования типов?

#преобразование #cpp


#include 
using 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); }

Комментариев нет:

Отправить комментарий