Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Błąd podczas usuwania elementu vectora

Ostatnio zmodyfikowano 2015-09-11 23:04
Autor Wiadomość
Gibas11
Temat założony przez niniejszego użytkownika
Błąd podczas usuwania elementu vectora
» 2015-09-11 21:38:52
Jak w tytule, mam klasę, zawierającą vector innej klasy i gdy chcę usunąć któryś element dostaję taki komunikat:

pure virtual method called
terminate called without an active exception
Aborted

Problem leży w linijce 313 w funkcji meteor::contains (linijka pod tą zakomentowaną). Mam na razie rozwiązanie na około z ustawianiem zmiennej exist na false w każdym elemencie do usunięcia i pomijaniem go przy jakichkolwiek operacjach, ale wolałbym go jednak usuwać.
C/C++
#ifndef SPACEOBJECTS_H_INCLUDED
#define SPACEOBJECTS_H_INCLUDED

namespace space
{
    sf::RenderTexture rt;
   
    class meteorPart
    {
    public:
       
        sf::Color color;
        sf::CircleShape hexagon;
       
        bool right = true;
        bool left = true;
        bool upDown = true;
        bool Rotated;
        bool exist;
       
        int HP;
       
        void create( sf::Color mask, sf::Vector2f pos, bool rotated, int polygons, int hp );
    };
   
    void meteorPart::create( sf::Color mask, sf::Vector2f pos, bool rotated, int polygons, int hp )
    {
        hexagon = sf::CircleShape( 29, polygons );
        hexagon.setFillColor( mask );
        hexagon.setOrigin( 20, 29 );
        hexagon.setPosition( pos );
        Rotated = rotated;
        exist = true;
        HP = hp;
       
        hexagon.setRotation(( int ) rotated * 60 );
    }
   
    class meteor
        : public sf::Drawable
    {
    public:
        vector < meteorPart > meteorParts;
       
        void startCreating( int m, sf::Vector2f Pos, int Polygons, int partsPerClock );
        void create();
        void update();
        void destroy();
       
        void setColor( sf::Color color );
        void move( sf::Vector2f vect );
        void move( float x, float y );
        void move();
       
        void push( sf::Vector2f vect, int mass );
       
        bool contains( sf::Vector2f point, int damage );
       
        sf::Color getColor();
        sf::Vector2f getPosition();
       
        bool created = false;
        bool creating = false;
        bool destroyed = false;
        bool moving;
       
        int lastDamage;
       
        sf::Vector2f pos;
    private:
        float momentumX;
        float momentumY;
       
        sf::Texture texture;
        sf::Sprite sprite;
        sf::FloatRect rect;
       
        virtual void draw( sf::RenderTarget & target, sf::RenderStates states ) const;
       
        unsigned int targetParts = 0;
        unsigned int currentParts = 0;
        unsigned int polygons;
        unsigned int parts;
       
        unsigned int HPPerPart = 40;
       
        int poz1P[ 2 ] = { 29, - 22 };
        int poz1L[ 2 ] = { - 20, - 22 };
        int poz1B[ 2 ] = { 4, 21 };
       
        int poz2P[ 2 ] = { 20, 22 };
        int poz2L[ 2 ] = { - 29, 22 };
        int poz2U[ 2 ] = { - 4, - 21 };
    };
   
    void meteor::startCreating( int m, sf::Vector2f Pos, int Polygons, int partsPerClock )
    {
        targetParts = m;
        pos = Pos;
        polygons = Polygons;
        created = false;
        parts = partsPerClock;
        creating = true;
       
        moving = false;
        momentumX = 0.f;
        momentumY = 0.f;
    }
   
