C++Aufgabe

Neue Frage »

Auf diesen Beitrag antworten »
ccc C++Aufgabe

Hallo ich habe gerade probleme bei dieser Aufgabe:
Gegeben seien folgende (unvollständige) Klassendefinitionen. Die Klassen sollen ein Protokoll verbrauchter
elektrischer Leistung realisieren. Dabei stellt die Klasse CMeasurement die Protokolleinträge dar, die Klasse CConsumptionLog modelliert das Protokoll. Neue Einträge werden von einer Messeinrichtung durch Aufruf der Methode addEntry zum Protokoll hinzugefügt, wenn sich die gemessene Leistung ändert. Im Protokolleintrag
bezeichnet datetime den Zeitpunkt der Messung und power die gemessene Leistung. Die in einem
Protokolleintrag angegebene Leistung wird also ab dem zugehörigen Zeitpunkt solange konstant verbraucht, bis
über einen erneuten Aufruf der Methode addEntry neue Werte gemeldet werden. Der Messzeitpunkt wird in
Millisekunden seit einem fest definierten Startzeitpunkt angegeben, z.B. seit dem 1.2.2011

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:


class CMeasurement
{
private:
long m_datetime; // Messzeitpunkt in Millisekunden seit 1.2.2011 0:00
float m_power; // Gemessene Leistung in Watt
public:
//Konstruktor
CMeasurement(long datetime, float power);
CMeasurement();
void print();
};
class CConsumptionLog
{
private:
CMeasurement* m_entries; // Array mit den Messwerten
long m_maxEntries; // Größe des Array mit den Messwerten
long m_loggedEntries; // Aktuelle Anzahl von Messwerten im Array
public:
void addEntry(long datetime, float power);
void clearLogEntries();
void print();
};


















a) Mit der aktuell für CMeasurement definierten Schnittstelle können Sie neue Objekte erzeugen, aber auf die
Werte in den Objekten nicht zugreifen. Ergänzen Sie in der Klassendefinition Methoden, die Ihnen
Messzeitpunkt (m_datetime) und Leistung (m_power) als Rückgabewerte liefern. (Tragen Sie die
Ergänzungen direkt in obige Klassendefinition ein.)


Wie soll ich genau bei der a) vorgehen ?

Meine idee
long get datetime(){

return m_datetime;

}

Richtig?
 
Auf diesen Beitrag antworten »
Karlito

Hallo ccc,

damit eine Methode einen Wert zurückgibt, reicht es den Rückgabetypen anzugeben und den Wert dann mit return den Wert zurückzugeben. Das get wird nicht benötigt und ist an dieser Stelle sogar falsch. Sinnvoll ist, das get als Teil des Namens für den getter zu verwenden, also:
code:
1:
2:
3:
long getDatetime();


Richtig wäre also:
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
class CMeasurement
{
	private:
		long m_datetime; // Messzeitpunkt in Millisekunden seit 1.2.2011 0:00
		float m_power; // Gemessene Leistung in Watt
	public:
		//Konstruktor
		CMeasurement(long datetime, float power);
		CMeasurement();
		void print();
		long getDatetime(){
			return m_datetime;
		}
		float getPower(){
			return m_power;
		}
};


Gruß,

Karlito
Auf diesen Beitrag antworten »
ccc

b) Ergänzen Sie die gegebene Klassendefinition von CConsumptionLog um einen Konstruktor, der es ermöglichen soll, optional die initiale Größe des Arrays mit Messwerten zu setzen. Die Default-Größe (keine Größe angegeben) soll 100 Elemente sein.
Ergänzen Sie in der Klassendefinition außerdem den Copy-Konstruktor sowie den Destruktor.
(Tragen Sie die Ergänzungen direkt in obige Klassendefinition ein.)

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:

CConsumptionLog::CConsumptionLog(long maxEntries,){

m_maxEntries = maxEntries;

maxEntries = 100;


}



Ist der Konstruktor so richtig?
Auf diesen Beitrag antworten »
eulerscheZahl

code:
1:
2:
3:
CConsumptionLog::CConsumptionLog(long maxEntries = 100) {
    m_maxEntries = maxEntries;
}
 
Auf diesen Beitrag antworten »
Karlito

Wenn der Konstruktor in der Klassendefinition selbst mit angegeben wird, muss man dann den Scope nicht weg lassen? Ich glaube die Aufgabenstellung besagt, dass direkt in der Klassendefinition gearbeitet werden soll (siehe a)).
Außerdem: sollte das Array für dei Messwerte nicht gleich mit initialisiert werden?

Gruß,

Karlito
Auf diesen Beitrag antworten »
ccc

@eulersche Zahl

Muss man den default Wert immer in der runden Klammer definieren ?
Auf diesen Beitrag antworten »
eulerscheZahl

