Napisz definicję klasy wielomianu

0

Witam, mam do napisania definicję klasy wielomianu, poniżej mam podane deklaracje oraz kawałek kodu, lecz nie mam pojęcia tak naprawdę co mam zrobić, tak wyglądają deklaracje:
s - stopień wielomianu

W - adres w pamięci gdzie zapisane są współczynniki wielomianu

wielomian() - konstruktor, który tworzy wielomian stopnia 0 z wyrazem wolnym równym 0.0

wielomian(int) - konstruktor, który tworzy wielomian stopnia podanego jako argument, z wszystkimi współczynnikami równymi 0.0

int PobierzStopien() - metoda, która zwraca stopień wielomianu

double PobierzWspolczynnik(int) - metoda, która zwraca współczynnik wielomianu przy potędze przekazanej jako argument

void ZapiszWspolczynnik(int,double) - metoda, która zapisuje wartość współczynnika przy odpowiedniej potędze

~wielomian() - destruktor zwalniający pamięć

A tak kod:

class wielomian{
	private:
		int s;
		double* W;
	public:
		wielomian();
		wielomian(int);
		int PobierzStopien();
		double PobierzWspolczynnik(int);
                void ZapiszWspolczynnik(int,double);
		~wielomian();
};

1

Krótka recenzja:

  • Nie rób tych chorych wskaźników -> std::array lub std::vector
  • metody odczytujące - const na końcu przez średnikiem
  • mastering level - współczynniki bym zrobił przez operator []

Mniemam, to kod od nauczyciela zajęcz technicznych / religii /geografii ?
Jeden nauczyciel informatyki nauczył mnie sentencji: jak ktoś umie robić, to robi. Jak nie umie, to uczy.

masz zrobić ciąg takich rzeczy jak:

int wielomian::PobierzStopien()
{
   return s;
}
0
AnyKtokolwiek napisał(a):

Krótka recenzja:

  • Nie rób tych chorych wskaźników -> std::array lub std::vector
  • metody odczytujące - const na końcu przez średnikiem
  • mastering level - współczynniki bym zrobił przez operator []

Mniemam, to kod od nauczyciela zajęcz technicznych / religii /geografii ?
Jeden nauczyciel informatyki nauczył mnie sentencji: jak ktoś umie robić, to robi. Jak nie umie, to uczy.

masz zrobić ciąg takich rzeczy jak:

int wielomian::PobierzStopien()
{
   return s;
}

Nie powinno to być zrobione tak ?

		int PobierzStopien()
		{
		return (*this).s;
		}

1
mikko napisał(a):

masz zrobić ciąg takich rzeczy jak:

int wielomian::PobierzStopien()
{
   return s;
}

Nie powinno to być zrobione tak ?

		int PobierzStopien()
		{
		return (*this).s;
		}

Nie.

  • implementacja (definicja) zewnętrzna (w pliku CPP) musi zawierać nazwę klasy z podwójnym dwukropkiem. Inaczej to będzie goła funkcja - która nic nie wie o klasie
  • this jest domyślny dla metod, mój przykład jest prawidłowy. Jeśli facet uczy tych gwiazdek to ma ode mnie ... cóż, będę siedział, ale mu wytłumaczę ...
0
#include <iostream>
#include <stdlib.h>

using namespace std;

class wielomian{
	private:
		int s;
		double* W;
	public:
		wielomian()
		{
        (*this).s=0;
        (*this).W=(double *)malloc(sizeof(double));
        (*this).W[0]=0;
		}
		wielomian(int x)
		{
		 (*this).s=x;
         (*this).W=(double *)malloc(sizeof(double)*x);
          for(int i=0;i<x;i++) (*this).W[i]=0;
		}
		int PobierzStopien()
		{
		return (*this).s;
		}
		double PobierzWspolczynnik(int x)
		{
		return (*this).W[x];
		}
        void ZapiszWspolczynnik(int x,double y)
        {
        (*this).W[x]=y;
        }
		~wielomian()
		{
		free((*this).W);
		free(this);
		}
};






int main()
{


return 0;
}






Mam zrobione w taki sposób czyli rozumiem, że nie poprawnie, co wyrzucić i co pozmieniać aby to lepiej wyglądało/było bardziej poprawne?

1

Było by to względnie poprawne oprócz tej strasznej sekwencji z gwiazdką. Mniejszych czy większych błędów jest więcej, ale to mnie wkurza.

Jednak:
Wyobraź sobie, że w pliku H masz deklarację, i nie wolno Ci pliku H zmieniać. Więc robisz implementację (w C++ mówi się też definiujesz - to to samo) w pliku CPP. Tak bym rozumiał zadanie, takie zadanie możesz dostać np w pracy.

teraz wyliczanka:

  • nie alokuj przez malloc, tylko przez new
  • zwalniaj przez delete a nie free(). Tutaj delete[]
  • nie zwalniaj "samego siebie" free(this) - wcale nie ma pewności, że obiekt był alokowany. To realizuje kod zewnętrzny. To jego zakres odpowiedzialności. destruktor się wykonuje, gdy zewnętrzny kod już podjął nieubłaganą decyzję o zniszczeniu obiektu.
  • flaki wielomianu są o 1 większe od jego stopnia (wyraz wolny) - mogę czegoś nie pamiętać z matmy

teraz ja mam do Ciebie pytanie: chcesz rozwiązanie minimum, czy dla własnego rozwoju drugie "po bożemu" ?

0

Chciałbym po ,, bożemu" ze względu że dopiero zaczynam jak mam się uczyć to chciałbym już poprawnie się nauczyć

0

Po bożemu v.1. array jest kontenerem o długości danej podczas kompilacji, rozmiar nie może być zmieniany

