Неявное преобразование в пользовательские типы
Подскажите, плиз, что не так:
class Complex
{
double Re, Im;
public
Complex()
{Re=0; Im=0};
Complex(double r)
{ Re=r; Im=0;};
operator+(Complex&);
operator-(Complex&);
operator*(Complex&);
operator/(Complex&);
...
}
Во все книжках написано, что должны выполняться следующие выражения:
Complex a;
a=a*0.1+0.1; // и т.д.
По идее должно происходить неявное преобразование типа double в Complex, но этого не происходит!? Получается только так: a=0.1;
А если так, то
a=a+0.1; // [C++ Error] Unit1.cpp(55): E2094 'operator+' not implemented in type 'Complex' for arguments of type 'double'
a=0.1*a; // [C++ Error] Unit1.cpp(55): E2096 Illegal structure operation
Вроде и конструктор для преобразования есть и все операторы, пробовал и friend Complex operator(Complex&, Complex&), результат тот же. Я в замешательстве :)
Заранее СПАСИБО!
{
double Re, Im;
public
Complex()
{Re=0; Im=0};
Complex(double r)
{ Re=r; Im=0;};
operator+(Complex&[color=red],Complex&[/color]);
operator-(Complex&[color=red],Complex&[/color]);
operator*(Complex&[color=red],Complex&[/color]);
operator/(Complex&[color=red],Complex&[/color]);
...
}
operator+(Complex&[color=red],Complex&[/color]);
operator-(Complex&[color=red],Complex&[/color]);
operator*(Complex&[color=red],Complex&[/color]);
operator/(Complex&[color=red],Complex&[/color]);
...
}
Переписал:
friend Complex operator+(Complex&,Complex&);
friend Complex operator-(Complex&,Complex&);
friend Complex operator*(Complex&,Complex&);
friend Complex operator/(Complex&,Complex&);
...
Ничего не изменилось, те же ошибки!
Переписал:
friend Complex operator+(Complex&,Complex&);
friend Complex operator-(Complex&,Complex&);
friend Complex operator*(Complex&,Complex&);
friend Complex operator/(Complex&,Complex&);
...
Ничего не изменилось, те же ошибки!
'operator+' not implemented in type 'Complex' for arguments of type 'double':
По русски это означает что для оператора + типа "Complex" не определен аргумент типа "double". Отсюда - решение проблемы элементарное - определи оператор + где одним из аргумкентов будет переменная типа "double". А именно так:
friend Complex operator+(Complex&,double&);
friend Complex operator-(Complex&,double&);
friend Complex operator*(Complex&,double&);
friend Complex operator/(Complex&,double&);
...
'operator+' not implemented in type 'Complex' for arguments of type 'double':
По русски это означает что для оператора + типа "Complex" не определен аргумент типа "double". Отсюда - решение проблемы элементарное - определи оператор + где одним из аргумкентов будет переменная типа "double".
[/code]
Спасибо за комментарий!
Дело в том, что я хочу добиться именно АвтоматическогО преобразования. Для этого вроде как достаточно написать конструктор с одним формальным параметром, с типом из которого хочешь произвести преобразование. В 3 книгах так написано.
Я скоро лопну от любопытства. Что не ТАК!?!?!
Спасибо за комментарий!
Дело в том, что я хочу добиться именно АвтоматическогО преобразования. Для этого вроде как достаточно написать конструктор с одним формальным параметром, с типом из которого хочешь произвести преобразование. В 3 книгах так написано.
Я скоро лопну от любопытства. Что не ТАК!?!?!
Попробуй
const Complex operator+([color=red]const[/color] Complex&);
Спасибо за комментарий!
Дело в том, что я хочу добиться именно АвтоматическогО преобразования. Для этого вроде как достаточно написать конструктор с одним формальным параметром, с типом из которого хочешь произвести преобразование. В 3 книгах так написано.
Я скоро лопну от любопытства. Что не ТАК!?!?!
Тогда попробуй еще так - уже в самом коде:
a=a+(Complex)0.1;
Дело в том что я не слышал о том чтобы можно было так на автомате преобразовать стандартный тип к классу. А вот если сделать (Complex)(double) - это будет равносильно new Complex(double) и далее уже все будет нормально. По идее еще можно попробовать перекрыть istream, ostream - но сейчас на вскидку не скажу как.
Язык программирования С++
Бьерн Страуструп.
Вместо того, чтобы описывать несколько функций, можно описать конструктор, который из параметра double создает complex:
class complex {
// ...
complex(double r) { re=r; im=0; }
};
Этим определяется как получить complex, если задан double. Это традиционный способ расширения вещественной прямой до комплексной плоскости. Конструктор с единственным параметром не обязательно вызывать явно:
complex z1 = complex(23);
complex z2 = 23;
Обе переменные z1 и z2 будут инициализироваться вызовом complex(23). Конструктор является алгоритмом создания значения заданного типа. Если требуется значение некоторого типа и существует строящий его конструктор, параметром которого является это значение, то тогда этот конструктор и будет использоваться. Так, класс complex можно было описать следующим образом:
class complex {
double re, im;
public:
complex(double r, double i =0) { re=r;im=i; }
friend complex operator+(complex, complex);
friend complex operator*(complex, complex);
// ...
};
Все операции над комплексными переменными и целыми константами с учетом этого описания становятся законными. Целая константа будет интерпретироваться как комплексное число с мнимой частью, равной нулю. Так, a=b*2 означает
a = operator*(b, complex( double(2), double(0) ) )
А что касается моей проблемы то всё заработало как только я вместо
friend Complex operator-(Complex&,Complex&);
friend Complex operator*(Complex&,Complex&);
friend Complex operator/(Complex&,Complex&);
написал
friend Complex operator-(Complex,Complex);
friend Complex operator*(Complex,Complex);
friend Complex operator/(Complex,Complex);
непонятно толко, почему?
По поводу неявного преобразования, если кто не знает...
Язык программирования С++
Бьерн Страуструп.
А что касается моей проблемы то всё заработало как только я вместо
friend Complex[COLOR=red]&[/COLOR] operator-(Complex&,Complex&);
friend Complex[COLOR=red]&[/COLOR] operator*(Complex&,Complex&);
friend Complex[COLOR=red]&[/COLOR] operator/(Complex&,Complex&);
написал
friend Complex operator-(Complex,Complex);
friend Complex operator*(Complex,Complex);
friend Complex operator/(Complex,Complex);
непонятно толко, почему?
Если бы Вы написали так, то тоже все заработало. У Вас типы операндов и тип возвращаемого значения разные. И Вам надо бы было тогда описывать несколько операций.
непонятно толко, почему?
Потому-что во втором случае значения передаются по значению, а не по ссылке. Если передаются по ссылке, тогда теоретически могут быть изменены, поэтому комп. не применяет неявное преобразование.