Braeuchte mal Hilfe bei Member-Objekten und einfacher Vererbung



  • Gruess euch,

    ich habe da ein Problem mit meinem Informatik-Praktikum an dem ich nun schon gefuehlte 25 Stunden dransitze...

    Es geht in diesem Praktikum um Member-Objekte un einfache Vererbung und ich komme damit einfach nicht klar.

    Ziel ist es benutzereingaben zu einem Elektro-Gleichstrommotor modifiziert auszugeben.

    Dazu soll ich drei Klassen benutzen, einmal die Basis-Klasse "cMotor", dann die Kind-Klasse "cEMotor" und eine Klasse die untrennbar zu "cEMotor" gehoert und zwar "cAnker".

    Ich weiss nun nicht wie ich die Konstruktoren schreiben muss, alle meine Versuche liefen bisher auf grund.

    Hier mal der Code "Unit1.cpp:

    //---------------------------------------------------------------------------
    #include "UMotor.h"
    
    #pragma hdrstop
    using namespace std;
    
    //---------------------------------------------------------------------------
    
    int main(void)
    {
      string mHersteller, mTyp;
      double leistung, nSpannung, mGewicht, ankerStrom, ankerWiderstand;
      int nennDrehZahl, spulenWindungsZahl;
    
      cout<<" Eingabe von Motoreigenschaften " <<endl<<endl;
      cout<<" Motor-Hersteller:"; cin>>mHersteller; cout<<endl;
      cout<<" Motor-Typ:"; cin>>mTyp; cout<<endl;
      cout<<" Motor-Nennleistung:"; cin>>leistung; cout<<endl;
      cout<<" Motor-Nenndrehzahl:"; cin>>nennDrehZahl; cout<<endl;
      cout<<" Ankerwindungszahl:"; cin>>spulenWindungsZahl; cout<<endl;
      cout<<" Ankerwiderstand:"; cin>>ankerWiderstand; cout<<endl;
      cout<<" Ankerstrom:"; cin>>ankerStrom; cout<<endl;
    
      cMotor a(mHersteller=a.getHersteller(), nennDrehZahl=a.getDrehZahl());
      a.mAusgabe();
    
      cEMotor b(mTyp,leistung);
      b.mAusgabe();
    
      system("Pause");
      return 0;
    }
    

    und die Klassen "UMotor.h":

    /---------------------------------------------------------------------------
    
    #ifndef UMotorH
    #define UMotorH
    using namespace std;
    
    //--------------------------------------------------------------------------
    //Klasse cMotor beginn
    //--------------------------------------------------------------------------
    class cMotor
    {
      private:
    
      string mHersteller;
      int nennDrehZahl;
    
      public:
    
      cMotor (string mHersteller_, int nennDrehZahl_);
      void mAusgabe (void);
      string getHersteller(void){return mHersteller;}
      int getDrehZahl(void){return nennDrehZahl;}
    };
    //--------------------------------------------------------------------------
    
    cMotor::cMotor (string mHersteller_, int nennDrehZahl_)
    {
      mHersteller=mHersteller_;
      nennDrehZahl=nennDrehZahl_;
    }
    
    //--------------------------------------------------------------------------
    
    void cMotor::mAusgabe (void)
    {
      cout<<endl<<endl
    	  <<" Allgemeines Motorobjekt "<<endl<<endl
    	  <<mHersteller<<"    "<<nennDrehZahl<<endl;
    }
    
    //--------------------------------------------------------------------------
    //Klasse cMotor Ende
    //--------------------------------------------------------------------------
    //--------------------------------------------------------------------------
    //Klasse cEMotor Beginn
    //--------------------------------------------------------------------------
    
    class  cEMotor : public cMotor
    {
      private:
    
      string mTyp;
      double leistung;
      cAnker rot;
    
      public:
    
      cEMotor (string mTyp_, double leistung_);
      void mAusgabe(void); // Ausgabe der Kenndaten
      double getLeistung(void){return leistung;}
      string getTyp (void) {return mTyp;}
    };
    
    cEMotor::cEMotor (string mTyp_, double leistung_)
    {
      mTyp=mTyp_;
      leistung=leistung_;
    }
    //--------------------------------------------------------------------------
    //Klasse cEmotor Ende
    //--------------------------------------------------------------------------
    
    //--------------------------------------------------------------------------
    //Klasse cAnker Beginn
    //--------------------------------------------------------------------------
    class cAnker
    {
    
      private:
    
      double ankerStrom;
      double ankerWiderstand;
      int spulenWindungsZahl;
    
      public:
    
      cAnker(int spulenWindungsZahl_, double ankerWiderstand_, double ankerStrom_);
      int getWindungsZahl (void); //Rueckgabe ...
      double getWiderstand (void);
      double getStrom (void);
    
    };
    //--------------------------------------------------------------------------
    // Klasse cAnker Ende
    //--------------------------------------------------------------------------
    

    Ich hoffe das ist nicht zu unuebersichtlich 😃 Vermutlich wird das eine Banalitaet fuer die Meisten von euch sein, ich aber weis nicht mehr weiter...

    Vielen Dank schonmal fuer anregungen und Hinweise.

    EDIT by Phoemuex: Code-Tags -> C++-Tags



  • Hallo,

    ich habe mir jetzt nicht deinen kompletten Code durchgelesen, deshalb nur einige Sachen:

    Dein größtes Problem scheint hier beim Aufruf des Konstruktors/erstellen eines Objekts zu sein.

    Neutron schrieb:

    cMotor a(mHersteller=a.getHersteller(), nennDrehZahl=a.getDrehZahl());
    

    Was denkst du denn, was das machen soll? Weißt du, wie "normale" Funktionen aufgerufen werden? Ein Konstruktoraufruf unterscheidet sich davon nicht wesentlich.

    Wenn du zum Beispiel eine Funktion f: R -> R, x |-> x^2 hast, dann schreibst du doch auch f(3) und nicht f(x=3), oder? Und weiter erzeugst du in der Zeile doch erst das Objekt a und benutzt es dann als Parameter für die Erzeugung...

    Eigentlich wollte ich es nicht direkt verraten, aber es sollte wohl

    cMotor a(mHersteller, nennDrehZahl);
    

    heißen.

    Weiteres: Man benutzt kein

    using namespace std;
    

    in Header-Dateien, weil damit jeder, der deinen Header einbindet, direkt ganz std in den globalen Namensraum geklatscht kriegt, was das Konzept von Namespaces ad absurdum führt.

    Außerdem ist system("pause"); nicht das Gelbe vom Ei, eine bessere Lösung gibt es hier.

    Bei den Konstrkutoren könntest du übrigens Initialisierunglisten verwenden!

    EDIT: Außerdem fehlen natürlich die notwendigen Includes, um string, cout, ... verwenden zu können, also: #include <iostream> #include <string>, ...

    EDIT 2: Das void in den Parameterlisten von Funktionen ist in C++ unnötig, das kommt nur noch von C. Es reicht also

    int getDrehzahl();
    

    . Außerdem sollten Getter eigentlich const sein, also

    int getDrehZahl() const;
    

    , damit sie auch für konstante Objekte der Klasse aufgerufen werden können.

    Felix

    P.S.: Das waren vielleicht etwas viele Dinge, aber falls du estwas nicht verstehst/noch Fragen hast, dann frag :p



  • Danke schonmal fuer die schnelle Antwort 🙂

    Das mit dem Aufruf dachte ich mir schon, war irgendwann so Verzweifelt das ich einfach wild rumprobiert habe...

    Mein groesstes Problem liegt jetzt eigentlich darin, geeignete Kostruktoren zu schreiben.
    Ich weiss nicht wie ich die Basisklasse (cMotor) in den Konstruktor (welcher ausserhalb des Klassenrumpfes erstellt werden soll) der Klasse "cEMotor" einbrigen soll. Also wie man das vernuenftig initialisiert.

    Ich habe es jetzt mal so versucht:

    cEMotor::cEMotor (string mHersteller_, string mTyp_, double leistung_, int nennDrehZahl_)
    {
      mHersteller=mHersteller_;
      mTyp=mTyp_;
      leistung=leistung_;
      nennDrehZahl=nennDrehZahl_;
    }
    

    wobei mHersteller und nennDrehZahl bestandteile von cMotor sind. Klappt aber nicht 😃

    Und wie schaffe ich es das cAnker ein fester Bestandteil von cEMotor wird, denn ohne Anker funktioniert ein E-Motor nicht 😉

    Habe das so:

    class  cEMotor : public cMotor
    {
      private:
    
      string mTyp;
      double leistung;
      cAnker rot;
    
      public:
    
      cEMotor (string mHersteller_, string mTyp_, double leistung_, int nennDrehZahl_ );
      void mAusgabe(void); // Ausgabe der Kenndaten
      double getLeistung(void){return leistung;}
      string getTyp (void) {return mTyp;}
    };
    

    versucht, klappt jedoch auch nicht, als Fehlermeldung gibt er mir :[C++ Fehler] UMotor.h(57): E2303 Typname erwartet und [C++ Fehler] UMotor.h(57): E2139 In Deklaration fehlt ; .

    Vielen Dank duer eure/deine Hilfe 😃



  • Initialisierungsliste heisst hier das magische Wort.

    Und den ctor der Basisklasse kannst du dann so aufrufen:

    cEMotor::cEMotor (string mHersteller_, string mTyp_, double leistung_, int nennDrehZahl_)
    :
    cMotor( mHersteller_, nennDreZahl_), // ctor der Basisklasse aufrufen
    mTyp ( mTyp_ ), // andere Member initialisieren
    leistung ( leistung_ ) // dito
    {
    }
    


  • Nimm doch bitte cpp-Tags statt die Code-Tags... ist doch direkt links daneben - da klappt das auch mit der syntax-highlightning und es hat vll auch mal wer lust, sich das dann durchzulesen - einfach, weil man es dann auch erkennt ^^

    bb



  • unskilled schrieb:

    Nimm doch bitte cpp-Tags statt die Code-Tags... ist doch direkt links daneben - da klappt das auch mit der syntax-highlightning und es hat vll auch mal wer lust, sich das dann durchzulesen - einfach, weil man es dann auch erkennt ^^

    bb

    entschuldige bitte, habe jetzt mal editiert was ich konnte. Den ersten Beitrag habe ich leider als unreg. Benutzer verfasst, kann den also nicht mehr aendern.

    Werde ich in Zukunft auf jeden Fall beruecksichtigen 😃

    Danke nochmal fuer die Antworten, das hat mir schon viel weiter geholfen.

    Versuche es jetzt nochmal und melde mich nachher wieder ob es geklappt hat 👍



  • Also, es lauft jetzt soweit, nur wie ich die Member-beziehung zwischen cAnker und cEMotor herstelle ist mir schleierhaft.

    Ich habe in der Klasse cEMotor im Private-Bereich "cAnker rot;" mit aufgefuehrt.

    Hier der entsprechende Codeausschnitt:

    class  cEMotor : public cMotor
    {
      private:
    
      string mTyp;
      double leistung;
      string mHersteller;
      int nennDrehZahl;
      cAnker rot;
    

    und hier meine Klasse cAnker:

    class cAnker
    {
    
      private:
    
      double ankerStrom;
      double ankerWiderstand;
      int spulenWindungsZahl;
    
      public:
    
      cAnker(double ankerStrom_, double ankerWiderstand_, int spulenWindungsZahl_);
      double getStrom (void){return ankerStrom;}
      double getWiderstand (void){return ankerWiderstand;}
      int getWindungsZahl (void) {return spulenWindungsZahl;}
    };
    
    //--------------------------------------------------------------------------
    
    cAnker::cAnker(double ankerStrom_, double ankerWiderstand_, int spulenWindungsZahl_)
    {
      ankerStrom=ankerStrom_;
      ankerWiderstand=ankerWiderstand_;
      spulenWindungsZahl=spulenWindungsZahl_;
    }
    

    cAnker muss ein fester Bestandteil von cEMotor sein, komme aber nicht drauf wie ich das realisieren kann.
    Haengt das evtl. mit der Reihenfolge zusammen in welcher ich das in die Entwicklungsumgebung eingegeben habe?


Anmelden zum Antworten