//======= komplex2214.h - hlavička třídy ============

// trasujte a divejte se kudyma to chodi, tj. zobrazte *this, ...

// objekty muzete rozlisit pomoci indexu


#ifndef KOMPLEX_H

#define KOMPLEX_H


#include <math.h>


struct Komplex {

enum TKomplexType {eSlozky, eUhel};

static int Poradi;

static int Aktivnich;

double Re,Im;

int Index;


Komplex(void) {Re=Im=0;Index = Poradi;Poradi++;Aktivnich++; }

inline Komplex(double re,double im=0, TKomplexType kt = eSlozky);

Komplex(const char *txt);

inline Komplex(const Komplex &p);

~Komplex(void) {Aktivnich--;}


void PriradSoucet(Komplex const &p1,Komplex const &p2){Re=p1.Re+p2.Re;Im=p1.Im+p2.Im;}

Komplex Soucet(const Komplex & p){Komplex pom(Re+p.Re,Im+p.Im);return pom;}

Komplex& Prirad(Komplex const &p){Re=p.Re;Im=p.Im;return *this;}

double faktorial(int d) {double i,p=1; for (i=1;i<d;i++) p*=i; return p; }

double Amplituda(void)const {// Re = 4;

return sqrt(Re*Re + Im *Im);}

bool JeMensi(Komplex const &p) {return Amplituda() < p.Amplituda();}

double Amp(void) const;

bool JeVetsi(Komplex const &p) {return Amp() > p.Amp();}


// operatory

Komplex & operator+ (void) {return *this;}

// unární +, může vrátit sám sebe, vrácený prvek je totožný s prvkem, který to vyvolal

Komplex operator- (void) {return Komplex(-Re,-Im);}

// unární -, musí vrátit jiný prvek než je sám (ten konstruktor v returnu je dost drastický)

Komplex & operator++(void) {Re++;Im++;return *this;}

// nejdřív přičte a pak vrátí, takže může vrátit sám sebe (pro komplex patrně nesmysl)

Komplex operator++(int) {Re++;Im++;return Komplex(Re-1,Im-1);}

//vrací původní prvek, takže musí vytvořit jiný pro vrácení (pro komplex patrně nesmysl)

Komplex & operator= (Komplex const &p) {Re=p.Re;Im=p.Im;return *this;}

// bez const v hlavičce se neprelozi nektera prirazeni, implementováno i zřetězení

Komplex & operator+=(Komplex &p) {Re+=p.Re;Im+=p.Im;return *this;}

// návratový prvek je stejný jako ten, který to vyvolal, takže se dá vrátit sám

bool operator==(Komplex &p)

{if ((Re==p.Re)&&(Im==p.Im)) return true;else return false;}

bool operator> (Komplex &p) {if (Amp() > p.Amp()) return true;else return false;}

// může být definováno i jinak

bool operator>=(Komplex &p) {if (Amp() >=p.Amp()) return true;else return false;}

Komplex operator~ (/*Komplex &p*/ void) {return Komplex(Re,-Im);}

//komplexne sdruzeny / kdyz je bez parametru, musi byt bez parametru

// bylo by dobré mít takové operátory dva jeden, který by změnil sám prvek

// a druhý, který by prvek neměnil

Komplex& operator! () {Im*=-1;return *this;}; // a tady je ten operátor

// co mění prvek. Problém je, že je to nestandardní pro tento operátor

// a zároveň se mohou plést. Takže bezpečnější je nechat jen ten první

// bool operator&&(Komplex &p) {}

Komplex operator+ (Komplex &p) {return Komplex(Re+p.Re,Im+p.Im);}

Komplex operator+ (float f) {return Komplex(f+Re,Im);}

Komplex operator* (Komplex const &p) {return Komplex(Re * p.Re - Im * p.Im,Re * p.Im + Im * p.Re);}

Komplex &operator*= (Komplex const &p) // zde je nutno použít pomocné proměnné, protože

// je nutné použít v obou přiřazeních obě proměnné

{double pRe=Re,pIm=Im; Re=pRe*p.Re-Im*p.Im;Im=pRe*p.Im+pIm*p.Re;return *this;}

// ale je to špatně v případě, že použijeme pro a *= a;, potom první přiřazení změní

// i hodnotu p.Re a tím nakopne výpočet druhého parametru (! i když je konst !)

// {double pRe=Re,pIm=Im,oRe=p.Re; Re=pRe*p.Re-Im*p.Im;Im=pRe*p.Im+pIm*oRe;return *this;}

// verze ve ktere přepsání Re složky již nevadí

// friend Komplex operator+ (float f,Komplex &p); //není nutné pokud nejsou privátní proměnné

operator int(void){return Amp();}

};

inline Komplex::Komplex(double re,double im, TKomplexType kt )

{

Re=re;

Im=im;

Index=Poradi;

Poradi++;

Aktivnich++;

if (kt == eUhel)

{Re=re*cos(im);Im = Re*sin(im);}

}


Komplex::Komplex(const Komplex &p)

{

Re=p.Re;

Im=p.Im;

Index=Poradi;

Poradi++;

Aktivnich++;

}


#endif

//======= komplex2214.cpp - zdrojový kód třídy ============

// trasujte a divejte se kudyma to chodi, tj. zobrazte *this, ...

// objekty muzete rozlisit pomoci indexu


#include "komplex2214.h"


int Komplex::Poradi=0;

int Komplex::Aktivnich=0;


Komplex::Komplex(const char *txt)

{

/* vlastni alg */;

Re=Im=0;

Index = Poradi;

Poradi++;

Aktivnich++;

}


double Komplex::Amp(void)const

{

return sqrt(Re*Re + Im *Im);

}


Komplex operator+ (float f,Komplex &p)

{

return Komplex(f+p.Re,p.Im);

}

//======= komplex2214p.cpp - kód aplikace ============


#include "komplex2214.h"


char str1[]="(73.1,24.5)";

char str2[]="23+34.2i";


int main ()

{

Komplex a;

Komplex b(5),c(4,7);

Komplex d(str1),e(str2);

Komplex f=c,g(c);

Komplex h(12,35*3.1415/180.,Komplex::eUhel);

Komplex::TKomplexType typ = Komplex:: eUhel;

Komplex i(10,128*3.1415/180,typ);


d.PriradSoucet(b,c);

e.Prirad(d.Prirad(c));

d.PriradSoucet(5,c);

d.PriradSoucet(Komplex(5),c);


e = a += c = d;

a = +b;

c = -d;

d = a++;

e = ++a;

if (a == c)

a = 5;

else a = 4;

if (a > c)

a = 5;

else a = 4;

if (a >= c)

a = 5;

else a = 4;

b = ~b;


//?? bool operator&&(Komplex &p) {}

c = a + b + d;

//??c = a + 5 + 4 + d;

c = 5 + c;

int k = int (c);

int l = d;

float m = e; // pozor - použije jedinou možnou konverzi a to přes int

if (a && c) // musi byt implementovan - neni-li konverze (např. zde se

// proháčkuje přes konverzi int, kde je && definovana)

e = 8; // u komplex nesmysl

Komplex n(2,7),o(2,7),p(2,7);

n*=o;

p*=p; // pro první realizaci n*=n je výsledek n a p různy i když vstupy jsou stejné

if (n!=p)

return 1;

return 0;

}