Задать вопрос
@psvworks

Как лучше (проще и красивее) реализовать произведение комплексных и действительных чисел?

Добрый день всем!

Есть такая задача - реализовать класс комплексных чисел. Всё шло хорошо до тех пор пока не добрался до реализации произведения/сложения комплексных и действительных чисел между собой. Есть три случая - когда комплексное число умножается на действительное, когда комплексное умножается на комплексное, и действительное на комплексное. Получается, что все эти три случая можно объединить через перегрузку оператора умножения (либо через шаблон функции), но не могу правильно написать синтаксис, Visual Studio 2015 пишет что нельзя дублировать перегружаемый оператор. А описывать каждую комбинацию complex и double - это некрасивый код. Есть у кого идеи как правильно это реализовать?

#include <iostream>
#include <conio.h>
using namespace std;


class Complex {
private:
    double re, im;

public:
    Complex(double r=0, double i=0) : re(r), im(i) {};   // конструктор
    Complex operator+ (Complex &other);                  // перегрузка сложения    
    Complex operator* (Complex &other);                  // перегрузка умножения
    Complex operator- (Complex &other);                  // перегрузка вычитания

    void show();                                         // вывод комплексного числа на экран
    ~Complex();
};
//------------------------------------------------

Complex Complex::operator+ (Complex &other) {
    return Complex(re + other.re, im + other.im);
}

Complex Complex::operator* (Complex &other) {
    return Complex(re*other.re - im*other.im, re*other.im + im*other.re);
}

Complex Complex::operator- (Complex &other) {
    return Complex(re - other.re, im - other.im);
}
  • Вопрос задан
  • 1070 просмотров
Подписаться 1 Оценить 5 комментариев
Решения вопроса 1
Нужно понимать, что не существует операций между комплексными и действительными числами в математике. Действительные числа неявно приводятся к комплексным, и операции уже выполняются над комплексными числами.
C++ позволяет вам так делать, достаточно определить конструктор с 1 параметром.

Complex(double _r): Complex(_r, 0){}

Теперь любые числовые литералы и типы, которые могут быть неявно приведены к double, так же могут быть неявно приведены к Complex. Теперь можно писать следующее:
Complex(1,2) + 1;

Остаётся другая проблема. Операторы объявлены как функции-члены, что позволяет их использовать лишь тогда, когда левый операнд - комплексное число. Такое выражение не скомпилируется:
1 + Complex(1,2)

Что бы обойти эту проблему, нужно заменить функцию-член на дружественную функцию:

#include <iostream>
using namespace std;

class Complex {
	public:
		Complex(double _r, double _i): r(_r), i(_i){}
		Complex(double _r): Complex(_r, 0){}
		
		friend Complex operator + (const Complex &left, const Complex &right);

	private:
		double r,i;
};

Complex operator + (const Complex &left, const Complex &right) { //Friend function
	return Complex(left.r + right.r, left.i + right.i);
}

int main() {
	Complex a = 4;
	Complex b(1,2);
	int c = 5;
	a+b;       // OK
	3+b;       // OK
	a+123.0f;  // OK
	c+a;       // OK
	return 0;
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы