webForumDet fria alternativet

Klass i klass

8 svar · 273 visningar · startad av Mc Fetto

Mc FettoMedlem sedan nov. 20022 355 inlägg
#1

Hej, jag har gjort en klass Bil som innehåller två andra klasser Datum och Tank, nu undrar jag om man genom Bil's konstruktor kan skapa de andra två klasserna eller ska man göra eett par metoder i Bil som skapar respektive klass??

Skickar med mina klasser, då jag inte vet om jag är ute och bikar helt eller vad!!

class Datum {
	public:
		Datum(string tillverkning, string inkop);
		Datum();
	private:
		string tillverkning;
		string inkop;
};

class Tank {
	public:
		Tank(float kapacitet, float niva);
		Tank();
	private:
		float kapacitet;
		float niva;
};

class Bil {
	public:
		Bil(string regNr, string fabrikat, int vikt,Datum Ti_ink, float bensinForbruk, Tank tnk);
		Bil();
	private:
		string regNr;
		string fabrikat;
		int vikt;
		Datum ti_ink;
		float bensinForbrukning;
		Tank tnk;
};
aasahMedlem sedan mars 20034 471 inlägg
#2

Din klass Bil innehåller ingenting annat än

public:
   Bil(string regNr, string fabrikat, int vikt,Datum Ti_ink, float bensinForbruk, Tank tnk);
   Bil();
private:
   string regNr;
   string fabrikat;
   int vikt;
   Datum ti_ink;
   float bensinForbrukning;
   Tank tnk;

Däremot innehåller din fil tre stycken klassdefinitioner. Det är något helt annat det. I C++ kan du lägga hur många klassdefinitioner du vill i en fil. (Visserligen kan klokskapen med det diskuteras, men det finns inget hinder för det.) Men varje klass är fortfarande sin egen klass. En konstruktor för en klass används för att instansiera och fylla denna instans med vettiga värden. Det görs klassvis.

------------
Sen har jag visst problem med innantilläsning :r så ett litet tillägg kan var på sin plats:
När du implementerar konstruktorn för Bil *kan* du skapa nya Datum och Tanks i den. Men i så fall ska konstruktorn ta argumenten till konstruktorerna inte färdiga objekt. Exempel:

I)
I .h: Bil(string regNr, string fabrikat, int vikt, Datum Ti_ink, float bensinForbruk, Tank tnk);
I .cpp: Datum och Tank är redan skapade så instansvariablerna får dessa värden direkt via tilldelning. Alltså måste Tank och Datum skapas *före* anropet till Bils konstruktor.

eller

II)
I .h: Bil(string regNr, string fabrikat, int vikt, string tillv, string ink, float bensinForbruk, float kap, float n);
I.cpp:
Bil::Bil(string regNr, string fabrikat, int vikt, string tillv, string ink, float bensinForbruk, float kap, float n) {
.....
ti_ink = *(new Datum(tillv, ink));
tnk = *(new Tank(kap, n));
}

Alltså kan du välja att anropa Datums och Tanks konstruktorer antingen före eller inom Bils konstruktor.

Mc FettoMedlem sedan nov. 20022 355 inlägg
#3

Men kan jag då om jag skickar in data till Bil-konstruktorn (två strängar) och ifrån den kallar på Datum-konstruktorn för att skapa en klass som ska vara med i Bil-klassen?

aasahMedlem sedan mars 20034 471 inlägg
#4

Kolla mitt redigerade svar. Klarnar det?

Mc FettoMedlem sedan nov. 20022 355 inlägg
#5

Japp det gör det, det andra hajar jag :) det första har jag försökt men får felmedelandet: error C2614: 'Bil' : illegal member initialization: 'Tank' is not a base or member

Så här ser det ut i cpp-filen

 
Tank::Tank(float kapacitet, float niva): kapacitet(kapacitet), niva(niva) {}
Tank::Tank() {}

Bil::Bil(string regNr, string fabrikat, int vikt, float bensinForbrukning, Tank tnk):
	regNr(regNr), fabrikat(fabrikat), vikt(vikt),bensinForbrukning(bensinForbrukning), Tank(tnk) {}
Bil::Bil() {}

Jag har ännu inte gjort något test-prog som skickar in ngr färdiga variabler!

Så här ser Bil-klassen ut:

class Bil {
	public:
		Bil(string regNr, string fabrikat, int vikt, float bensinForbruk, Tank tnk);
		Bil();
	private:
		string regNr;
		string fabrikat;
		int vikt;
		Datum ti_ink;
		float bensinForbrukning;
		Tank tnk;
};
aasahMedlem sedan mars 20034 471 inlägg
#6

Mc Fetto skrev:

Japp det gör det, det andra hajar jag :) det första har jag försökt men får felmedelandet: error C2614: 'Bil' : illegal member initialization: 'Tank' is not a base or member

Så här ser det ut i cpp-filen

 
Tank::Tank(float kapacitet, float niva): kapacitet(kapacitet), niva(niva) {}
Tank::Tank() {}

Bil::Bil(string regNr, string fabrikat, int vikt, float bensinForbrukning, Tank tnk):
	regNr(regNr), fabrikat(fabrikat), vikt(vikt),bensinForbrukning(bensinForbrukning), Tank(tnk) {}
Bil::Bil() {}

...

Men felmeddelandet stämmer ju. Tank är en typ, ungefär som String är en typ, inte ett värde. Det som tilldelas mellan : och { i konstruktorn är ju värden, inte typer. Att skriva Tank(tnk) motsvarar att skriva String (fabrikat). Du måste skicka in ett värde på en Tank, alltså följande:
I main eller dylikt..
Tank* t = new Tank(5.9, 9.0);
Bil* b = new Bil(....., *t);
Koden i bilens konstruktor borde då vara i princip ..., tnk(tnk).

Men... din tilldelning ser rent allmänt skum ut... Nu är jag på lite hal is, jag är 100% säker på hur det funkar i Java men jag är inte säker i C++. Jag *tror* att just detta är lika, men kan inte garantera det. Det "borde", tror jag, vara så att dina inparametrar skymmer instansvariablerna när de heter samma sak. Hur ska C++ kunna veta att det är skillnad på fabrikat(fabrikat) och fabrikat(fabrikat). De heter ju samma sak. För att komma åt den instansvariabel som du vill tilldela så *tror* jag att du måste skriva this.fabrikat(fabrikat) (och på motsvarande sätt för övriga variabler). Men det kan ev vara så att just mellan : och { i en konstruktor så vet språket med automatik.

Mc FettoMedlem sedan nov. 20022 355 inlägg
#7

När jag gör på ditt sätt så får jag detta felmedelandet: cannot convert from 'class Bil *' to 'class Bil' och samma fär TAnk-klassen!

Tog bort new i mainprogrammet och det fungerade!

aasahMedlem sedan mars 20034 471 inlägg
#8

Mc Fetto skrev:

När jag gör på ditt sätt så får jag detta felmedelandet: cannot convert from 'class Bil *' to 'class Bil' och samma fär TAnk-klassen!

Tog bort new i mainprogrammet och det fungerade!

new returnerar en pekare till objektet, ja, så jag har skrivit tokigt, ska ändra omedelbart efter detta. Dessutom lever ditt objekt tills du väljer att explicit anropa destruktorn. Utan new får du en instans vars destruktor kommer att köras när du lämnar den funktion/det block där variabeln skapades i. Om du vill ha new eller ej beror på hur ditt program ser ut.

Mc FettoMedlem sedan nov. 20022 355 inlägg
#9

Får titta mer på det i morgon :) tack för all hjälp!!

136 ms totalt · 3 externa anrop · v20260731065814-full.30151723
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
133 ms — hämta tråd, inlägg och bilagor (db)