C++- Metody wirtualne

0

Witam, mam do zrobienia zadanie w którym pokaże polimorfizm poprzez metody wirtualne, a więc jest klasa Figura, która ma klasy pochodne np: Prostokąt,koło,trójkąt. Metody wirtualne mają miec nazwy: ustaw_wartosc, i oblicz pole, a dla każdych klas maja miec inne parametry w tych metodach (np dla koła ważny jest promień, nie jest to pożądane dla innych figur). Rozwiązałem problem wcześniej, jednak rozwiązanie mnie nie zadawala- po prostu w konstruktorze przypisuje wartości obiektów, jednakże chciałbym to robić nieco inaczej... i tutaj pojawia się błąd, jak go naprawić? Co robie źle? Proszę o pomoc!
Kod programu:

#include "stdafx.h"
#include <string>
#include <iostream>
/*2. (C++) In the class Figura the member functions area and set_values have been declared as virtual.
They are later redefined in each of the derived classes: PROSTOKAT TROJKAT and KOLO which additionally have specific for them members
like width, height and radius.
Use polymorphism to show how functions area and set_values work for different objects.
*/

class Figura
{
protected:
std::string RodzajZwierza;

public :
Figura(std::string);
Figura(); // wymagany był konstruktor default... nie wiem dlaczego- tak podpowiedzial kompilator, ktos mi odpowie?
__// **virtual void Oblicz_Pole()
{ std::cout << "Moge obliczyc czegos pole..." << std::endl; }
;

virtual void Ustaw_Wartosci()
{ std::cout << "Moge ustawic jakies wartosci" << std::endl; }

**//__
};

Figura::Figura(std::string JakieZwierze)
{
RodzajZwierza=JakieZwierze;
std::cout << "Utworzono jakas figure o nazwie" << RodzajZwierza<< std::endl;
}
/----------------------------------------------------------/

class Prostokat:public Figura
{
private:
int A,B,Pole;
public:
Prostokat(std::string);
void Oblicz_Pole() * tutaj jest pokazane rozwiązanie problemu na jakie wpadłem... jednak nie zadowala mnie takie rozwiązanie (nie ma * wartosci przekazywanych przez argumenty
{
std::cout << "Pole Prostokatu wynosi: " <<AB << std::endl;
Pole=A
B;
}

void Ustaw_Wartosci(int a,int b) // tutaj chce przekazac wartosci przez argumenty by ustawic wartosci
{ 
	A=a;
	B=b;
}

};
Prostokat::Prostokat(std::string Jakie):Figura(Jakie)
{
std::cout << "Utworzylem Prostokat"<< std::endl;
}
/----------------------------------------------------------/

class Trojkat:protected Figura
{
void Oblicz_Pole()
{
std::cout << "Moge obliczyc czegos pole trojkatu" << std::endl; }

void Ustaw_wartosci()
{ std::cout << "Moge ustawic wartosci trojkatu" << std::endl; }

};
/----------------------------------------------------------/
int main()
{
Figura* pierwsza= new Prostokat("P1");

pierwsza->Ustaw_Wartosci(2,1); // błąd: 	2	IntelliSense: too many arguments in function call
pierwsza->Oblicz_Pole();


return 0;

}

Co poprawić?? Pomóżcie bo nie moge tego znaleŹć...

0

przepraszam za nieprzejrzystość kodu... wstawie zrzut ekranu -.-<image>foo</image>68e01e4339.png

2
Bartosz Olchowik napisał(a):
Figura::Figura(std::string JakieZwierze)
{
	RodzajZwierza=JakieZwierze;
	std::cout << "Utworzono jakas figure o nazwie" << RodzajZwierza<< std::endl;
}

Bomba! Te figury no normalnie zwierzęcia, mogą przerazić na śmierć!

0

Przepraszam jeśli to AŻ TAK CIĘ RAZI, wzieło się to z tego, iż kierowałem się stroną na której były pokazane metody wirtualne na podstawie zwierząt (jako tworzone obiekty). Może ktoś mądrzejszy odpowie na dręczące mnie problemy?

0
 
class Figura
{
protected:
	std::string Rodzajfigury;

public :
	Figura(std::string);
	Figura();
	virtual void Oblicz_Pole()
	{ std::cout << "Moge obliczyc czegos pole..." << std::endl; }
	;

	virtual void Ustaw_Wartosci()
	{ std::cout << "Moge ustawic jakies wartosci" << std::endl; }

};

Figura::Figura(std::string RodzajFigury)
{
	Rodzajfigury= RodzajFigury;
	std::cout << "Utworzono jakas figure o nazwie" << RodzajFigury<< std::endl;
}
/*----------------------------------------------------------*/

class Prostokat:public Figura
{
private:
	int A,B,Pole;
public:
	Prostokat(std::string);
	void Oblicz_Pole()
	{
		std::cout << "Pole Prostokatu wynosi: " <<A*B << std::endl;
		Pole=A*B;
	}

