Dziedziczenie z polimorfizmem, niewłaściwe wywołanie przeciążonego operatora.

0

Piszę na uczelnię taki program i mam oto pytanko. Mianowicie chodzi o ten fragment:

    *tab[1] = test1;
    *tab[4] = test2;
    *tab[2] = "jasno" + *tab[2];
    *tab[4] *= 2;

Wskaźniki są typu Figura, więc wywołuje się przeciążony operator= właśnie z tej klasy i nie przepisuje mi wszystkich danych. Jak sobie z tym poradzić? Podobna sytuacja ma miejsce z operatorem+. Jest wywoływany dla klasy Figura, a powinien być dla innej, nie mogę zrobić z tego metody wirtualnej tak jak z operatorem*=, bo dla każdej klasy będą inne argumenty formalne funkcji. Pomóżcie co z robić z tymi fantami i czy *= może być tak rozwiązany? Poniżej cały kod.

#include <iostream>
#include <cmath>

using namespace std;

class Figura{
	protected:
		string *_kolor;
		static unsigned _liczba;
	public:
		Figura(): _kolor(new string("brak_nazwy")) {_liczba++;}
		Figura(const string& kolor): _kolor(new string(kolor)) {_liczba++;}
		Figura(const Figura& fig): _kolor(new string(*fig._kolor)) {_liczba++;}
		virtual double pole() const = 0;
		virtual ostream& wypisz(ostream&) const = 0;
		friend ostream& operator<< (ostream&, const Figura&);
		Figura& operator= (const Figura&);
		virtual Figura& operator*= (const double&);
		static unsigned liczba_obiektow()
		{
			return _liczba;
		}
		virtual ~Figura() {delete _kolor; _liczba--;}
};

ostream& operator<< (ostream& out, const Figura& fig)
{
	return fig.wypisz(out);
}

Figura& Figura::operator= (const Figura& fig)
{
	if (this != &fig)
	{
		*_kolor = *fig._kolor;
	}
	return *this;
}

Figura& Figura::operator*= (const double& liczba)
{
	return *this;
}

class kolo: public Figura{
	private:
		double _promien;
	public:
		kolo(): Figura(), _promien(0.0) {_liczba++;}
		kolo(const string& kolor, const double promien): Figura(kolor), _promien(promien) {_liczba++;}
		kolo(const kolo& kol): Figura(kol), _promien(kol._promien) {_liczba++;}
		double pole() const
		{
			return M_PI * pow(_promien, 2);
		}
		ostream& wypisz(ostream& out) const 
		{
			return out << *_kolor << " " << _promien << endl;
		}
		kolo& operator= (const kolo&);
		~kolo() {_liczba--;}
};

kolo& kolo::operator= (const kolo& kol)
{
	if (this != &kol)
	{
		Figura::operator= (kol);
		_promien = kol._promien;
	}
	return *this;
}

class prost: public Figura{
	protected:
		double _a;
		double _b;
	public:
		prost(): Figura(), _a(0.0), _b(0.0) {_liczba++;}
		prost(const string& kolor, const double a, const double b): Figura(kolor), _a(a), _b(b) {_liczba++;}
		prost(const prost& pro): Figura(pro), _a(pro._a), _b(pro._b) {_liczba++;}
		double pole() const
		{
			return _a * _b;
		}
		ostream& wypisz(ostream& out) const 
		{
			return out << *_kolor << " " << _a << " " << _b << endl;
		}
		prost& operator= (const prost&);
		friend prost operator+ (const string&, const prost&);
		prost& operator*= (const double&);
		~prost() {_liczba--;}
};

prost& prost::operator= (const prost& pro)
{
	if (this != &pro)
	{
		Figura::operator= (pro);
		_a = pro._a;
		_b = pro._b;
	}
	return *this;
}

prost operator+ (const string& kol, const prost& pro)
{
	return prost(kol + *pro._kolor, pro._a, pro._b);
}

