# Aufgabe: Klasse für Polynome



## drpingoo (15. September 2008)

Hallo zusammen,

Ja, ich weiss, ich beschäftige mich momentan intensiv mit Klassen, deswegen auch wieder eine Aufgabe dazu.

Zunächst einmal zum Verständnis des Codes, den versteh ich nämlich nicht ganz. Bei der Aufgabe steht übrigens noch folgendes:

Ein Polynom kann durch ein Array von Koeffizienten beschrieben werden. Hierbei werden
die Koeffizienten niedrigen Grades auf die niedrigen Index-Werte abgebildet. Beispiel: Hier
wird ein Polynom mit Grad (degree) 3 in einem Array der Grösse 4 abgespeichert:
3x^3 + 12.1x^2 -10.5x +8.3 

Im Array sie das dann so aus: 8.3|-10.5|12.1|3.0

Folgendes Gerüst skizziert eine Klasse für Polynome. Konstruktoren, der Destruktor und zwei Hilfsfunktionen sind bereits implementiert.

Ausserdem ist die Implementation des Copy-Konstruktors angegeben. Der Copy-
Konstruktor bewirkt, dass Sie innerhalb einer Funktion, ein Objekt der Klasse CPolynom
einfach per return zurückgeben können (wie einen Basistyp) und dieses dabei korrekt
kopiert wird.


```
#include <iostream>
using namespace std;


class CPolynom
{
private:
	int degree;
	double * coeff;

public:
	CPolynom(const CPolynom &);
	CPolynom(int d) {coeff = new double[d+1]; degree = d;};
	virtual ~CPolynom() {delete [] coeff;};
	int getDegree() const {cout << degree << endl; return degree;};
	double* getCoeff() const {cout << coeff << endl; return coeff;};
	
	CPolynom deriv() const;
	CPolynom multiply(const CPolynom& p) const;
};


CPolynom::CPolynom(const CPolynom & p){
	degree = p.getDegree();
	coeff = new double[degree+1];
	double* coeff2 = p.getCoeff();
	for (int i=0; i<=degree; i++) coeff[i] = coeff2[i];
	}
```

Nun zu meinen Fragen.
Wenn ich folgendes mache:


```
int main(){


	CPolynom poly(8);
	poly.getDegree();
	poly.getCoeff();

	return 0;}
```

Dann weise ich doch dem neuen poly den Grad 8 zu. Was ich jedoch nicht ganz verstehen ist, wie ich das Array fülle. Er legt ja ausserdem ein Array, in diesem Falle der Grösse 9 an.

Und des weiteren verstehe ich die Aussage über den Copy-Konstruktor nicht. Was ist genau damit gemeint, was ist der Gedanke dieser Funktion?

lg


----------



## Online-Skater (15. September 2008)

Hallo _drpingoo_,

für die Aufnahme der Werte müsstest du noch eine Funktion schreiben etwa fill() oder so indem du das Array durchläufst und per cin Werte abfragst oder du gestaltest einen Konstruktor so das gleich Werte übergeben werden können. In deiner Beispiel-Implementation sind keine Werte drin sondern nur die Reservierung des Speichers.

Der Kopierkonstruktor ist nicht nur für interne Funktion sehr wichtig z.b. wenn du Operatoren überlädsts bsp. Addition sondern auch wie der Name es schon verrät ein Objekt mit einem vorhandenem Objket instanzierst.


```
int main(int argc, char* argv[])
{
	CPolynom poly1(8);
        // angenommen poly1 ist mit werten gefüllt
	CPolynom poly2 = poly1;  // --> Aufruf des Kopierkonstruktors
       
       CPolynom poly3;   // --> Default Konstruktor
       poly3 = poly1        // --> hierfür müsste man den Zuweisungs operator = überladen

	return 0;
}
```

Der Kopierkonstruktor ist meines Wissens nach ziemlich umständlich bzw. merkwürdig ausgefallen, mag sein das es funktioniert aber warum nicht einfach so:

```
CPolynom::CPolynom(const CPolynom& p)
{
  degree = p.degree;
  coeff = new double[degree + 1];
  for (int i = 0; i <= degree; i++)
  {
    coeff[i] = p.coeff[i];
  }
}
```

mfg ;-)


----------



## drpingoo (15. September 2008)

Hi,

Danke für deine Antwort!

Ok, ich werd mich dann mal daran machen eine fill-Fkt. zu erstellen. 

Ich hab jetzt glaub verstanden, wie der Copy-Konstruktor funktioniert, aber noch nicht, wieso das so sein muss. 

