[SOLVED] Kein geeigneter Standardkonstruktor



  • Hallo liebe Freunde des Programmierens,

    ich habe in C++ in einem Framework für Spiele in 2D, welches ich gerade schreibe, eine Klasse implementiert, die für das Laden und Zeichnen von Bildern bzw. Texturen zuständig ist, eine Texture Klasse halt. Allerdings erhalte ich die Fehlermeldung, dass kein geeigneter Standardkonstruktor verfügbar ist. Ich habe dann folgendes hinzugefügt:

    Texture()
    {
    
    }
    

    Dann war der Fehler auch weg, dennoch frage ich mich, wieso ich den Konstruktor so hinschreiben muss. Eigentlich übernimmt doch C++ für mich die Aufgabe einen Konstruktor hinzuzufügen, wenn ich das nicht explizit tue.

    Hier der Code meiner Texture Klasse ohne Konstruktor (also mit dem Fehler), falls das überhaupt nötig ist:

    // --- Texture.h ---
    
    // general class to handle loading and drawing images
    
    #ifndef __Texture__
    #define __Texture__
    
    #include "Vector2D.h"
    #include "Standard.h"
    
    class Texture
    {
    	private:			
    
    		// basic SDL objects
    
    		SDL_Surface* surface;
    		SDL_Texture* texture;
    		SDL_Renderer* renderer;
    
    		// basic rectangles for texture
    
    		SDL_Rect sourceRectangle;
    		SDL_Rect destinationRectangle;			
    
    		// simple variables 
    
    		int currentFrame;	
    		int currentRow;	
    		int frames;		
    		int sourceWidth;
    		int sourceHeight;
    
    	public:	
    
    		// load
    
    		void LoadImgTexture(string textureID, const char* filePath, Vector2D texturePosition, int textureWidth, int textureHeight, SDL_Renderer* textureRenderer);
    		void LoadObjTexture(const char* filePath, Vector2D texturePosition, int textureWidth, int textureHeight, int textureFrames, SDL_Renderer* textureRenderer);
    
    		// update
    
    		void Update(int latestFrame, int latestRow, Vector2D texturePosition, int textureWidth, int textureHeight); 
    		void Update(int latestFrame, int latestRow, Vector2D texturePosition);
    		void Update(int latestFrame, int latestRow);
    
    		// draw
    
    		void Draw(SDL_RendererFlip SDL_Flip);	
    
    		// clean
    
    		void Clean();
    
    		int width;
    		int height;
    
    		Vector2D position;
    };	
    
    #endif __Texture__
    

    Ich hoffe, jemand kann mir helfen.


  • Mod

    Eigentlich übernimmt doch C++ für mich die Aufgabe einen Konstruktor hinzuzufügen, wenn ich das nicht explizit tue.

    Korrekt. Aber dieser Konstruktor ist nicht immer nutzbar. Er wird com Compiler als deleted definiert (sprich, als unnutzbar), wenn einige Voraussetzungen nicht stimmen.

    Allerdings müssen alle Voraussetzungen stimmen, da der von dir definierte Defaultkonstruktor, Texture () {} , einwandfrei zu funktionieren scheint.

    Gehe ich richtig in der Annahme, dass du VC++ nutzt? Ich tippe auf einen Bug.

    Edit: Klappt es auch wenn du

    Texture() = default;
    

    schreibst?



  • Arcoth schrieb:

    Eigentlich übernimmt doch C++ für mich die Aufgabe einen Konstruktor hinzuzufügen, wenn ich das nicht explizit tue.

    Korrekt. Aber dieser Konstruktor ist nicht immer nutzbar. Er wird com Compiler als deleted definiert (sprich, als unnutzbar), wenn einige Voraussetzungen nicht stimmen.

    Allerdings müssen alle Voraussetzungen stimmen, da der von dir definierte Defaultkonstruktor, Texture () {} , einwandfrei zu funktionieren scheint.

    Gehe ich richtig in der Annahme, dass du VC++ nutzt? Ich tippe auf einen Bug.

    Edit: Klappt es auch wenn du

    Texture() = default;
    

    schreibst?

    Ja ich nutze VC++ (Visual Studio 2012). Aber wenn ich den Konstruktor auf default setzte, kommen diese Fehler:

    Fehler 10 error C2253: "Texture": Ein reiner Spezifizierer oder ein abstrakter Überschreibungsspezifizierer ist nur für eine virtuelle Funktion zulässig.

    Fehler 3 error C2065: 'default': nichtdeklarierter Bezeichner

    Und zwar kommt jeder Fehler 5 mal. Komisch.


  • Mod

    Und zwar kommt jeder Fehler 5 mal.

    Wahrscheinlich weil du den Header in fünf Übersetzungseinheiten (=Source-Dateien) einbindest.

    VS 2012 unterstützt default wahrscheinlich noch nicht.

    In dem Fall: Bug. Schreib einfach deine Definition hin und fertig.



  • Es ist außerdem so, dass der gleiche Fehler mit dem fehlenden geeigneten Standardkonstruktor auch in meiner Vector2D Klasse entstand. Ich habe also auch in der Vector2D Klasse einfach einen leeren Konstruktor hinzugefügt.

    Vector2D()
    {
    }
    

    Ich inkludiere ja die Vector Klasse ja auch in meiner Texture.h, vielleicht hängt das irgendwie miteinander zusammen. Hier ist die ganze Vector2D Klasse:

    // --- Vector2D.h ---
    
    // Vector2D class handling position of objects
    
    #ifndef __Vector2D__
    #define __Vector2D__
    
    #include "Standard.h"
    
    // Vector2D for position and movement of game objects
    
    class Vector2D
    {
    	public:
    
    		// coordinates
    
    		float x;
    		float y;
    
    		// constructor
    
    		Vector2D(float x, float y);		
    
    		Vector2D()
    		{			
    		}
    
    		// methods
    
    		float Length();
    		void Normalize();
    
    		// adding vectors [+]
    
    		Vector2D operator+(const Vector2D &v) const
    		{
    			return Vector2D(x + v.x, y + v.y);
    		}
    
    		// adding vectors [+=]
    
    		friend Vector2D& operator+=(Vector2D &v1, const Vector2D &v2)
    		{
    			v1.x += v2.x;
    			v1.y += v2.y;
    
    			return v1;
    		}
    
    		// multiplying by scalar number [*]
    
    		Vector2D operator*(float scalar)
    		{
    			return Vector2D(x * scalar, y * scalar);
    		}
    
    		// multiplying by scalar number [*=]
    
    		Vector2D& operator*=(float scalar)
    		{
    			x *= scalar;
    			y *= scalar;
    
    			return *this;
    		}
    
    		// subtracting vectors [-]
    
    		Vector2D operator-(const Vector2D &v) const
    		{
    			return Vector2D(x - v.x, y - v.y);
    		}
    
    		// subtracting vectors [-=]
    
    		friend Vector2D& operator-=(Vector2D &v1, Vector2D &v2)
    		{
    			v1.x -= v2.x;
    			v1.y -= v2.y;
    
    			return v1;
    		}
    
    		// dividing by scalar number [/]
    
    		Vector2D operator/(float scalar)
    		{
    			return Vector2D(x / scalar, y / scalar);
    		}
    
    		// dividing by scalar number [/=]
    
    		Vector2D& operator/=(float scalar)
    		{
    			x /= scalar;
    			y /= scalar;
    
    			return *this;
    		}
    
    };
    
    #endif __Vector2D__
    


  • Arcoth schrieb:

    Und zwar kommt jeder Fehler 5 mal.

    Wahrscheinlich weil du den Header in fünf Übersetzungseinheiten (=Source-Dateien) einbindest.

    VS 2012 unterstützt default wahrscheinlich noch nicht.

    In dem Fall: Bug. Schreib einfach deine Definition hin und fertig.

    Achso, ok. Dann ist es ein Bug. Ist ja auch so gesehen eigentlich gar kein Problem den Konstruktor da noch hinzuschreiben. 🙂



  • Ein Standardkonstruktor wird vom Compiler nur erzeugt, wenn es keinen anderen Konstruktor gibt. In Texture erzeugst du ein Vector2D-Objekt über den Standardkonstruktor, also bekommst du eine Fehlermeldung. Das Problem kann man entweder lösen, indem man Vector2D einen Standardkonstruktor gibt, oder indem man Texture einen Standardkonstruktor gibt, der Vector2D über einen der vorhandenen Konsturktoren erzeugt.

    Ich wundere mich nur über die Fehlermeldung deines Compilers, ich glaube es wäre sinnvoller gewesen, zuerst auf das Problem mit Vector2D hinzuweisen.


  • Mod

    Ohgottohgott - da hab' ich was völlig übersehen.
    Texture2D hat ja einen eigenen Konstruktor. In dem Fall wird natürlich kein Defaultkonstruktor für Texture2D generiert. Und somit auch nicht für Texture .

    Das ist natürlich kein Bug.



  • Bashar schrieb:

    Ein Standardkonstruktor wird vom Compiler nur erzeugt, wenn es keinen anderen Konstruktor gibt. In Texture erzeugst du ein Vector2D-Objekt über den Standardkonstruktor, also bekommst du eine Fehlermeldung. Das Problem kann man entweder lösen, indem man Vector2D einen Standardkonstruktor gibt, oder indem man Texture einen Standardkonstruktor gibt, der Vector2D über einen der vorhandenen Konsturktoren erzeugt.

    Ich wundere mich nur über die Fehlermeldung deines Compilers, ich glaube es wäre sinnvoller gewesen, zuerst auf das Problem mit Vector2D hinzuweisen.

    Nur durch die Deklaration einer Instanz von Vector2D

    Vector2D position;
    

    wird also schon der Standardkonstruktor von Vector2D aufgerufen und da ich den nicht definiert hatte, dafür nur einen eigenen überladenen Konstruktor

    Vector2D(float x, float y);
    

    kommt es zu der Fehlermeldung, habe ich das so richtig verstanden?

    Und dann brauche ich den Standardkonstruktor in der Texture Klasse gar nicht, sondern nur einen in der Vector2D.



  • huzzm schrieb:

    Nur durch die Deklaration einer Instanz von Vector2D

    Vector2D position;
    

    wird also schon der Standardkonstruktor von Vector2D aufgerufen und da ich den nicht definiert hatte, dafür nur einen eigenen überladenen Konstruktor

    Vector2D(float x, float y);
    

    kommt es zu der Fehlermeldung, habe ich das so richtig verstanden?

    Durch die bloße Deklaration passiert erstmal überhaupt nichts. Das Problem ist, dass der vom Compiler erzeugte Standardkonstruktor für Texture so aussieht:

    Texture()
    {
      // gähnene Leere
    }
    

    Jetzt sag mir, wenn ich eine Instanz von Texture anlege, wie wird der Vector2D-Member initialisiert?

    Du dagegen hättest die Möglichkeit, ihn z.B. so zu definieren:

    Texture()
      : position(0, 0)  // z.B.
    { }
    

    so dass kein Standardkonstruktor von Vector2D nötig wäre.

    Und dann brauche ich den Standardkonstruktor in der Texture Klasse gar nicht, sondern nur einen in der Vector2D.

    Oder so. Sich für eine der Möglichkeiten zu entscheiden ist das, was man Design nennt.



  • Bashar schrieb:

    huzzm schrieb:

    Nur durch die Deklaration einer Instanz von Vector2D

    Vector2D position;
    

    wird also schon der Standardkonstruktor von Vector2D aufgerufen und da ich den nicht definiert hatte, dafür nur einen eigenen überladenen Konstruktor

    Vector2D(float x, float y);
    

    kommt es zu der Fehlermeldung, habe ich das so richtig verstanden?

    Durch die bloße Deklaration passiert erstmal überhaupt nichts. Das Problem ist, dass der vom Compiler erzeugte Standardkonstruktor für Texture so aussieht:

    Texture()
    {
      // gähnene Leere
    }
    

    Jetzt sag mir, wenn ich eine Instanz von Texture anlege, wie wird der Vector2D-Member initialisiert?

    Du dagegen hättest die Möglichkeit, ihn z.B. so zu definieren:

    Texture()
      : position(0, 0)  // z.B.
    { }
    

    so dass kein Standardkonstruktor von Vector2D nötig wäre.

    Und dann brauche ich den Standardkonstruktor in der Texture Klasse gar nicht, sondern nur einen in der Vector2D.

    Oder so. Sich für eine der Möglichkeiten zu entscheiden ist das, was man Design nennt.

    Alles klar. Danke 🙂



  • Guten Tag zusammen,

    nach dem ich diverse Threads durchgelesen habe, aber keins gefunden habe welches mir bei meinem Problem hilft, dachte ich mir das dieser Thread am nächsten zu meinem Problem passt auch wenn es einfacher ist als vom Threadersteller.

    Wie wende ich einen Konstruktor auf die Klasse an?
    Ich hab mir auch schon diverse Artikel zum Thema Konstruktor durchgelesen und folgendes kommt meiner Meinung nach bei mir raus, aber beim kompilieren bekomme ich ständig eine Fehlermeldung das mein Konstruktor falsch sei.
    Mein Konstruktor soll aber die Paramter a, name etc haben.

    Folgendes allg. Beispiel:

    class x{
      private:
      int a;
      sting name;
      ..etc..
    
       //Konstrukor so 
       x(int a, string name)
    
       //oder so?
      x::x(int a, string name)
    
      public:
    
    };
    

    Irgendwas habe ich missverstanden in diesem Thema. 😞



  • Warum machst du nicht einen eigenen Beitrag auf?

    Der Compiler sagt ganz sicher, was falsch ist! Warum verschweigst du das?

    Die erste Version ist richtig (sofern string bekannt ist). Allerdings ist der Kontruktor private. Möglicherweise ist das der Fehler.



  • mobile-freak schrieb:

    Guten Tag zusammen,

    nach dem ich diverse Threads durchgelesen habe, aber keins gefunden habe welches mir bei meinem Problem hilft, dachte ich mir das dieser Thread am nächsten zu meinem Problem passt auch wenn es einfacher ist als vom Threadersteller.

    Wie wende ich einen Konstruktor auf die Klasse an?
    Ich hab mir auch schon diverse Artikel zum Thema Konstruktor durchgelesen und folgendes kommt meiner Meinung nach bei mir raus, aber beim kompilieren bekomme ich ständig eine Fehlermeldung das mein Konstruktor falsch sei.
    Mein Konstruktor soll aber die Paramter a, name etc haben.

    Folgendes allg. Beispiel:

    class x{
      private:
      int a;
      sting name;
      ..etc..
      
       //Konstrukor so 
       x(int a, string name)
    
       //oder so?
      x::x(int a, string name)
    
      public:
      
    
    };
    

    Irgendwas habe ich missverstanden in diesem Thema. 😞

    Ich würde das folgendermaßen schreiben:

    class x{
    
    private:
    
    int a;
    sting name;  
    
    public:
    
    x(int a, string name)
    {
      // ...
    }  
    
    };
    


  • huzzm schrieb:

    ..

    Hi, danke. Jetzt klappt alles soweit.

    Hab den Teil bei mir gelöscht und nochmal abgetippt. Wahrscheinlich hatte ich noch irgendwo was vergessen.


Log in to reply