    void meteor::create()
    {
        if( currentParts == targetParts )
        {
            created = true;
            creating = false;
            return;
        }
       
        for( unsigned int i = 0; currentParts < targetParts and i < parts; i++ )
        {
            if( currentParts == 0 )
            {
                int i = 85;
                meteorPart tmp;
                meteorParts.push_back( tmp );
                meteorParts[ meteorParts.size() - 1 ].create( sf::Color( i, i, i, 50 ), pos, true, polygons, HPPerPart );
                currentParts++;
            }
            else
            {
                for( bool done = false; !done; )
                {
                    int addTo = rand() % currentParts;
                   
                    if( meteorParts[ addTo ].right or meteorParts[ addTo ].left or meteorParts[ addTo ].upDown )
                    {
                        bool rotated = !meteorParts[ addTo ].Rotated;
                        sf::Vector2f pos = meteorParts[ addTo ].hexagon.getPosition();
                       
                        int strona = rand() % 3;
                       
                        for( bool Done = false; !Done; )
                        {
                            if( strona == 0 )
                            {
                                if( !meteorParts[ addTo ].right )
                                     strona++;
                               
                                else
                                {
                                    if( meteorParts[ addTo ].Rotated )
                                    {
                                        pos.x += poz2P[ 0 ];
                                        pos.y += poz2P[ 1 ];
                                    }
                                    else
                                    {
                                        pos.x += poz1P[ 0 ];
                                        pos.y += poz1P[ 1 ];
                                    }
                                    meteorParts[ addTo ].right = false;
                                    Done = true;
                                }
                            }
                            if( strona == 1 )
                            {
                                if( !meteorParts[ addTo ].left )
                                     strona++;
                               
                                else
                                {
                                    if( meteorParts[ addTo ].Rotated )
                                    {
                                        pos.x += poz2L[ 0 ];
                                        pos.y += poz2L[ 1 ];
                                    }
                                    else
                                    {
                                        pos.x += poz1L[ 0 ];
                                        pos.y += poz1L[ 1 ];
                                    }
                                    meteorParts[ addTo ].left = false;
                                    Done = true;
                                }
                            }
                            if( strona == 2 )
                            {
                                if( !meteorParts[ addTo ].upDown )
                                     strona = 0;
                               
                                else
                                {
                                    if( meteorParts[ addTo ].Rotated )
                                    {
                                        pos.x += poz2U[ 0 ];
                                        pos.y += poz2U[ 1 ];
                                    }
                                    else
                                    {
                                        pos.x += poz1B[ 0 ];
                                        pos.y += poz1B[ 1 ];
                                    }
                                    meteorParts[ addTo ].upDown = false;
                                    Done = true;
                                }
                            }
                        }
                       
                        int i = 85;
                        meteorPart tmp;
                        meteorParts.push_back( tmp );
                        meteorParts[ currentParts ].create( sf::Color( i, i, i, 50 ), pos, rotated, polygons, HPPerPart );
                       
                        if( strona == 0 )
                             meteorParts[ currentParts ].left = false;
                       
                        if( strona == 1 )
                             meteorParts[ currentParts ].right = false;
                       
                        if( strona == 2 )
                             meteorParts[ currentParts ].upDown = false;
                       
                        currentParts++;
                        done = true;
                    }
                }
            }
        }
        if( currentParts == targetParts )
             update();
       
    }
   
    void meteor::draw( sf::RenderTarget & target, sf::RenderStates states ) const
    {
        for( unsigned int i = 0; i < currentParts; i++ )
             target.draw( meteorParts[ i ].hexagon, states );
       
    }
   
    void meteor::destroy()
    {
        meteorParts.clear();
        currentParts = 0;
        destroyed = true;
    }
   
    void meteor::move( float x, float y )
    {
        sf::Vector2f vect( x, y );
       
        for( unsigned int i = 0; i < currentParts; i++ )
             meteorParts[ i ].hexagon.setPosition( meteorParts[ i ].hexagon.getPosition() + vect );
       
        update();
        pos += vect;
    }
   
    void meteor::move( sf::Vector2f vect )
    {
        for( unsigned int i = 0; i < currentParts; i++ )
             meteorParts[ i ].hexagon.setPosition( meteorParts[ i ].hexagon.getPosition() + vect );
       
        update();
        pos += vect;
    }
   
    void meteor::move()
    {
        sf::Vector2f vect = sf::Vector2f( momentumX, momentumY );
       
        for( unsigned int i = 0; i < currentParts; i++ )
             meteorParts[ i ].hexagon.setPosition( meteorParts[ i ].hexagon.getPosition() + vect );
       
        update();
        pos += vect;
    }
   
    void meteor::push( sf::Vector2f vect, int mass )
    {
        momentumX +=( vect.x * mass ) / currentParts;
        momentumY +=( vect.y * mass ) / currentParts;
       
        moving = true;
    }
   
    void meteor::setColor( sf::Color color )
    {
        for( unsigned int i = 0; i < currentParts; i++ )
             meteorParts[ i ].hexagon.setFillColor( color );
       
    }
   