Es gibt eine Referenz auf ein Polynom. Da degree private ist, die anderen Fkt. jedoch damit arbeiten, ordnen wir p.degree degree zu. Danach wird ein Array erstellt, wie immer um eins grösser als der Grad des Polynoms. Schliesslich, da coeff ebenfalls private ist, füllen wir das gesamte Array. Damit das funktioniert, müssen wir jedoch schon ein gefülltes Polynom haben. Ist das so richtig und ist das der Grund, weshalb es einen Copy-Konstruktor geben muss?



> 1.
> int main(int argc, char* argv[])
> {
> CPolynom poly1(8);
> ...



Man kann doch gar keinen default-Konstruktor erstellen, da ja gar keiner in der Klasse definiert ist und der Compiler würde nur von selbst einen erzeugen, falls wir noch gar keinen definiert hätten. Wie meinst du das mit Überladen? Also ich weiss schon, was das Überladen von Operatoren bedeutet, aber ich dachte Zuweisungen müsse man nie überladen... Weshalb bei poly3=poly1 schon und bei poly2=poly1 nicht? Weil poly3 ein default Konstruktor ist?

lg


----------



## Online-Skater (16. September 2008)

Hey hier ein bischen Lesestoff das sollte das Prinzip verdeutlichen:

Kopierkonstruktor

_Jeder Konstruktor, der ohne Parameter aufgerufen werden kann, ist ein Default Konstruktor. Ein Konstruktor ist also auch dann ein Default Konstruktor wenn jeder Parameter einen default Wert hat. Wenn wir selber einen Konstruktor erstellen, erstellt der Compiler keinen Standard Konstruktor mehr._

mfg


----------



## drpingoo (16. September 2008)

Danke, für den Link, ich les ihn gleich mal durch.

lg


----------



## drpingoo (16. September 2008)

Hm das mit Initialisierung und Zuweisung hab ich sprachlich glaub auch schon oft durcheinander gebracht...

Ich habs das Array-Auffüllen mit dem Knostruktor versucht, aber iwie t das immer noch nicht. Sehe meinen Fehler auch nicht...:-(

Ich weiss, es ist nicht elegant, da ich einen double zu int konvertiere.


```
#include <iostream>
#include <time.h>
using namespace std;


class CPolynom
{
private:
	int degree;
	double * coeff;

public:
	CPolynom(const CPolynom &);
	CPolynom(int d) {coeff = new double[d+1]; degree = d;};
	virtual ~CPolynom() {delete [] coeff;};
	int getDegree() const {cout << degree << endl; return degree;};
	double* getCoeff() const {cout << coeff << endl; return coeff;};
	
	CPolynom deriv() const;
	CPolynom multiply(const CPolynom& p) const;
	
};






CPolynom::CPolynom(const CPolynom & p){
	degree = p.getDegree();
	coeff = new double[degree+1];
	double* coeff2 = p.getCoeff();
	for (int i=0; i<=degree; i++) {
		srand(time(NULL));
		coeff2[i] = rand();
		coeff[i] = coeff2[i];
		cout << coeff[i] << endl;} //Ausgabe mehr so zum gucken, obs funktioniert hat
	}




int main(){


	CPolynom poly(8);
	poly.getDegree();
	poly.getCoeff();
	CPolynom pol(const CPolynom & poly);
	poly.getCoeff();

	return 0;}
```


----------



## Online-Skater (16. September 2008)

Hi,

so wie du den "Kopierkonstruktor" gestaltet hast ist es keiner mehr denn er generiert nun zufällige Zahlen wo ist da der Sinn des kopierens ? Der Kopierkonstruktor den ich dir vorgeschlagen entspricht genau dem was er tun soll... kopieren !

Deine Generierung der Zahlen kommt in den "normalen" Konstruktor in dem du den Grad des Polynoms übergibst. Wenn du double Zahlen generien willst gibt es mehrere Ansätze z.b. eine Zahl zwischen [1-100] + [1-9]/10.

Schön weiter fleißig üben und möglichst viel nachlesen


----------



## drpingoo (16. September 2008)

Du hast Recht^^, aber iwie muss ich den ja füllen. Es stimmt, dass es dann keine Kopie mehr wäre, bloss die Grösse des Array würde dann noch stimmen, jedoch wäre das eigtl meine Absicht das Array so zu füllen.

Ach, iwie funktioniert das von hinten und vorne nicht. Kannst du mir nicht einen Tipp geben?
(Ich weiss, das hast du schon, aber ich steh grad voll aufem Schlauch)...

lg


----------