Mir ist zumindest keine andere Möglichkeit bekannt.
Auf diesen Beitrag antworten »
ccc

Was muss man den genau beim Copy Konstruktor beachten ?
Auf diesen Beitrag antworten »
ccc

So?


code:
1:
2:
3:
4:
5:
6:
7:
CConsumptionLog::CConsumptionLog(long maxEntries = 100) {
    m_maxEntries = origin.maxEntries;
}


Auf diesen Beitrag antworten »
eulerscheZahl

Nein, dem Copy Konstruktor musst du ein CConsumptionLog& übergeben.
Auf diesen Beitrag antworten »
ccc

code:
1:
2:
3:
4:
5:
6:
7:
8:

CConsumptionLog&::CConsumptionLog(long maxEntries = 100) {
    m_maxEntries = origin.maxEntries;
}




Richtig?
Auf diesen Beitrag antworten »
eulerscheZahl

code:
1:
2:
3:
CConsumptionLog::CConsumptionLog(CConsumptionLog& origin) {
    this->m_maxEntries = origin.maxEntries;
}
Auf diesen Beitrag antworten »
ccc

Wieso kommt da plötzlich ein this her ?
Auf diesen Beitrag antworten »
eulerscheZahl

this sagt einfach, dass es sich um die aktuelle Instanz der Klasse handelt. Es funktioniert zwar auch ohne, aber die Lesbarkeit wird meiner Meinung nach erhöht, da du so klar machst: die aktuelle Instanz nimmt den Wert von der anderen.

Würdest du die Klassenvariable nicht m_maxEntries nennen, sondern maxEntries, brächtest du hier zwingend ein this, um das klarzumachen:
code:
1:
2:
3:
CConsumptionLog::CConsumptionLog(long maxEntries = 100) {
    this->maxEntries = maxEntries;
}
Auf diesen Beitrag antworten »
ccc

Im destruktor einfach delete maxEntries,

einfügen ?
Auf diesen Beitrag antworten »
eulerscheZahl

Ich habe mir jetzt mal die Aufgabenstellung angeschaut: im Konstruktor musst du noch Speicherplatz für die Einträge (m_entries) anlegen. Den musst du dann im Destruktor auch wieder freigeben.
Auf diesen Beitrag antworten »
ccc

Wie legt man Speicherplatz an ?
Auf diesen Beitrag antworten »
eulerscheZahl

code:
1:
long m_loggedEntries = new long[m_maxEntries];

Das musst du dann mit delete wieder löschen.
Auf diesen Beitrag antworten »
ccc

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:

CConsumptionLog::~CConsumptionLog(){

delete m_maxEntries;


}



Geht das so?

War mir nicht sicher ob ich logged Entries oder max Entries löschen sollte ?
Auf diesen Beitrag antworten »
eulerscheZahl

Du musst den Speicher wieder freigeben, den du im Konstruktor dynamisch allokiert hast, also m_loggedEntries.
Und da es sich um ein Array handelt, solltest du delete[] verwenden.

PS: Karlito hat mich darauf hingewiesen, dass es this-> heißen muss, statt this., wenn man auf die Felder zugreifen will.
Auf diesen Beitrag antworten »
ccc

Zeichnen Sie das UML-Klassendiagramm der Klasse CConsumptionLog (mit Initialwerten, Defaultwerten und
Zusicherungen) auf der Grundlage der in Aufgabenteil b) ergänzten Klassendefinition. Verwenden Sie den hier
dafür vorgesehenen Platz


code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:

CConsumptionLog::~CConsumptionLog(){

delete[m_loggedEntries];


}



Wisst ihr wie man so ein UML Diagramm erstellt ?
Auf diesen Beitrag antworten »
Karlito

Zitat:
Original von ccc
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:

CConsumptionLog::~CConsumptionLog(){

delete[m_loggedEntries];


}


Ist falsch.

code:
1:
2:
3:
4:
5:
CConsumptionLog::~CConsumptionLog(){
  delete [] m_entries;
}


Zitat:
Original von ccc
Wisst ihr wie man so ein UML Diagramm erstellt ?


Ja. Schau dir einfach den Wikipedia-Artikel an und mache einen Vorschlag. Wir schauen dann drüber.

Gruß,

Karlito
Auf diesen Beitrag antworten »
ccc

Wieso schreibt ihr da nur m_entries ?
Auf diesen Beitrag antworten »
Karlito

Weil m_logEntries vom Typ long ist und die aktuelle Anzahl an Datensätzen vorhalten soll. m_Entries hingegen ist das Array mit den Datensätzen. Das ist es, was reserviert und auch freigegeben werden muss. Ich glaube da war ein Fehler bei euler. Du solltest das Programm auch mal probieren.

Gruß,

Karlito
 
Neue Frage »
Antworten »


Verwandte Themen

Die Beliebtesten »
Die Größten »
Die Neuesten »