    sf::Color meteor::getColor()
    {
        return meteorParts[ 0 ].hexagon.getFillColor();
    }
   
    sf::Vector2f meteor::getPosition()
    {
        return pos;
    }
   
    bool meteor::contains( const sf::Vector2f point, int damage )
    {
        if( rect.contains( point ) )
        {
            bool any = false;
           
            for( int i = meteorParts.size() - 1; i >= 0; i-- )
            {
                if( meteorParts[ i ].hexagon.getGlobalBounds().contains( point ) and meteorParts[ i ].exist )
                {
                    int tmpHP = meteorParts[ i ].HP;
                   
                    meteorParts[ i ].HP -= damage;
                    if( meteorParts[ i ].HP < 0 )
                         meteorParts[ i ].HP = 0;
                   
                    if( meteorParts[ i ].HP == 0 )
                    //meteorParts[i].exist = false;
                         meteorParts.erase( meteorParts.begin() + i );
                   
                    lastDamage = tmpHP - meteorParts[ i ].HP;
                    any = true;
                    break;
                }
            }
           
            bool existBuf = false;
            for( int i = meteorParts.size() - 1; i >= 0; i-- )
            {
                if( !meteorParts[ i ].exist )
                     meteorParts[ i ].hexagon.setFillColor( sf::Color( 0, 0, 0, 0 ) );
                else
                     existBuf = true;
               
            }
            if( !existBuf )
                 destroy();
           
            return any;
        }
        else
             return false;
       
    }
   
    void meteor::update()
    {
        int top = pos.y;
        int bottom = pos.y;
        int right = pos.x;
        int left = pos.x;
       
        for( unsigned int i = 0; i < currentParts; i++ )
        {
            sf::Vector2f tmp = meteorParts[ i ].hexagon.getPosition();
            if( tmp.y < top )
                 top = tmp.y;
           
            if( tmp.y > bottom )
                 bottom = tmp.y;
           
            if( tmp.x < left )
                 left = tmp.x;
           
            if( tmp.x > right )
                 right = tmp.x;
           
        }
       
        rect.top = top - 30;
        rect.height =( bottom - top ) + 30;
        rect.left = left - 30;
        rect.width =( right - left ) + 30;
       
       
    }
   
    bool anyCreating = false;
};

vector < space::meteor > meteors;

#endif // SPACEOBJECTS_H_INCLUDED
P-137425
Lora
» 2015-09-11 22:33:25
C/C++
if( meteorParts[ i ].HP == 0 )
     meteorParts.erase( meteorParts.begin() + i );

lastDamage = tmpHP - meteorParts[ i ].HP;
Usuwasz element wektora, a później się do niego odwołujesz.
P-137428
Gibas11
Temat założony przez niniejszego użytkownika
» 2015-09-11 23:04:53
O, rzeczywiście. :) Niestety po poprawieniu tego co napisałeś błąd dalej występował, trzeba było jeszcze dopisać
C/C++
currentParts--;
po usuwaniu elementu, ponieważ funkcja update, korzystała z tej zmiennej, a nie sprawdzała rozmiar tablicy. :/ Po poprawieniu tych 2 błędów kod jest w pełni sprawny, dziękuję za pomoc i dla zainteresowanych zamieszczam poniżej:
C/C++
#ifndef SPACEOBJECTS_H_INCLUDED
#define SPACEOBJECTS_H_INCLUDED

namespace space
{
    sf::RenderTexture rt;
   
    class meteorPart
    {
    public:
       
        sf::Color color;
        sf::CircleShape hexagon;
       
        bool right = true;
        bool left = true;
        bool upDown = true;
        bool Rotated;
       
        int HP;
       
        void create( sf::Color mask, sf::Vector2f pos, bool rotated, int polygons, int hp );
    };
   
    void meteorPart::create( sf::Color mask, sf::Vector2f pos, bool rotated, int polygons, int hp )
    {
        hexagon = sf::CircleShape( 29, polygons );
        hexagon.setFillColor( mask );
        hexagon.setOrigin( 20, 29 );
        hexagon.setPosition( pos );
        Rotated = rotated;
        HP = hp;
       
        hexagon.setRotation(( int ) rotated * 60 );
    }
   
