C++ / Array in einer Klasse

06/19/2012 04:02 deathkeeper#1
Hi Leute!

Ich erstelle das Objekt "ElevatorControl" genau einmal. Zu einem späteren Zeitpunkt erstelle ich ein oder mehrere Objekte von "ElevatorCabin" und möchte die Adressen von "ElevatorCabin" in dem Array "elevators[0]","elevators[1]", usw. speichern. Leider habe ich eine totale Denkblockade und komme einfach nicht drauf wie ich dass hinbekommen soll. Ich hoffe jemand von euch kann mir helfen.

//ElevatorControl.h
Code:
class ElevatorControl {
public:
	void requestUpward(int atLevel);
	void requestDownward(int atLevel);
	void addCabin(ElevatorCabin *c);
	void print();
	void moveTo(ElevatorCabin* ec, int targetLevel);
private:
	int numOfElevators;
	int findBest(int level, ElevatorDirection d);
	ElevatorCabin* elevators[5];
};
06/19/2012 06:59 2n0w#2
Verstehe ich nicht so ganz, glaube aber das das gehen sollte.
Code:
void addCabin(ElevatorCabin *c)
{
  elevators[numOfElevators] = c;
  numOfElevators++;
}
06/19/2012 08:01 deathkeeper#3
Ich denke ich habe das Problem gelöst. Deine Funktion habe ich gleich mal übernommen.
Ich poste mal was ich bisher habe. Vieleicht versteht man dann besser was mein Problem war oder es kommen noch Verbesserungsvorschläge.
Dafür, dass ich bis vor zwei Tagen noch nie was mit C++ und schon gar nichts mit Klassen zu tun hatte denke ich, dass dieser Code soweit ok sein wird. Warscheinlich unsauber, aber zweckmäßig :p

//ElevatorControl.h
Code:
#if !defined(_ELEVATORCONTROL_H)
#define _ELEVATORCONTROL_H
#include "ElevatorCabin.h"
#include "ElevatorDirection.h"

class ElevatorControl {
public:
	void requestUpward(int atLevel);
	void requestDownward(int atLevel);
	void addCabin(ElevatorCabin *c);
	void print();
	void moveTo(ElevatorCabin* ec, int targetLevel);
	ElevatorControl(int numOfElevators): numOfElevators(numOfElevators) {}; //Konstruktor
private:
	int numOfElevators;
	int findBest(int level, ElevatorDirection d);
	ElevatorCabin* elevators[3];
};

#endif  //_ELEVATORCONTROL_H
//ElevatorControl.cpp
Code:
#include "ElevatorControl.h"
#include <iostream>

void ElevatorControl::requestUpward(int atLevel) {

}

void ElevatorControl::requestDownward(int atLevel) {

}

void ElevatorControl::addCabin(ElevatorCabin* c) {
    elevators[numOfElevators] = c;
    numOfElevators++;
}

void ElevatorControl::print() {

}

void ElevatorControl::moveTo(ElevatorCabin* ec, int targetLevel) {

}

int ElevatorControl::findBest(int level, ElevatorDirection d) {

}
//main.cpp
Code:
#include <iostream>
#include "ElevatorCabin.h"
#include "ElevatorControl.h"
#include "ElevatorCallButton.h"
#include "ElevatorSendButton.h"
#include "CallButtonPosition.h"
#include "ElevatorDirection.h"

#define ANZ 3
#define TL_1 10
#define BL_1 0
#define TL_2 10
#define BL_2 0
#define TL_3 10
#define BL_3 0

using namespace std;

