warum stürzt das ab(push_back bei vector)



  • @Boris: Praktisch ja - technisch läuft das eher auf Initialisierungslisten hinaus:

    Klasse::Klasse(const Klasse& src)
    : Basis(src)
    , V_1(src.V_1)
    ,
    ...
    , V_N(src.V_N)
    {}
    

    @pixartist: op= hat etwas andere Anforderungen als der CCtor (unter anderem braucht letzterer keinen Test auf Selbstzuweisung und muß die alten Objektdaten nicht freigeben).



  • CStoll schrieb:

    @Boris: Praktisch ja - technisch läuft das eher auf Initialisierungslisten hinaus:

    Klasse::Klasse(const Klasse& src)
    : Basis(src)
    , V_1(src.V_1)
    ,
    ...
    , V_N(src.V_N)
    {}
    

    @pixartist: op= hat etwas andere Anforderungen als der CCtor (unter anderem braucht letzterer keinen Test auf Selbstzuweisung und muß die alten Objektdaten nicht freigeben).

    hmm, wieso kann ich eigentlich beim operator= auf private's vom parameter zugreifen ? (und geht das auch beim copy ctor? )

    was sind die anderen "anderen anforderungen" ?



  • class Particle 
    { 
    public: 
        //contructor 
        Particle( SDL_Surface *img, Vektor *grav, Uint32 bgColor, int lifeTime = 0, double xpos = 0, double ypos = 0, double xvel = 0, double yvel = 0); 
    
        const Particle& operator=(const Particle &right); 
        void addFadeStruct(fadeStruct fs); 
        void move(SDL_Surface *surf); 
        SDL_Surface* getSprite(); 
        //dtor 
        virtual ~Particle(); 
    
        //x,y, gravity, alive vals usw. 
        Vektor position; //<-- Tiefe Kopie
        Vektor velocity; //<-- Tiefe Kopie
        Vektor *gravity;  // <-- inhalt des Pointers für das neue Objekt mit new anlegen
    
        bool alive; //<-- einfach zuweisung
        Uint32 bgColor; //<-- einfach zuweisung
    private: 
        SDL_Surface *sprite; // <-- inhalt des Pointers für das neue Objekt mit new anlegen
    
        int spawntime; //<-- einfach zuweisung
        int lifetime; //<-- einfach zuweisung
        Uint32 replaceColor; //<-- einfach zuweisung
        bool hasFadeStruct;   //<-- einfach zuweisung
        fadeStruct fade; //<-- einfach zuweisung (jenachdem was da drin ist)
        Uint32 *sprPixels; // <-- inhalt des Pointers für das neue Objekt mit new anlegen
    
    };
    

    bei einem Poibnter komm es drauf an ob du für jede Instanz ein Objekt anlegen muss und dese npointer speicherst, oder ob du über den pointer ein externe Objekt referenzierst!



  • Erstens: private gilt auf Klassenebene, nicht auf Objektebene.

    Zweitens: Der Copy-Ctor erzeugt eine Kopie aus dem Nichts, der op= ersetzt ein bestehendes Objekt - das sind schon ganz andere Arbeitsbedingungen. Das bedeutet auch, daß der Copy-Ctor keine Tests auf Selbstzuweisung durchführen muß (this ist immer ein jungfräuliches Objekt) und auch keine Alt-Daten entsorgen muß.



  • Ich werde es wohl ausprobieren müssen. 😛
    Ausserdem ist der Grundansatz wohl eher ungeignet da sich auf die Art den Juds nur Kinder zugewiesen können bevor sie selbst in ein übergeordneten Hud gesteckt werden.



  • ähh was soll denn das jetzt ?

    __thiscall Particle::Particle(class Particle const &)" (??0Particle@@QAE@ABV0@@Z) bereits in Particle.obj definiert



  • Hast du vielleicht versucht, den Copy-Ctor direkt im Header zu definieren?



  • CStoll schrieb:

    Hast du vielleicht versucht, den Copy-Ctor direkt im Header zu definieren?

    nö:

    class Particle
    {
    public:
    	//contructor
    	Particle( SDL_Surface *img, Vektor *grav, Uint32 bgColor, int lifeTime = 0, double xpos = 0, double ypos = 0, double xvel = 0, double yvel = 0);
    	//copy ctor
    	Particle(const Particle &right);
    
    	const Particle& operator=(const Particle &right);
    	void addFadeStruct(fadeStruct fs);
    	void move(SDL_Surface *surf);
    	//dtor
    	virtual ~Particle();
    
    	//x,y, gravity, alive vals
    	Vektor position;
    	Vektor velocity;
    	Vektor *gravity;
    	bool alive;
    	Uint32 bgColor;
    private:
    	SDL_Surface *sprite;
    	int spawntime;
    	int lifetime;
    	Uint32 replaceColor;
    	bool hasFadeStruct;
    	fadeStruct fade;
    	Uint32 *sprPixels;
    
    };
    


  • Und wo stehen die dazugehörigen Methodendefinitionen? (btw, bei welcher Datei beschwert sich eigentlich der Linker?)



  • CStoll schrieb:

    Und wo stehen die dazugehörigen Methodendefinitionen? (btw, bei welcher Datei beschwert sich eigentlich der Linker?)

    in der Particle.ccp 😉

    #include "Particle.h"
    
    //contructor
    Particle::Particle(SDL_Surface *img, Vektor *grav, Uint32 bgColor, int lifeTime, double xpos, double ypos, double xvel, double yvel)
    {
    	gravity = grav;
    	sprite = img;
    	position.x = xpos;
    	position.y = ypos;
    	velocity.x = xvel;
    	velocity.y = yvel;
    	alive = true;
    	spawntime = SDL_GetTicks();
    	lifetime = lifeTime;
    	replaceColor = bgColor;
    	hasFadeStruct = false;
    	sprPixels = (Uint32 *)sprite->pixels;
    }
    Particle::Particle(const Particle &p)
    {
    	gravity = p.gravity;
    	sprite = p.sprite;
    	sprite->refcount++;
    
    	position = p.position;
    	velocity = p.velocity;
    	alive = true;
    	spawntime = SDL_GetTicks();
    	lifetime = p.lifetime;
    	replaceColor = p.replaceColor;
    	hasFadeStruct = p.hasFadeStruct;
    	sprPixels = (Uint32 *)sprite->pixels;
    	if(hasFadeStruct)
    		fade = p.fade;
    }
    
    const Particle& Particle::operator=(const Particle &right)
    {
    	if(this != &right)
    	{
    		gravity = right.gravity;
    		gravity = right.gravity;
    		sprite = right.sprite;
    		sprite->refcount++;
    		position = right.position;
    		velocity = right.velocity;
    		alive = true;
    		spawntime = SDL_GetTicks();
    		lifetime = right.lifetime;
    		replaceColor = right.replaceColor;
    		hasFadeStruct = right.hasFadeStruct;
    		sprPixels = (Uint32 *)sprite->pixels;
    		fade = right.fade;
    	}
    	return *this;
    }
    ....
    


  • pixartist schrieb:

    CStoll schrieb:

    Und wo stehen die dazugehörigen Methodendefinitionen? (btw, bei welcher Datei beschwert sich eigentlich der Linker?)

    in der Particle.ccp 😉

    Und bei welcher Datei beschwert sich der Linker?

    Bindest du irgendwelche .cpp-Dateien mittels Includedirektive in andere ein?



  • MFK schrieb:

    pixartist schrieb:

    CStoll schrieb:

    Und wo stehen die dazugehörigen Methodendefinitionen? (btw, bei welcher Datei beschwert sich eigentlich der Linker?)

    in der Particle.ccp 😉

    Und bei welcher Datei beschwert sich der Linker?

    Bindest du irgendwelche .cpp-Dateien mittels Includedirektive in andere ein?

    achso ja:

    PSpawner.obj : error LNK2005: "public: __thiscall Particle::P...
    


  • Und wie kommt die Definition des Particle-Copykonstruktors in PSpawner.cpp?



  • MFK schrieb:

    Und wie kommt die Definition des Particle-Copykonstruktors in PSpawner.cpp?

    hmm

    Particle pt(t, gravity, replaceColor, lifetime, pos.x, pos.y, direction.x, direction.y);
    

    hatte es verursacht...
    jetzt gehts 🙂



  • WOW wusstet ihr, dass die vector klasse die enthaltenen objekte nicht nur im ram rumschiebt, sonder auch ständig kopiert und dabei den copy ctor aufruft? ich hab die spawntime des partikels im copy ctor immer auf getticks() gesetzt, und mich gewundert, warum die partikel im flug ständig "resetted" werden...da muss man erstmal drauf kommen....



  • Die vector-Klasse ist eben auch nicht das Maß aller Dinge 🙂



  • Badestrand schrieb:

    Die vector-Klasse ist eben auch nicht das Maß aller Dinge 🙂

    Wenn man sich anschaut warum der ctor verwendet wird, und warum die Entscheidung den Vector so zu definieren erfolgt ist, wird man feststellen, das der Vector vielleicht nicht das Maß aller Dinge ist, aber dennoch seinen Sinn hat. Man muss ihn natürlich verstehen und entsprechent sinnvoll einsetzen...

    std::vector ist nicht ohne Grund eigentlich der Standardcontainer.

    cu André



  • hmm ich hab da noch ein kleines problem:

    in meiner hauptprogrammschleife läuft jetzt folgendes ab:

    int downC = 0;
    		int pls = pList.size();
    		for(int i = 0; i < pls-downC ; i++)
    		{
    			if(pList.at(i-downC).alive)
    			{
    				pList.at(i-downC).move(screen);
    			}
    			else
    			{
    				pList.at(i-downC).~Particle();
    				pList.erase( pList.begin( ) + (i-downC));
    				downC++;
    			}
    		}
    

    jetzt passier folgendes:
    sagen wir ich hab 200 partikel in der liste, welche alle zum gleichen zeitpunkt "sterben".
    komischerweise ist die größe con pList dann nich sofort 0, sondern wird jedes frame um einen runtergezählt oO wenn aber alle zur gleichen zeit sterben, müsste er doch auch alle in einem schleifendurchlauf löschen oder?
    wär ja nich so schlimm, wenn nich die anzahl der partikel dann unendlich wächst, wenn ich in jedem frame z.B. 2 partikel erstelle und gleichzeitig 2 lösche....



  • was soll den das?

    pList.at(i-downC).~Particle();
    

    du rufst den destruktor selber auf??
    Ist doch nich nötig

    wenn du bspw. das letzte elemet des vectors löschen willst:

    pList.erase(pList.end());
    

    das letze objekt im vector wird nun zerstört d.h. der destruktor von diesem objekt wird automatisch aufgerufen.

    pList.pop_back();
    

    das letzte bzw. ungültige zerstöre element wird nun aus dem vector gemommen.

    Also müsste es so aussehen:

    int downC = 0;
            int pls = pList.size();
            for(int i = 0; i < pls-downC ; i++)
            {
                if(pList.at(i-downC).alive)
                {
                    pList.at(i-downC).move(screen);
                }
                else
                {
                    pList.erase(pList.end()); //letzes objekt zerstören
                    pList.pop_back();  //letzte objekt vom vecotr kicken
                    downC++;
                }
            }
    

    P.S. Wenn ich da nen fehlter habe Sorry,, habe noch nich viel mit vector gemacht.



  • pixartist schrieb:

    komischerweise ist die größe con pList dann nich sofort 0, sondern wird jedes frame um einen runtergezählt oO wenn aber alle zur gleichen zeit sterben, müsste er doch auch alle in einem schleifendurchlauf löschen oder?

    Eigentlich schon. Nimm erst mal den direkten Aufruf des Destruktors da raus. Das ist nicht nur unnötig, sondern falsch.

    Wenn du rückwärts durch deinen Vektor läufst (statt vorwärts, wie jetzt), brauchst du auch das Gehampel mit downC nicht mehr. Das sollte den Code weiter vereinfachen. Wenn der Fehler dann immer noch auftritt, sag Bescheid.

    Und wenn du andauernd mittendrin Objekte löschst und immer nur komplett durchiterierst und nie mittels Index gezielt auf einzelne Objekte zugreifen musst, dann ist vector der falsche Container.

    BorisDieKlinge schrieb:

    wenn du bspw. das letzte elemet des vectors löschen willst:

    pList.erase(pList.end());
    

    Das ist falsch. end() zeigt nicht auf das letzte Element, sondern dahinter. Außerdem will pixartist ja ein bestimmtes Element löschen, nicht das letzte.


Anmelden zum Antworten