    class meteor
        : public sf::Drawable
    {
    public:
        vector < meteorPart > meteorParts;
       
        void startCreating( int m, sf::Vector2f Pos, int Polygons, int partsPerClock );
        void create();
        void update();
        void destroy();
       
        void setColor( sf::Color color );
        void move( sf::Vector2f vect );
        void move( float x, float y );
        void move();
       
        void push( sf::Vector2f vect, int mass );
       
        bool contains( sf::Vector2f point, int damage );
       
        sf::Color getColor();
        sf::Vector2f getPosition();
       
        bool created = false;
        bool creating = false;
        bool destroyed = false;
        bool moving;
       
        sf::Vector2f pos;
    private:
        float momentumX;
        float momentumY;
       
        sf::Texture texture;
        sf::Sprite sprite;
        sf::FloatRect rect;
       
        virtual void draw( sf::RenderTarget & target, sf::RenderStates states ) const;
       
        unsigned int targetParts = 0;
        unsigned int currentParts = 0;
        unsigned int polygons;
        unsigned int parts;
       
        unsigned int HPPerPart = 40;
       
        int poz1P[ 2 ] = { 29, - 22 };
        int poz1L[ 2 ] = { - 20, - 22 };
        int poz1B[ 2 ] = { 4, 21 };
       
        int poz2P[ 2 ] = { 20, 22 };
        int poz2L[ 2 ] = { - 29, 22 };
        int poz2U[ 2 ] = { - 4, - 21 };
    };
   
    void meteor::startCreating( int m, sf::Vector2f Pos, int Polygons, int partsPerClock )
    {
        targetParts = m;
        pos = Pos;
        polygons = Polygons;
        created = false;
        parts = partsPerClock;
        creating = true;
       
        moving = false;
        momentumX = 0.f;
        momentumY = 0.f;
    }
   
    void meteor::create()
    {
        if( currentParts == targetParts )
        {
            created = true;
            creating = false;
            return;
        }
       
        for( unsigned int i = 0; currentParts < targetParts and i < parts and !created; i++ )
        {
            if( currentParts == 0 )
            {
                int i = 85;
                meteorPart tmp;
                meteorParts.push_back( tmp );
                meteorParts[ meteorParts.size() - 1 ].create( sf::Color( i, i, i, 50 ), pos, true, polygons, HPPerPart );
                currentParts++;
            }
            else
            {
                for( bool done = false; !done; )
                {
                    int addTo = rand() % currentParts;
                   
                    if( meteorParts[ addTo ].right or meteorParts[ addTo ].left or meteorParts[ addTo ].upDown )
                    {
                        bool rotated = !meteorParts[ addTo ].Rotated;
                        sf::Vector2f pos = meteorParts[ addTo ].hexagon.getPosition();
                       
                        int strona = rand() % 3;
                       
                        for( bool Done = false; !Done; )
                        {
                            if( strona == 0 )
                            {
                                if( !meteorParts[ addTo ].right )
                                     strona++;
                               
                                else
                                {
                                    if( meteorParts[ addTo ].Rotated )
                                    {
                                        pos.x += poz2P[ 0 ];
                                        pos.y += poz2P[ 1 ];
                                    }
                                    else
                                    {
                                        pos.x += poz1P[ 0 ];
                                        pos.y += poz1P[ 1 ];
                                    }
                                    meteorParts[ addTo ].right = false;
                                    Done = true;
                                }
                            }
                            if( strona == 1 )
                            {
                                if( !meteorParts[ addTo ].left )
                                     strona++;
                               
                                else
                                {
                                    if( meteorParts[ addTo ].Rotated )
                                    {
                                        pos.x += poz2L[ 0 ];
                                        pos.y += poz2L[ 1 ];
                                    }
                                    else
                                    {
                                        pos.x += poz1L[ 0 ];
                                        pos.y += poz1L[ 1 ];
                                    }
                                    meteorParts[ addTo ].left = false;
                                    Done = true;
                                }
                            }
                            if( strona == 2 )
                            {
                                if( !meteorParts[ addTo ].upDown )
                                     strona = 0;
                               
                                else
                                {
                                    if( meteorParts[ addTo ].Rotated )
                                    {
                                        pos.x += poz2U[ 0 ];
                                        pos.y += poz2U[ 1 ];
                                    }
                                    else
                                    {
                                        pos.x += poz1B[ 0 ];
                                        pos.y += poz1B[ 1 ];
                                    }
                                    meteorParts[ addTo ].upDown = false;
                                    Done = true;
                                }
                            }
                        }
                       
                        int i = 85;
                        meteorPart tmp;
                        meteorParts.push_back( tmp );
                        meteorParts[ currentParts ].create( sf::Color( i, i, i, 50 ), pos, rotated, polygons, HPPerPart );
                       
                        if( strona == 0 )
                             meteorParts[ currentParts ].left = false;
                       
                        if( strona == 1 )
                             meteorParts[ currentParts ].right = false;
                       
                        if( strona == 2 )
                             meteorParts[ currentParts ].upDown = false;
                       
                        currentParts++;
                        done = true;
                    }
                }
            }
        }
        if( currentParts == targetParts )
             update();
       
    }
   
