Fehler bei der



  • Hallo Leute,
    ich muss in einer Aufgabe drei Klassen anlegen:

    1. abstrakte Basisklasse Material (Schnittstelle zu den von ihr abgeleiteten Klassen Schraube und Mutter)
    2. Klasse Schraube
    3. Klasse Mutter
      und habe dies nachstehend programmiert.
    class Material {
    	public:
    		char Name;
    		float Preis;
    		long Anzahl;
    		char Typ;
    		
    		void getName(char n) {
    			n=Name;
    		}
    		void getPreis(float p) {
    			p=Preis;
    		} 
    		void getAnzahl(long a) {
    			a=Anzahl;
    		}
    		virtual void setAnzahl(void)=0;
    };
    
    class Schraube:public Material{
    	public:
    		void setAnzahl(int AnzahlNeu){
    			AnzahlNeu=Anzahl;
    		}
    };
    
    class Mutter:public Material{
    	public:
    		long passend;
    		void setAnzahl(int AnzahlNeu){
    			AnzahlNeu=Anzahl;
    		}
    };
    
    int main() {
    	using namespace std;
    	Schraube schr;
    	schr.getName('K');
    	schr.getAnzahl(125);
    	schr.getPreis(1.25);
    

    Bei der Definition von schr bringt mir der Compiler "Cannot declare variable 'schr' to be of abstract type 'Schraube' because the following virtual functions are pure within 'Schraube'
    virtual void Material:setAnzahl()

    Wo ist denn da der Haken, ich seh´s nicht.

    Danke für jede Info!



  • @totaler-anfänger sagte in Fehler bei der:

    setAnzahl

    Du hast zwei verschiedene setAnzahl Funktionen programmiert. Schau dir sie mal genau an.



  • Hallo out,
    sorry, ich hänge seit gestern Abend an dieser Aufgabe und bin im Moment total betriebsblind.
    Ich komme nicht drauf.



  • virtual void setAnzahl(void);
            void setAnzahl(int AnzahlNeu);
    

    Gibts einen Unterschied?
    Sämtliche Get-Funktionen machen außerdem nicht das, was man sich gemeinhin darunter vorstellt. Was du dir darunter vorstellst, ist mir jedoch auch nicht ganz klar...
    Beschreib mal, was schr.getAnzahl(125); genau machen soll.



  • virtual void setAnzahl(void)
    Eine Set Funktion ohne Set-Funktionalität, was ne Ironie.



  • Ein Name, der nur aus einem Zeichen besteht?



  • Ich denke, Ihr seht genau, dass hier ein Mega-Anfänger am Werk ist, der zugegebenermaßen einige Sachen (hoffentlich nur "noch") nicht verstanden hat. Folgende Aufgabenstellung habe ich erhalten und muss trotzdem schauen, wie ich sie umsetze:

    Folgende Klassen sind vorgesehen:

    • abstrakte Basisklasse Material: diese bildet lediglich die Schnittstelle zu den von
      ihr abgeleiteten Klassen Schraube und Mutter. Von dieser Klasse Material
      sollen keine Objekte instanziiert werden können. Dafür sind in dieser abstrakten
      Klasse die Attribute Name, Preis, Anzahl und Typ vorgesehen. Zudem
      deklariert die Klasse Material bereits die abstrakten Funktionen getName(),
      getAnzahl() und getPreis(), sowie eine virtuelle Funktion zum Verändern
      (erhöhen / verringern) der Anzahl.
    • die Klassen Schraube, Mutter: diese Klassen instanziieren die eigentlichen
      Objekte. Beispielsweise kann es eine Schraube namens „Kreuzschlitz 5 mm“
      (getName()) geben, die 1,25 Euro kostet (getPreis()) und von der sich aktuell
      noch 125 Stück (getAnzahl()) im Lager befinden, sowie eine passende Mutter
      namens „Flügel 5 mm“ geben, die 0,50 Euro kostet und von der noch 10 Stück im
      Lager sind.
    • Die Klasse Mutter besitzt zudem als Attribut einen Zeiger auf eine evtl. passende
      Schraube. Zum Beispiel passt zur Flügelmutter die Schraube „Kreutzschlitz 5 mm“.

    Und da ich nicht mehr weiter weiß - try & error geht halt nur bis zu einem bestimmten Punkt - habe ich mich hier an die Community gewandt.



  • @yahendrik
    Ich wollte lediglich den Wert Anzahl auf 125 setzen,
    vermutlich geht das eigentlich mit
    schr.Anzahl = 125



  • @totaler-anfänger sagte in Fehler bei der:

    Und da ich nicht mehr weiter weiß - try & error geht halt nur bis zu einem bestimmten Punkt - habe ich mich hier an die Community gewandt.

    Hier ist nicht die Aufgabenlösecommunity für Leute die im Unterricht geschlafen haben.



  • @manni66
    Und genau deshalb habe ich mich vorher auch damit beschäftigt, es selbst hin zu bekommen (siehe Threaderöffnung), Tutorials angeschaut, gegooglet, etc.
    Jetzt habe ich hier einen Code, der nicht funktioniert, wie er soll - so, wie es jedem Programmierer oder auch C++-Guru vielleicht mal passiert. Und deshalb wendet man sich doch an Helfer in Foren, die dann nicht gleich die Augenbrauen hochziehen, sondern auch dem Anfänger bei seinen Basisfehlern Unterstützung geben, so wie sie bei Fehlern der Cracks dann ihren Hirnschmalz mal zum Kochen bringen können. Ich gehöre leider zur ersten Kategorie und habe so ein bisschen das Gefühl, dass sich hier teilweise auch "Helfende" bewegen, die blutige Anfänger als Last sehen. Denn auch in diesem Forum habe ich einige Threads durchstöbert, bevor ich mich angemeldet habe. Und da ist immer gleich vom faulen "Schüler" die Rede, der nur seine Aufgaben gelöst haben will. Ich bin relativ sicher, dass dies in den meisten Fällen eben nicht so ist. Und vielleicht noch ein kleines Beispiel: Ich selbst unterstütze Leute, die z.B. mit Excel und VBA Probleme haben. Und erst vorgestern sagte ein Maschinenbau-Student zu mir: "Ja, wenn uns der Dozent das auch so erklärt hätte, würde man es auch verstehen." - Jeder fängt mal an 😉
    Nochmals Danke allen, die helfen!



  • Wenn du in einer abgeleiteten Klasse eine virtuelle Methode implementieren willst, solltest du das Schlüsselwort "override" verwenden. Dann meckert der Compiler, wenn du da Tippfehler drin hast.

    Für den Namen solltest du std::string verwenden.

    Und zur Namenskonvention: Mit "SetXZY(x);" setzt du einen Wert, mit "x = a.GetXYZ()" lässt du den Wert rausgeben. Getter sind daher normalerweise auch "const", da der Zustand der Instanz nicht verändert wird.



  • Und um noch mehr Hilfe zu geben:

    Wenn du eine Funktion überschreibst (override), dann müssen die Funktionsargumente dieselben Typen haben. Ansonsten überlädst du die Funktionen nur und hast dann 2 unterschiedliche Funktionen mit demselben Namen.

    In deinem Beispiel hattest du ein

    void setAnzahl(void);  // ohne Parameter*, aus der Basisklasse
    void setAnzahl(int); // mit einem int-Parameter, aus der Schraube
    

    [*] in C++ kannst du besser void setAnzahl(); schreiben und das void weglassen - das void in der Klammer zum Anzeigen einer leeren Parameterliste wird nur in C benötigt, nicht aber in C++ (abgesehen davon, dass setAnazhal ohne Parameter keinen Sinn ergibt, du hier also einen Parameter benötigst)

    Set-Funktionen sollten grundsätzlich ein Argument haben, get-Funktionen dagegen 0 Argumente.

    Zum Überschreiben lies dir bitte auch https://en.cppreference.com/w/cpp/language/override durch.
    Die anderen Hinweise hier waren auch alle sinnvoll!



  • @wob sagte in Fehler bei der:

    get-Funktionen dagegen 0 Argumente

    Nicht unbedingt man kann schon getter haben mit Argumenten. Wenn ich einen Rückgabewert für einen bestimmtes Argument anfordere. Beispielsweise wenn ich eine Übersetzung anfordere übergebe ich die Sprache in der ich die Übersetzung gerne habe.

    Aber eine get-Funktion die nichts zurückliefert macht auf jeden Fall keinen Sinn. So wie das hier aber aussieht sind die getter aber sowieso setter die falsch benannt wurden.



  • @totaler-anfänger sagte in Fehler bei der:

    void getPreis(float p) {
    p=Preis;

    Obwohl wenn ich mir das recht anschaue, ich bin verwirrt. Die Funktion macht in diesem fall überhaupt nichts.
    Setzt die loakle variable p auf den Wert des fields (Preis)?

    Wahrscheinlich:

    float getPreis() { return Preis; }
    

    und dann natürlich

    private:
     float Preis;
    

    Und genau deshalb habe ich mich vorher auch damit beschäftigt, es selbst hin zu bekommen?

    die Beschäftigung war aber nicht sehr lange denn das hätte man mit jedem Anfänger Tutorial raus bekommen.


Log in to reply