Funkcja kwadratowa z użyciem szablonów

0

Mam prośbę o podpowiedź jak rozwiązać zadanie które brzmi:

Utworzyć klasę SquareEquation rozwiązującą równanie kwadratowe o współczynnikach float lub double (szablon - template). Wykorzystać funkcje składowe Wczytaj_wspolczynniki(), Wypisz_wspolczynniki(), Wypisz_rozwiazanie()

Jeżeli pominąć szablony to mam coś takiego :

#include <iostream>
#include <cstdlib>
#include <cmath>

using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */

class SquareEquation
{
	private:
		float a;
		float b;
		float c;
	public:
		void Wczytaj_wspolczynniki()
		{
			cout << "Podaj wspolczynnik a = ";
			cin >> a;
			
			cout << "\nPodaj wspolczynnik b = ";
			cin >> b;
			
			cout << "\nPodaj wspolczynnik c = ";
			cin >> c;
		}	
		
		void Wypisz_wspolczynniki()
		{
			cout << "\nWspolczynniki rowniania kwadratowego:\na = " << a << "\nb = " << b << "\nc = " << c << "\n\n";						
		}
		
		void Wypisz_rozwiazanie()
		{
			float delta;
			float x1;
			float x2;
			
			if (a==0)
			{
				cout << "Wspolczynnik a=0 - rownanie nie jest rownianiem kwadratowym";
			}
			else
			{
				delta = pow(b,2) - (4 * a * c);
				cout << "delta = " << delta << "\n\n";
				if (delta < 0)
				{
					cout << "Rownianie nie ma rozwiazan";
				}
				else if (delta == 0)
				{
					x1 = (-1 * b) / (2 * a);
					cout << "Rownianie ma jedno rozwiazanie x1 = " << x1;
				}
				else
				{
					x1 = (-1 * b - sqrt(delta)) / (2 * a);
					x2 = (-1 * b + sqrt(delta)) / (2 * a);	
					cout << "Rownianie ma dwa rozwiazania:\nx1 = " << x1 <<"\nx2 = " << x2;				
				}
			}
		}
};

int main(int argc, char** argv) {
	SquareEquation funkcja;
	funkcja.Wczytaj_wspolczynniki();
	funkcja.Wypisz_wspolczynniki();
	funkcja.Wypisz_rozwiazanie();
	return 0;
} 

Program działa i poprawnie liczy tylko nie mam pomysłu jak wstawić tu szablon...
Możecie mi podpowiedzieć ?

0

Znalazłam taki przykład w internecie:

template < class klasa > //używamy szablonu
klasa pierwiastek( klasa liczba ) //nowa funkcja z typem zwracalnym, jaki podaliśmy w template
{
    klasa liczba_pierwiastka =( liczba * liczba ); //kto nie lubi liczenia ;)
    return liczba_pierwiastka;
}

A w main:

double liczba1 = pierwiastek < double >( 3.9 ); //przypisujemy wartość zmiennej
    cout << liczba1 << endl;

Przerób swój kod aby wyglądał następująco.

0

Klasa szablonowa (funkcje możesz zaimplementować wewnątrz klasy):

Patrz "Class templates" w: http://www.cplusplus.com/doc/tutorial/templates/

To co podała lightinside to funkcja szablonowa, nie klasa.

0

Widziałem te tutoriale tylko że za każdym razem przy tworzeniu obiektu klasy trzeba podać typ zmiennej a nie jestem pewny czy o to chodziło...
Bo w takim przypadku mam dodać menu na początku z pytaniem dla jakiego typu danych użytkownik chce liczyć rozwiązania ?

0

Wątpię żeby chodziło o to żeby użytkownik mógł podać z konsoli typ wartości.
Raczej chodzi o to że właśnie w main możesz podać jeden lub drugi typ - ale niestety musisz w tym wypadku podać.

Gdybyś miał konstruktor, to wtedy można by inicjalizować obiekt parametrem określającym typ przechowywanej danej, jak w przykładzie:
http://stackoverflow.com/questions/18880700/creating-a-template-class-object-using-a-template-constructor

Do tego dokładasz auto i możesz nie podawać typu. Ale i tak typ zostanie określony w czasie kompilacji a nie uruchomienia.
W czasie uruchomienia da się, ale wątpliwe żeby o to chodziło w zadaniu.

0

Czyli coś takiego:

#include <iostream>
#include <cstdlib>
#include <cmath>

using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */

template <class T>
class SquareEquation
{
	private:
		T a;
		T b;
		T c;
	public:
		void Wczytaj_wspolczynniki()
		{
			cout << "Podaj wspolczynnik a = ";
			cin >> a;
			
			cout << "\nPodaj wspolczynnik b = ";
			cin >> b;
			
			cout << "\nPodaj wspolczynnik c = ";
			cin >> c;
		}	
		
		void Wypisz_wspolczynniki()
		{
			cout << "\nWspolczynniki rowniania kwadratowego:\na = " << a << "\nb = " << b << "\nc = " << c << "\n\n";						
		}
		
		void Wypisz_rozwiazanie()
		{
			T delta;
			T x1;
			T x2;
			
			if (a==0)
			{
				cout << "Wspolczynnik a=0 - rownanie nie jest rownianiem kwadratowym";
			}
			else
			{
				delta = pow(b,2) - (4 * a * c);
				cout << "delta = " << delta << "\n\n";
				if (delta < 0)
				{
					cout << "Rownianie nie ma rozwiazan";
				}
				else if (delta == 0)
				{
					x1 = (-1 * b) / (2 * a);
					cout << "Rownianie ma jedno rozwiazanie x1 = " << x1;
				}
				else
				{
					x1 = (-1 * b - sqrt(delta)) / (2 * a);
					x2 = (-1 * b + sqrt(delta)) / (2 * a);	
					cout << "Rownianie ma dwa rozwiazania:\nx1 = " << x1 <<"\nx2 = " << x2;				
				}
			}
		}
};

int main(int argc, char** argv) {
	SquareEquation<double> funkcja;
	
	funkcja.Wczytaj_wspolczynniki();
	funkcja.Wypisz_wspolczynniki();
	funkcja.Wypisz_rozwiazanie();
	return 0;
} 

powinno być ok :) ?

0

Prawie dobrze, z tym że liczby zmiennoprzecinkowe nie powinno się porównywać.

Spróbuj zamiast:

if (a==0)

dać

// źródło: http://en.cppreference.com/w/cpp/types/numeric_limits/epsilon
if (std::abs(a) < std::numeric_limits<T>::epsilon())

lub:

// wymyślone na kolanie
if ((a * 2.0 == a) && isfinite(a))

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