int main()
{
    ElevatorControl _ElevatorControl(0);   //Objekt "Fahrstuhlkontrolle" erstellen (numOfElevators)

    #if ANZ == 1
    ElevatorCabin   _ElevatorCabin[1] = {ElevatorCabin(BL_1,TL_1,BL_1)};   // Objekte "Fahrstuhlkabine" erstellen (actLevel, topLevel, bottomLevel)
    _ElevatorControl.addCabin(&_ElevatorCabin[0]);
    #endif

    #if ANZ == 2
    ElevatorCabin   _ElevatorCabin[2] = {ElevatorCabin(BL_1,TL_1,BL_1), ElevatorCabin(BL_2,TL_2,BL_2)}; // Objekte "Fahrstuhlkabine" erstellen (actLevel, topLevel, bottomLevel)
    _ElevatorControl.addCabin(&_ElevatorCabin[0]);
    _ElevatorControl.addCabin(&_ElevatorCabin[1]);
    #endif

    #if ANZ == 3
    ElevatorCabin   _ElevatorCabin[3] = {ElevatorCabin(BL_1,TL_1,BL_1), ElevatorCabin(BL_2,TL_2,BL_2), ElevatorCabin(BL_3,TL_3,BL_3)};  // Objekte "Fahrstuhlkabine" erstellen (actLevel, topLevel, bottomLevel)
    _ElevatorControl.addCabin(&_ElevatorCabin[0]);
    _ElevatorControl.addCabin(&_ElevatorCabin[1]);
    _ElevatorControl.addCabin(&_ElevatorCabin[3]);
    #endif

    return 0;
}
06/19/2012 11:47 yihaaa#4
Du solltest dir erst mal Gedanken über das machen, was du überhaupt willst und überlegen ob es nicht einen besseren Weg gibt.
Warum diese komische addCabin-Funktion benutzen, wenn du dies auch einfach im Konstruktor verstecken kannst?

Desweitern sollte du keine #define benutzen! Benutz einfach const.
Du solltest dir auch überlegen wie sich eine Klassen verhalten wenn du sie kopieren oder zuweisen willst, da du weder eine Kopierkonstruktor oder den Zuweisungsoperator überladen hast.
Du sollest auch mal nach der Parameterübergabe schauen, da du willst eine Kopier erzeugst, aber bei den Funktionen wahrscheinlich nur auf den Wert zugreifen möchtest, dann kannst du auch einfach z.B. void requestUpward(const int& atLevel); verwenden. Das const verhindert das auch fälschlicherweise den Wert atLevel verändern würdest!

Du könntest auch mal danach schauen die Funktionen mit const zu sicher z.B.
void ElevatorControl::print() const;

Zu guter Letzt konnte man man über Vererbung nachdenken, den das sieht mir doch verdammt danach auch, das sich dadarch einiges vereinfacht.

MfG
06/19/2012 16:36 deathkeeper#5
Quote:
Originally Posted by yihaaa View Post
Du solltest dir erst mal Gedanken über das machen, was du überhaupt willst und überlegen ob es nicht einen besseren Weg gibt.
Ich kenn mich nicht so aus und bin mir sicher das es einen besseren weg gibt. Aber bis jetzt weis ich leider nocht nicht wie der aussieht.

Quote:
Originally Posted by yihaaa View Post
Warum diese komische addCabin-Funktion benutzen, wenn du dies auch einfach im Konstruktor verstecken kannst?
Wenn ich wüsste wie. Ich brauche halt drei unterschiedliche Versionen von dem Programm. Einmal einen Fahrstuhl in einem Schacht. Dann zwei Fahrstühle und dann noch mehrere Fahrstühle mit unterschiedlichen Schachtlängen.

Quote:
Originally Posted by yihaaa View Post
Desweitern sollte du keine #define benutzen! Benutz einfach const.
Ich habe define benutzt um so zu Unterscheiden welche Verison ich sozusagen kompilieren möchte. Ein, zwei, oder mehrere Fahrstühle.

Quote:
Originally Posted by yihaaa View Post
Du solltest dir auch überlegen wie sich eine Klassen verhalten wenn du sie kopieren oder zuweisen willst, da du weder eine Kopierkonstruktor oder den Zuweisungsoperator überladen hast.
Hier versteh ich nur Bahnhof.

Quote:
Originally Posted by yihaaa View Post
Du sollest auch mal nach der Parameterübergabe schauen, da du willst eine Kopier erzeugst, aber bei den Funktionen wahrscheinlich nur auf den Wert zugreifen möchtest, dann kannst du auch einfach z.B. void requestUpward(const int& atLevel); verwenden. Das const verhindert das auch fälschlicherweise den Wert atLevel verändern würdest!
Ich muss später noch für jedes Stockwerk ein Objekt mit dem Namen "ElevatorCallButton" erzeugen. Wenn jemand in einem Stockwerk drückt wird dann irgendwie die Funktion requestUpward() aufgerufen und die Information übergeben auf Welchem Stockwerk der Fahrstuhl angefordert wird.

Quote:
Originally Posted by yihaaa View Post
Zu guter Letzt konnte man man über Vererbung nachdenken, den das sieht mir doch verdammt danach auch, das sich dadarch einiges vereinfacht.
Wie man vererbt weis ich leider auch noch nicht.