    void meteor::draw( sf::RenderTarget & target, sf::RenderStates states ) const
    {
        for( unsigned int i = 0; i < currentParts; i++ )
             target.draw( meteorParts[ i ].hexagon, states );
       
    }
   
    void meteor::destroy()
    {
        meteorParts.clear();
        currentParts = 0;
        destroyed = true;
    }
   
    void meteor::move( float x, float y )
    {
        sf::Vector2f vect( x, y );
       
        for( unsigned int i = 0; i < currentParts; i++ )
             meteorParts[ i ].hexagon.setPosition( meteorParts[ i ].hexagon.getPosition() + vect );
       
        update();
        pos += vect;
    }
   
    void meteor::move( sf::Vector2f vect )
    {
        for( unsigned int i = 0; i < currentParts; i++ )
             meteorParts[ i ].hexagon.setPosition( meteorParts[ i ].hexagon.getPosition() + vect );
       
        update();
        pos += vect;
    }
   
    void meteor::move()
    {
        sf::Vector2f vect = sf::Vector2f( momentumX, momentumY );
       
        for( unsigned int i = 0; i < currentParts; i++ )
             meteorParts[ i ].hexagon.setPosition( meteorParts[ i ].hexagon.getPosition() + vect );
       
        update();
        pos += vect;
    }
   
    void meteor::push( sf::Vector2f vect, int mass )
    {
        momentumX +=( vect.x * mass ) / currentParts;
        momentumY +=( vect.y * mass ) / currentParts;
       
        moving = true;
    }
   
    void meteor::setColor( sf::Color color )
    {
        for( unsigned int i = 0; i < currentParts; i++ )
             meteorParts[ i ].hexagon.setFillColor( color );
       
    }
   
    sf::Color meteor::getColor()
    {
        return meteorParts[ 0 ].hexagon.getFillColor();
    }
   
    sf::Vector2f meteor::getPosition()
    {
        return pos;
    }
   
    bool meteor::contains( const sf::Vector2f point, int damage )
    {
        if( rect.contains( point ) )
        {
            bool any = false;
           
            for( int i = meteorParts.size() - 1; i >= 0; i-- )
            {
                if( meteorParts[ i ].hexagon.getGlobalBounds().contains( point ) )
                {
                    meteorParts[ i ].HP -= damage;
                    if( meteorParts[ i ].HP < 0 )
                         meteorParts[ i ].HP = 0;
                   
                    if( meteorParts[ i ].HP == 0 )
                    {
                        meteorParts.erase( meteorParts.begin() + i );
                        currentParts--;
                    }
                   
                    any = true;
                    break;
                }
            }
           
            if( meteorParts.size() == 0 )
                 destroy();
           
            return any;
        }
        else
             return false;
       
    }
   
    void meteor::update()
    {
        int top = pos.y;
        int bottom = pos.y;
        int right = pos.x;
        int left = pos.x;
       
        for( unsigned int i = 0; i < currentParts; i++ )
        {
            sf::Vector2f tmp = meteorParts[ i ].hexagon.getPosition();
            if( tmp.y < top )
                 top = tmp.y;
           
            if( tmp.y > bottom )
                 bottom = tmp.y;
           
            if( tmp.x < left )
                 left = tmp.x;
           
            if( tmp.x > right )
                 right = tmp.x;
           
        }
       
        rect.top = top - 30;
        rect.height =( bottom - top ) + 30;
        rect.left = left - 30;
        rect.width =( right - left ) + 30;
       
       
    }
   
    bool anyCreating = false;
};

vector < space::meteor > meteors;

#endif // SPACEOBJECTS_H_INCLUDED
P-137430
« 1 »
  Strona 1 z 1