Kolejność definicji klas - przeciążanie operatorów

0

Cześć
Ćwiczac przeciazanie operatorow, natknolem sie na problem wynikajacy z braku zdefiniowanej wczesniej klasy Kelvin, oczywiscie czytalem o predefiniowaniu klasy tuz po include ale nie pomaga.To co niechce dzialac, zakomentowalem .

Caly poniższy kod znajduje sie w jednym pliku

#include <iostream>
using namespace std;


class Kelvin;
class CelsiusDeg;
class CelsiusDeg{
	private:
		double value;
	public:
		double getValue() const{
			return this->value;
		}
		void setValue(double value){
			this->value=value;
		}
		CelsiusDeg(){
			this->setValue(0);
		}
		CelsiusDeg(double value){
			this->setValue(value);
		}	
		friend ostream& operator<<(ostream& os,const CelsiusDeg& obj){
			return os<<obj.getValue()<<" [st. C]";
		}
		CelsiusDeg operator + (const CelsiusDeg &obj) { 
        	CelsiusDeg result(obj.getValue()+this->value); 
			return result; 
        } 
        CelsiusDeg operator - (const CelsiusDeg &obj) { 
        	CelsiusDeg result(this->value-obj.getValue()); 
			return result; 
        }
/*		CelsiusDeg operator - (const Kelvin &obj) { 
        	CelsiusDeg result(this->value-(obj.getValue()+273.15)); 
			return result; 
        } 
        CelsiusDeg operator + (const Kelvin &obj) { 
        	CelsiusDeg result(this->value+(obj.getValue()+273.15)); 
			return result; 
        } **/
};

class Kelvin{
	private:
		double value;
	public:
		double getValue() const{
			return this->value;
		}
		void setValue(double value){
			this->value=value;
		}
		Kelvin(){
			this->setValue(0);
		}
		Kelvin(double value){
			this->setValue(value);
		}
		
		friend ostream& operator<<(ostream& os,const Kelvin& obj){
			return os<<obj.getValue()<<" [K]";
		}
		
		Kelvin operator + (const Kelvin &obj) { 
        	Kelvin result(obj.getValue()+this->value); 
			return result; 
        } 
        Kelvin operator - (const Kelvin &obj) { 
        	Kelvin result(this->value-obj.getValue()); 
			return result; 
        } 
        Kelvin operator - (const CelsiusDeg &obj) { 
        	Kelvin result(this->value-(obj.getValue()-273.15)); 
			return result; 
        } 
        Kelvin operator + (const CelsiusDeg &obj) { 
        	Kelvin result(this->value+(obj.getValue()-273.15)); 
			return result; 
        }
};


int main(int argc, char** argv) {
	
	Kelvin* j1=new Kelvin();
	CelsiusDeg* m1=new CelsiusDeg();	
	
	Kelvin* j2=new Kelvin(23.15);
	CelsiusDeg* m2=new CelsiusDeg(56.01);		
	
	//referencje bo latwiej na nich operowac niz na wskaznikach
	Kelvin &J1= *j1;//dereferencja, dostanie sie do wartosci wskaznika
	Kelvin &J2= *j2;
	CelsiusDeg &M1= *m1;//dereferencja, dostanie sie do wartosci wskaznika
	CelsiusDeg &M2= *m2;	
	
	cout<<"Takie same typy"<<endl;
	cout<<(J1+J2)<<endl;
	cout<<(J1-J2)<<endl;
	cout<<(M1+M2)<<endl;
	cout<<(M1-M2)<<endl;
	
	cout<<"Rózne typy"<<endl;
//	cout<<(M1+J2)<<endl;
//	cout<<(M2-J1)<<endl;
	cout<<(J2+M1)<<endl;
	cout<<(J1-J2)<<endl;
	
	
	
	delete j1,j2,m1,m2;
	return 0;
}
0

Nawet w jednym pliku możesz rozdzielić deklaracje od definicji.
https://wandbox.org/permlink/O1P0U5kZcdrzwWI8 (tu ograniczyłem się jedynie do problematycznych metod).

class Kelvin;
class CelsiusDeg{
        ...
        CelsiusDeg operator-(const Kelvin &obj);
        CelsiusDeg operator+(const Kelvin &obj);
};

class Kelvin{
        ...
};

CelsiusDeg CelsiusDeg::operator-(const Kelvin &obj) { 
    CelsiusDeg result(this->value-(obj.getValue()+273.15)); 
    return result; 
} 
CelsiusDeg CelsiusDeg::operator+(const Kelvin &obj) { 
    CelsiusDeg result(this->value+(obj.getValue()+273.15)); 
    return result; 
}

Popatrz też na ostrzeżenia bo najwidoczniej ten fragment ze zwalnianiem pamięci nie działa tak jak myślisz.

0

Zdefiniuj metody który używają składowej innej klasy po definicji tej składowej.
Czyli część metod ma być tylko zadeklarowana w klasie, natomiast zdefiniowana dopiero po deklaracji obu klas.
poza tym nie tędy droga ... powinno być coś w rodzaju:

#include <iostream>
using namespace std;

class Temperature
{
    public:
    enum Kind { tCelsius,tFarenhate,tKelvin };
    struct MulAdd 
    {
       double mul,add;
       double recalc(double value)const { return value*mul+add; }
    };
    private:
    double value;
    static MulAdd &ma(Kind kind)
    {
        static Temperature::MulAdd tb[]=
        {
            { 1,0 }, //Celsius
            { 5.0/9.0,-32 }, // Farenhate
            { 1,272.15 }, // Kelvin
        };
        return tb[kind];
    }
    static const char *unit(Kind kind)
    {
        static const char *tb[]={"C","F","K",};
        return tb[kind];
    }
    const char *unit()const { return unit(kind); }
    Kind kind;
    public:
    static Temperature Celsius(double value) { return Temperature(value,Temperature::tCelsius); }
    static Temperature Farenhate(double value) { return Temperature(value,Temperature::tFarenhate); }
    static Temperature Kelvin(double value) { return Temperature(value,Temperature::tKelvin); }
    Temperature(double value,Kind kind):value(value),kind(kind) {}
    Temperature As(Temperature::Kind kind)
    {
        const MulAdd &in=ma(this->kind);
        const MulAdd &out=ma(kind);
        return Temperature(out.recalc(in.recalc(value)),kind);
    }
    friend ostream &operator<<(ostream &s,const Temperature &t) { return s<<t.value<<t.unit(); }
};

int main()
{
    Temperature t(Temperature::Celsius(100));
    cout<<t<<endl;
    cout<<t.As(Temperature::tCelsius)<<endl;
    cout<<t.As(Temperature::tFarenhate)<<endl;
    cout<<t.As(Temperature::tKelvin)<<endl;
    return 0;
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1