Ich habe eine UML die mir vorgiebt wie das Ganze aussehen soll:
[Only registered and activated users can see links. Click Here To Register...]

ElevatorCabin = Die Fahrstuhlkabinen
ElevatorControl = Die Fahrstuhlkontrolle. Über die sollen wir die Fahrstühle dirigieren. Und nicht direkt über ElevatorCabin.
ElevatorSendButton = Ziehlauswahl. Einmal in jeder Fahrstuhlkabine
ElevatorCallButton = Rufpanel. Einmal auf jedem Stockwerk.
06/19/2012 17:29 Nightblizard#6
Oh Gott, so viele pointer... Musst du dich zu 100% an das UML Diagramm halten? Denn in C++ sollte man keine raw pointer benutzen, das ist veraltet und höchst Fehleranfällig!
Die naming convention jagt mir auch einen Schauer über den Rücken, da solltest du dich ein wenig im Internet schlau machen, wie man sinnvoll seine Variablen, Klassen, etc. benennt (das macht alles nur einfacher, glaub' mir).


Aber gut, mal ein paar konkrete Tipps:
Wie yihaaa bereits sagte solltest du keine defines benutzen, um dein Programm zu steuern. const int ANZAHL und dann im Programm if(ANZAHL == x). Das Selbe gillt natürlich für TL und BL, welche du zusätzlich dringend umbenennen musst (ich habe keine Ahnung wofür die Abkürzungen stehen und ein Dritter sollte dein Programm so gut verstehen können wie du das tust).

Warum erstellt du die Arrays in der main Klasse? Mache es doch einfach so:
Code:
ElevatorControl control(2);
ElevatorCabin cabinLeft(1, 2, 3);
ElevatorCabin cabinRight(1, 2, 3);

control.addCabin(&cabinLeft);
control.addCabin(&cabinRight);
Lesbarkeit um 100% gesteigert! ;)
06/21/2012 02:15 MrSm!th#7
Wo soll ein Problem mit seiner Namenskonvention sein? Die ist relativ legitim.
In Java wird nur so programmiert.
06/21/2012 07:59 deathkeeper#8
Hi,

ich hab das Progamm jetzt soweit fertig, dass ich es meinem Prof hinklatschen kann. Für jene die wissen wollen wie ungeschickt das Ganze programmiert ist habe ich das Projekt mal gezippt. Habe versucht mich so gut es geht an das UML Diagramm zu halten. Tut mit auch leid dass ich einen Thread eröffnet habe obwohl ich nur hätte besser googlen müssen :rolleyes:

Gruß
deathkeeper
06/21/2012 17:00 Nightblizard#9
Quote:
Originally Posted by MrSm!th View Post
Wo soll ein Problem mit seiner Namenskonvention sein? Die ist relativ legitim.
In Java wird nur so programmiert.
Okay, ich wollte zwar nicht alles aufzählen, aber da du fragst...

Code:
#define ANZ 3
#define TL_1 10
#define BL_1 0
#define TL_2 10
#define BL_2 0
#define TL_3 10
#define BL_3 0
Solche Abkürzungen sind nicht in Ordnung. Nach 2 Wochen weißt du nicht mehr wofür das nun stand. Gut, über ANZ lässt sich streiten, aber das ist nochmal ein eigener Punkt.


Code:
ANZ
ElevatorControl
addCabin
Entweder nur deutsch oder nur englisch. Mischen ist unschön.

Code:
_ElevatorControl
Variablennamen fangen niemals mit einem Unterstrich an, noch mit einem Großbuchstaben. Ein Unterstrich gefolgt von einem Großbuchstaben geht gar nicht. ;)
Namen, die mit Unterstrichen beginnen, sollten vermieden werden, da diese i.d.R. von der Implementierung genutzt werden und es so zu Verwechslungen kommen kann.
Großbuchstaben am Anfang sind für Klassen reserviert.

Code:
ElevatorCabin   _ElevatorCabin[3]
Wenn man ein Array aus mehreren Objekten/Variablen erstellt, dann sollte man den Namen im Plural schreiben.


Aber am Ende ist das wie mit jeder naming convention, das sind nur hilfreiche Vorschläge, dran halten muss sich niemand.
06/21/2012 22:57 MrSm!th#10
Oh, gar nicht bemerkt, hab mir hauptsächlich das UML angesehen :o