	void Ustaw_Wartosci(int a,int b)
	{ 
		A=a;
		B=b;
	}
};
Prostokat::Prostokat(std::string Jakie):Figura(Jakie)
{
	std::cout << "Utworzylem Prostokat"<< std::endl; 
}
/*----------------------------------------------------------*/

class Trojkat:protected Figura
{
	void Oblicz_Pole()
	{
		std::cout << "Moge obliczyc czegos pole trojkatu" << std::endl; }

	void Ustaw_wartosci()
	{ std::cout << "Moge ustawic wartosci trojkatu" << std::endl; }
};
/*----------------------------------------------------------*/
int main()
{
	Figura* pierwsza= new Prostokat("P1");
	Prostokat* druga =new Prostokat("P2");
	pierwsza->Ustaw_Wartosci(2,2); // Tutaj jest błąd... too many arguments in function call
	pierwsza->Oblicz_Pole();
	

	return 0;
}

1

Błąd jest bo nie masz takiej funkcji która przyjmuje 2 argumenty.

0

Tak, i mam pokazać jak działają metody wirtualne... dlaczego on nie widzi metody wirtualnej która jest w klasie PROSTOKĄT? Powinna ona przesłaniać metode wirtualna z klasy ogólnej: Figura... Dlaczego tak sie nie dzieje?

0

Tak samo w kole przy ustawianiu wartości powinnien się znaleŹć promień... jak to wszystko zsynchronizować ze sobą, by zadziałał mechanizm polimorfizmu?

1

Bo stworzyłeś Psa podpiąłeś go pod wskaźnik na Ciepłokrwiste (no bo jest ciepłokrwisty) i dajesz rozkaż "Ciepłokrwisty, szczekać" na co kompilator słusznie mówi WTF?
Można to zrobić tak:

((Prostokat*)pierwsza)->Ustaw_Wartosci(2,2);

ale to się mija z celem funkcji wirtualnych.

Tu mniej więcej na ten temat przykład.
http://4programmers.net/Forum/C_i_C++/234110-wczytywanie_z_pliku_w_projekcie_na_programowanie_obiektowe?p=1036598#id1036598

0

Nie rozumiem przykładu wyżej... tak więc zadam może pytanie inaczej... jak ustalic wartości dla obiektów, jeżeli w głownej klasie mamy metode wirtualna: ustaw_wartosci, a w podklasach mamy ją redefiniowaną dla:
-prostokąta: ma ona ustalać wartości: długość i wysokość
-dla koła: promień
Skądś ona musi brać te wartości... nauczono mnie że funkcja(metoda) bierze wartości poprzez argumenty...

0
#include <iostream>
#include <map>
#include <string>
using namespace std;
 
class Figura
{
public:
  typedef map<string, unsigned> Dane;
 
  virtual ~Figura() {}
 
  virtual void ustaw(const Dane& dane) = 0;
  virtual unsigned pole() = 0;
};
 
class Prostokat : public Figura
{
public:
  void ustaw(const Dane& dane) override
  {
      a = dane.at("a");
      b = dane.at("b");
  }
 
  unsigned pole() override
  {
      return a * b;
  }
 
private:
  unsigned a, b;
};
 
int main() {
    const Figura::Dane dane {{"a", 10}, {"b", 20}};
    Figura* figura = new Prostokat();
    figura->ustaw(dane);
    cout << figura->pole() << "\n";
    delete figura;
    return 0;
}

Aczkolwiek nie polecam.

0

Właśnie przeczytałem o "override", jednak nie jest to celem wykonania ćwiczenia (tak myśle gdyż wykładowca nie wspominał o override)...
Jednak dałeś mi niezły pomysł rozwiązania tego problemu... po prostu pytać o wartości użytkownika w CIELE METODY, zamiast najpierw pytać, a potem przekazywac je przez argumenty. Dziękuję!!

0

Wrr... to sobie usun to override. Tak jak napisales nie rob, to chore.

0
Bartosz Olchowik napisał(a):

... po prostu pytać o wartości użytkownika w CIELE METODY, zamiast najpierw pytać, a potem przekazywac je przez argumenty.

  • to najgorszy z możliwych pomysłów. Wyobraź sobie że klasę podobną do twojej użyli w paint'cie ... klikasz ikonkę rysowania prostokąta i nagle wyskakuje czarne okienko z tekstem "Введи высоту: "

Normalnie pobierasz dane i podajesz je w konstruktorach. To co podał @n0name_l jest bardzo dobre, często używane w poważnych projektach, warto z tym się zapoznać ale jednak radzę zacząć od rzeczy prostych.

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