#cpp
Изучаю язык. Написал простенький класс: class Point{ public: Point(); Point(int x, int y); private: int _x; int _y; } Захотел преобразовать его в другой тип. По не знанию и паскалевской привычки написал такой оператор: int operator=(const Point& src); Скомпилировал класс вместе с оператором и все нормально скомпилировалось. Решил проверить на коде: int main(int argc, char *argv[]) { Point pt(1, 2); int i; i = pt; } Компиляция не удалась: main.cpp:14: ошибка: cannot convert 'Point' to 'int' in assignment Потом я нашел как преобразовать тип через другой оператор. Но мне интересно, раз компилятор дал мне скомпилировать этот оператор, значит наверно его, как то можно применить. Вопрос: Что это оператор делает и как его можно использовать?
Ответы
Ответ 1
Надо различать оператор присвоения и функцию преобразования. Оператор присвоения не меняет тип объекта, которому присваивается выражение. В вашем примере class Point{ public: //... int operator=(const Point& src); //... }; оператор присваивания присваивает выражение объекту класса Point. Причем присваиваемое выражение имеет также ссылочный тип класса Point. Вы можете использовать возвращаемое значение выражения с данным оператором присваивания, чтобы присвоить его переменной типа int. Например, int main(int argc, char *argv[]) { Point pt(1, 2); int i; i = pt = pt; } Так как операторы присваивания выполняются справа налево, то сначала бы выполнилось присваивание pt = pt результатом которого было бы значение типа int, и только во втором присваивании это значение было бы занесено в переменную i Если же вы хотите написать оператор преобразования, то он может выглядеть следующим образом: operator int() const; И тогда вы можете записать i = pt; Имейте в виду, что для не пользовательских типов вы не можете переопределить оператор присваивания. И в этом предложении i = pt; используется стандартное присваивание для целых чисел. Но так как pt не имеет целочисленный тип, то компилятор пытается его преобразовать к объекту целочисленного типа и вызывает для pt оператор operator int() const; если вы его определили. Иначе компилятор выдаст сообщение об ошибке.Ответ 2
Когда вы пишете a = b, это транслируется как a.operator=(b). То есть, для вашего случая (i = pt) вам нужно бы перегрузить оператор присваивания у i, в типе данных int. Это, очевидно, невозможно. Правильный путь — оператор преобразования типов operator int() const. Заметьте, что другие, сложные операторы присваивания вполне можно перегрузить и вне класса-получателя. Например, operator += (пример): class Point { public: Point() : _x(), _y() {} Point(int x, int y) : _x(x), _y(y) {} friend int& operator += (int& i, const Point& pt) { i += pt._x; i += pt._y; return i; } private: int _x; int _y; };Ответ 3
Интересно то, что никто так и не показал как реализовать оператор присваивания... class Point { public: Point(); Point( int x, int y ); Point & operator = ( const Point & rhs ) { if ( &rhs != this ) { _x = rhs._x; _y = rhs._y; } return *this; } private: int _x; int _y; };Ответ 4
Выше все ответили правильно. Забавно, что если использовать Ваше описание класса Point, то можно написать следующее: Point x(1, 2); Point y(3, 4); int i = y = x; И в i останется то, что Вы хотели получить. class A { public: A(int v) {this->v = v;} A(const A &a) { v = a.v; } int operator= (const A &a) { this->v = a.v; return v; } private: int v; }; int main(int argc, char *argv[]) { A x(1); A y(2); int i = y = x; cout << i; } выводит как раз 1
Комментариев нет:
Отправить комментарий