#include <array> 
...
std::array<double,5> wielomian4st; 

I to niemal wszystko, stopień to

wielomian4st.size() - 1;
// a tu operacje ze wspólczynnikiem
wielomian4st[2]  = 17.3;
double wsp3 = wielomian4st[4] ; // opanuj to pod względem matematycznym, który jest który

Po bożemu v2. std::vector jest kontenerem o zmiennej długości, tu wykorzystujemy fakt, że długość da się określić w konstruktorze
Tutaj z implementacją w samej klasie, żeby nie przedłużać.

#include <vector>


class wielomian {
private:
	std::vector<double> W;
public:
	wielomian() : W(1) {}
	wielomian(size_t s) : W(s + 1) {}

	int PobierzStopien() const { return W.size() - 1 ; }
	double& operator [] (size_t x) {  // można operator [], np w innym projekcie, w wersji const
                if (x >= W.size()) 
                          throw new std::exception("Przekroczenie zakresu");    // opcjonalne zabezpieczenie
		
		return W[x];  // zawraca referencję (nie widać tego na pierwszy rzut oka), więc dostępne do zmiany
	}
	virtual ~wielomian() {};  // wirtualne destruktory zaczynają być ważne, gdy z klas dziedziczymy. Niczemu nie przeszkadza, pomóc może.
};

int main() {
	

	wielomian w(7);
	w[3] = 12.4;
	auto s = w.PobierzStopien();

	return 0;
};

Wyjadaczy proszę o uwagi :)

0

Co robię nie tak ?


#include <iostream>
#include <stdlib.h>

using namespace std;

class wielomian{
	private:
		int s;
		double* W;
	public:
		wielomian()
		{
        s=0;
        W=(double *)new(sizeof(double));
        W[0]=0;
		}
		wielomian(int x)
		{
		 s=x;
         W=(double *)new(sizeof(double)*x);
          for(int i=0;i<x;i++) (W[i]=0;
		}
        int wielomian::PobierzStopien()
        {
        return s;
        }
		double wielomian::PobierzWspolczynnik(int x)
		{
		return W[x];
		}
        void wielomian::ZapiszWspolczynnik(int x,double y)
        {
        W[x]=y;
        }
		~wielomian()
		{
		delete [W];
		}
};






int main()
{


return 0;
}







0
mikko napisał(a):

Co robię nie tak ?

Bo co? Jakie masz błedy?

To co ja widzę, to ma być:

W = new double[liczba];
... 
delete W[];

Nie myśl na sposób C

Oraz wewnątrz klasy używasz notacji "zewnętrznej". Albo tak, albo tak, ale nie mix.
Mój to myślenia jest taki: zostawić w spokoju (tzn nie edytować) dostarczony plik nagłówkowy H (czy HPP, jak tam masz) i dopisać do niego adekwatny plik CPP

0

Może to jest bardziej przenośne.

double& operator [] (size_t x) {
		if (x >= W.size()) throw std::out_of_range("Poza zakresem");
		return W[x];
	}
0

To mam na myśli mówiąc o realizacji ZEWNĘTRZNEJ.
Niestety pewnego wzrokowego ostrzelania się z językiem nie przeskoczymy. Te gwiazdki, co mnie wkurzają, to z jakiegoś kursu? jest multum słabiutkich kursów.

// plik HPP
class wielomian{
....
};


// plik CPP
int wielomian::PobierzStopien()
        {
        return s;
        }
        double wielomian::PobierzWspolczynnik(int x)
        {
        return W[x];
        }
        void wielomian::ZapiszWspolczynnik(int x,double y)
        {
        W[x]=y;
        }
0

#include <iostream>
#include <stdlib.h>

using namespace std;

class wielomian{
	private:
		int s;
		double* W;
	public:
		wielomian()
		{
        s=0;
        W=(double *)malloc(sizeof(double));
        W[0]=0;
		}
		wielomian(int x)
		{
		 s=x;
         W=new double[x];
          for(int i=0;i<x;i++) W[i]=0;
		}
		int PobierzStopien()
		{
		return s;
		}
		double PobierzWspolczynnik(int x)
		{
		return W[x];
		}
        void ZapiszWspolczynnik(int x,double y)
        {
        W[x]=y;
        }
		~wielomian()
		{
		delete [];
				}
};


int main()
{


return 0;
}

Tak mam teraz

0

Pięknie się kompiluje (gdzieś wprowadziłem się w błąd co do delete [] przyznaję się)


class wielomian {
private:
	int s;
	double* W;
public:
	wielomian()
	{
		s = 0;
		W = new double[1];
		W[0] = 0;
	}
	wielomian(int x)
	{
		s = x;
		W = new double[x + 1];
		for (int i = 0; i < x; i++) W[i] = 0;
	}
	int PobierzStopien()
	{
		return s;
	}
	double PobierzWspolczynnik(int x)
	{
		return W[x];
	}
	void ZapiszWspolczynnik(int x, double y)
	{
		W[x] = y;
	}
	~wielomian()
	{
		delete[] W;
	}
};
0

Możesz zdefiniować swoją klasę z tylko jednym konstruktorem o domyślnym parametrze.

  wielomian( int stopien_ = 0 )
    : stopien {stopien_}
    {
        W = new double[ stopien + 1 ];
        for( int i = 0 ; i <= stopien ; ++i ) W[i] = 0;
    }

Dodatkowo postaraj się o podstawowe zabezpieczenia, tak aby nie można było czytać elementów z poza tablicy.
Na przykład:

double PobierzWspolczynnik( int x ) const { return (x>stopien||x<0)?0:W[x]; }

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