prost& prost::operator*= (const double& liczba)
{
	_a *= liczba;
	_b *= liczba;
	return *this;
}

class prostop: public prost{
	private:
		double _h;
	public:
		prostop(): prost(), _h(0.0) {_liczba++;}
		prostop(const string& kolor, const double a, const double b, const double h): prost(kolor, a, b), _h(h) {_liczba++;}
		prostop(const prostop& pro): prost(pro), _h(pro._h) {_liczba++;}
		double pole() const
		{
			return _a * _b * _h;
		}
		ostream& wypisz(ostream& out) const 
		{
			return out << *_kolor << " " << _a << " " << _b << " " << _h << endl;
		}
		prostop& operator= (const prostop&);
		prostop& operator*= (const double&);
		~prostop() {_liczba--;}
};

prostop& prostop::operator= (const prostop& pro)
{
	if (this != &pro)
	{
		prost::operator= (pro);
		_h = pro._h;
	}
	return *this;
}

prostop& prostop::operator*= (const double& liczba)
{	
	prost::operator*= (liczba);
	_h = _h * liczba;
	return *this;
}

unsigned Figura::_liczba = 0;

int main()
{	
	const kolo test1("czarny", 100);
	const prostop test2("szary", 2, 2, 2);
	
	Figura *tab[5];
	
	tab[0] = new kolo("czerwony", 1);
	tab[1] = new kolo;
	tab[2] = new prost("niebieski", 1, 1);
	tab[3] = new prostop("zielony", 1, 1, 1);
	tab[4] = new prostop;

    for(int i = 0; i < 5; ++i)
        cout << tab[i]->pole() << endl;
    cout << "***** 3 *****" << endl;

    for(int i = 0; i < 5; ++i)
        cout << *tab[i] << tab[i]->pole() << endl;

    cout << "***** 4 *****" << endl;

    *tab[1] = test1;
    *tab[4] = test2;
    //*tab[2] = "jasno" + *tab[2];
    *tab[4] *= 2;

    for(int i = 0; i < 5; ++i)
        cout<< *tab[i] << tab[i]->pole() <<endl;

    cout << "$" << prost::liczba_obiektow() <<endl;

    for(int i = 0; i < 5; ++i)
        delete tab[i];
   
    cout << "$" << prost::liczba_obiektow() << endl;
	
    cout << "***** 5 *****" << endl;
	
	return 0;
}
0

Pomoże ktoś? Bo temat raczej na szybko do zrobienia.

0

Podobna sytuacja ma miejsce z operatorem+. Jest wywoływany dla klasy Figura, a powinien być dla innej (...)

Nie sądzisz, że ten pomysł nie jest zbyt fortunny?

nie mogę zrobić z tego metody wirtualnej tak jak z operatorem*=, bo dla każdej klasy będą inne argumenty formalne funkcji.

A co stoi na przeszkodzie, poza względami estetycznymi i praktycznymi, żeby klasa pochodna definiowania swoją wersję operatora Figura& operator= (const Figura&)? Oczywiście będziesz musiał sprawdzać wewnątrz tego operatora, czy argumentem jest referencja na obiekt właściwej klasy. dynamic_cast się do tego nada.

0

To już tak zrobiłem, ale co z operatorem +?

0

Nic. Pisałem, że ten pomysł nie jest dobry.

0

to powinno być raczej tak:

// zmiast: *tab[1] = test1;
delete tab[1];
tab[1] = new kolo(test1);

albo:

// zmiast: *tab[1] = test1;
dynamic_cast<kolo &>(*tab[1]) = test1;

Najlepiej doczytaj o polimorfizmie i operatorze przypisania (Symfonia Grębosza powinna być odpowiednia).

0

Tak zgadza się masz rację, po prostu prowadzący zrobił mały błąd w zadaniu, dzisiaj się okazało. Już wszystko ok, dzięki za pomoc.

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