Hilfe bei Implementierung eines "Handynetzes"



  • Hallo zusammen!

    Der Titel klingt etwas verwirrend, aber mangels eines besseren Begriffes hab ich es bei der Original-Aufgabenstellung belassen 😉
    Das ganze ist eine Hausarbeit und bräuchte hier und da Hilfe, deswegen schreibe ich das mal so vollständig wie möglich auf.

    http://up.picr.de/21919549fr.jpg

    Es gibt drei Klassen, von denen die class SimCard eine Handynummer enthält und beim "Netzbetreiber" (class Carrier) auf eine bestimmte Person registriert wird. CellPhone-Klasse enthält eine SimCard kann anrufe tätigen und entgegennehmen und die Carrier-Klasse registriert SIM-Karten und enthält eine vector-Liste mit allen registrierten SIM-Karten. Wenn ein "Anruf" getätigt wird, dann vermittelt Carrier zwischen den SIM-Karten.
    Soweit so gut, ich hoffe, dass man sich damit das meiste denken kann, die ganze Aufgabenstellung wäre wohl etwas lange, aber wenn meine Fragen nicht klar werden, dann werde ich sie noch posten 🙂

    Also ich habe bisher den Großteil der Klasse SimCard implementiert und bin mir auch recht sicher, dass der Teil soweit korrekt ist. Hier mal der erste Nicht-Standardkonstruktor:

    SimCard::SimCard(string name, string adress){
    	srand(time(NULL));
    	for (int i = 0; i < 10; i++){
    		m_phoneNumber += rand() % 10;
    	}
    	SimCard* simCard = new SimCard();
            simcard->m_adress = adress;
            simcard->m_name = name;
            simcard->m_phoneNumber;
    	Carrier::registerSim(simCard);
    }
    

    Was mir nun Probleme gemacht hat ist Folgendes: Mein Dozent nennt es Verzeigerung und hat so (ich denke als Muster vorprogrammiert) den CellPhone-Konstruktor implementiert:

    CellPhone::CellPhone(SimCard* sim)
    {
         m_sim = sim;
         m_sim->setPhone(this);
    }
    

    Gemäß Aufgabenstellung soll der member m_sim nun der Funktion setPhone einen Zeiger auf sich selbst übergeben, ich nehme an zur Verbindung von SIM-Karte und Handy...nur habe ich hier eine Fehlermeldung, wenn ich das genau so hinschreibe, die da lautet:

    Fehler: Das Argument vom Typ ""CellPhone* "" ist mit dem Parameter vom Typ ""CellPhone *"" inkompatibel

    Keine Ahnung, was das bedeuten soll, noch was ich weiter machen soll.
    Meine setPhone Funktion sieht so aus:

    void SimCard::setPhone(Cellphone* phone){
    	m_phone = phone;	
    }
    

    Später soll ich das nochmal so ähnlich machen:

    [...]verwendet call die statische Methode Carrier::makeCall und übergibt einen Zeiger auf sich selbst sowie die anzurufende Rufnummer

    Meine bisherige Version von der call-Funktion sieht so aus:

    void Cellphone::call(const string &callee){
        for (int i=0; i<m_book.size(); i++){
            if(m_book[i].name == callee){    //Falls Name vorhanden, verwende Nummer
                Carrier::makeCall(???????, m_book[i].name); //<- Problem
            }
        }
    }
    

    Ich hoffe jemand kann mir da weiterhelfen und mir diese "Verzeigerung" erklären oder sonstige Hilfe und/oder Kritik äußern :p

    LG
    Dan



  • Was mir spontan auffällt

    - address schreibt man mit zwei d 😉
    - Parameter sollten meist als const & übergeben werden, so wie bei Cellphone::call, und nicht als Kopien
    - Der SimCard Konstruktor macht so wenig Sinn, bzw. gefällt mir nicht. Warum wird im SimCard Konstruktor wieder eine neue SimCard erstellt? Wenn der Carrier eine Kopie braucht, sollte er selber eine Kopie erstellen. Außerdem macht es wohl grundsätzlich nicht so viel Sinn, beim Carrier für die interne Speicherung ebenfalls die Simcard Klasse zu verwenden. Das ist wahrscheinlich vorgegeben, aber sinnvoll finde ich das nicht.
    - Würde eher Sinn machen, wenn der Carrier die Nummer generieren und vergeben würde, und nicht die SimCard eine zufällige generieren würde. So könnte es auch passieren, dass zwei Instanzen zufällig dieselbe Nummer bekommen.
    - Sicher, dass du die Fehlermeldung wirklich rauskopiert und nicht abgetippt und vielleicht selber ein * eingefügt hast? Ansonsten vielleicht irgendwo einen include vergessen.
    - Und was ist jetzt das letzte Problem?



  • Erstmal danke für deine Antwort, Mechanics!

    1.) Ja...stimmt, peinlich peinlich. 😃
    2.) das mit const reference hatte ich mir auch schon gedacht, so hab ich das nämlich gelernt, so waren teilweise die Vorgaben. Bin dem wohl zu strikt gefolgt
    3.) Puh, ja das mit dem Konstruktor ist so 'ne Sache: Ich glaube ich zeige dir mal die Aufgabenstellung, dann weißt du warum ich den so versucht habe zu implementieren:

     Der Standardkonstruktor kann auch weggelassen oder private implementiert werden.
     Die beiden übrigen Konstruktoren registrieren sich durch Aufruf der Carrier::registerSim-Methode beim
    Netzbetreiber
     Der Konstruktor ohne m_phoneNumber-Parameter soll eine neue 10-stellige Telefonnummer zufällig bestimmen
    und sich anschlieÿend registrieren
     Da nur SIM-Karten vom Objektregister erfasst werden, muss der Destruktor von SimCard auch das Telefon
    löschen. Dazu verwenden Sie dort delete auf dem m_phone-Zeiger.

    4.) Deine Kritik ist durchaus berechtigt, was den Sinn dieser ganzen Sache betrifft, aber da ich mich als Anfänger bezeichnen würde, ist mir vor Allem die Technik wichtig 🙂
    5.) Hier nochmal ein Bild:
    http://up.picr.de/21921605sc.jpg
    6.) Naja, also das ist scheinbar dasselbe wie auf dem bild oben drüber. Ich weiß nicht, wie dieses "Zeiger auf sich selbst übergeben" funktionieren soll, was anscheinend mit this gelöst wird, aber bei mir nicht klappt 😃

    LG
    Dan



  • 2. Diese Schlampigkeit sieht man leider sehr häufig. Ist anscheinend vielen "Profis" nicht mal klar, was da genau passiert.
    3. Daran erkenne ich aber noch nicht, warum ein SimCard Konstruktor gleich noch eine SimCard konstruiert 😉 Nochmal, wenn der Carrier eine Kopie braucht, sollte er sie selber erstellen.
    Dass eine Sim Karte das Telefon löscht, hört sich nach komplett falschem Design an. Ganz toller Lehrer.
    5. Die Klassennamen sind unterschiedlich geschrieben, schau genau hin. Deswegen hab ich gefragt, ob du die Fehlermeldung kopiert hast. Wahrscheinlich irgendwo falsch vorwärtsdeklariert.
    Im übrigen ist das ein Intellisense Fehler. Die schalte ich sowieso immer ab, weil da unglaublich viele false positives kommen.
    6. Man kann schon einen Zeiger auf sich selbst mit this übergeben.



  • Oh Mann, danke...ich hoffe, mein Auge für so kleine Fehler wird irgendwann mal besser. Das kleine p wäre mir wahrscheinlich nächstes Weihnachten aufgefallen -.-

    2.) Das hört sich doch gut an, dann werde ich das erstmal wieder da ändern, wo es nötig ist.
    3.) In diesem Sinne, wie genau soll ich denn die komplette Instanz von SimCard jedes mal kopieren ohne ein neues Objekt direkt anzulegen? Abseits der Aufgabenstellung, sollte ich dann ein neues SimCard-Objekt in der Carrier::registerSim Funktion anlegen mithilfe der getter?
    6.)ok also wenn das nochmal verändere, würde das "Zeiger auf sich selbst übergeben", dann so aussehen?

    void Cellphone::call(const string &callee){
        for (int i=0; i<m_book.size(); i++){
            if(m_book[i].name == callee){   
                Carrier::makeCall(this->m_sim, m_book[i].name); 
            }
        }
    }
    

    LG
    Dan



  • 3. Die Klasse sollte einen sinnvollen Copy Constructor haben (kann in dem Fall nicht automatisch generiert werden, weil sich die Sim Karte schlauerweise gleich das ganze Telefon löschen soll und wahrscheinlich nicht mal euer Prof einen double free haben will).
    6. Ich weiß nicht, was du übergeben musst und was dann passieren sollte. In deiner Beschreibung steht "und übergibt einen Zeiger auf sich selbst sowie die anzurufende Rufnummer". Das wäre wohl this und dann phoneNumber oder so statt name. Aber wie gesagt, keine Ahnung, was der Carrier mit einem Zeiger auf das Telefon anfangen soll.



  • Ich verstehe, hab auch an einen copy constructor gedacht, aber den hatten wir bisher noch nicht in der Vorlesung/Skript, ich habe eben noch mal nachgeschaut 😕 Also, irgendwie scheint die Aufgabenstellung diesmal ein wenig aus dem Ruder gelaufen zu sein. Naja, jedenfalls danke für den Hinweis! 💡

    6.) also die member SIM-Karte m_sim soll einen Zeiger auf sich selbst übergeben und der zweite Parameter ist ein string für die Tel.Nr. aus einem struct phoneBookItem. Die makeCall Funktion sucht in ihrer Liste dann nach dieser Nummer um einen Anruf einzuleiten.

    Hier an dieser Stelle noch mal vielen Dank an dich! Ich denke, den Rest versuche ich jetzt wieder alleine 🙂

    LG
    Dan


Anmelden zum Antworten