Pure virtual method called, terminate... Crash.

0

"pure virtual method called, terminate
terminate called without an active exception
This application has requested the runtime to terminate it in an unusual way."
Taki oto błąd dostaje w konsoli podczas dzialania mojej aplikacji. Pomoże mi ktoś ogarnąć sytuacje, dlaczego tak się dzieje, i ew jak przekształcić mój kod żeby działał prawidłowo?:) Wujek Google dał mi do zrozumienia że to błąd przy konstruktorze, lub coś w tym stylu, tylko że ja nie konstruowałem wlsnej classy tylko używam gotowych z biblioteki SFML. Poniżej wkleje kod. Generalnie to miała być prosta gierka, okno podzielone na 3 pionowe pasy, w ktorych beda pojawialy sie objekty ładowane w 3 vectory. Problem pojawił się na samym początku, przy pierwszym z nich, gdy przypuszczam że ma dojść do dodania nowego sf::RectangleShape do vectora. Będe wdzięczny za jakąkolwiek pomoc.:)
Edit: Błąd jest spowodowany na 99% przez column1Vec.pop_back();,a nie jak myslalem przy powtornym push_back(), nadal nie mam pojęcia dlaczego nie mogę usunąć tego obiektu...

#include <SFML/Graphics.hpp>
#include <vector>
#include <iostream>
using namespace std;

int main()
{
    sf::RenderWindow w( sf::VideoMode( 300, 600),"Three lines v0.1");

    // CREATING 3 VECTORS
    vector<sf::RectangleShape> column1Vec;
    vector<sf::RectangleShape> column2Vec;
    vector<sf::RectangleShape> column3Vec;

    bool onCreateSquare = 1;

    while( w.isOpen())
    {
        sf::Event e;
        while( w.pollEvent(e))
        {
            switch ( e.type)
            {
            case sf::Event::Closed:
                w.close();
                break;
            case sf::Event::KeyPressed:
                if (e.key.code == sf::Keyboard::Escape)
                    w.close();
            }
        }
        // CREATE SQUARE IN STARTING POSITION
        if (onCreateSquare == true) 
        {
            sf::RectangleShape square(sf::Vector2f(100, 100));
            square.setPosition(sf::Vector2f(0, 0));   // Starting position
            column1Vec.push_back(square);
            column1Vec[0].setFillColor(sf::Color::Red);
            onCreateSquare = false;
        }
        // IF COLUMN1VEC[0] EXIST:
        column1Vec[0].move(sf::Vector2f(0.f, 0.1f));

        // CHECKING COLISION, TURN ON ON_CREATESQUARE (IF)
        if ( column1Vec[0].getPosition().y >= 600)
        {
            column1Vec.pop_back();
            onCreateSquare = true;
        }
        // CHECKING SQUARE'S COORDINATES IN CONSOLE
        cout<<column1Vec[0].getPosition().x<<"  "<<column1Vec[0].getPosition().y<<endl;

        // DRAWING
        w.clear();

        w.draw(column1Vec[0]);

        w.display();
    }

    return 0;
}
2
		if ( column1Vec[0].getPosition().y >= 600)
		{
			column1Vec.pop_back(); // <---- 
			onCreateSquare = true;
		}
		
		cout<< column1Vec[0].getPosition().x << "  " << column1Vec[0].getPosition().y << endl;
		
		w.draw(column1Vec[0]);

Ryzykowne. Pewny jesteś, że w linii 7 i 9 column1Vec nie jest pusty?

1

Nie da się stworzyć obiektu bez zaimplementowanych metod wirtualnych.
Jedyny scenariusz jaki znam, kiedy użyta zostaje metoda abstrakcyjna to, gdy konstruktor klasy bazowej wywołuję abstrakcyjną metodę wirtualną (pośrednio lub nie), ponieważ w trakcie konstruowania obiekt "awansuje" z typem (zakończenie wywołania konstruktora klasy bazowej powoduję aktualizację referencji do v-table).
Z tego powodu wywoływanie metod wirtualnych z konstruktora jest niezalecane.

W twoim kodzie czegoś takiego nie widzę, ergo coś nie tak jest gdzieś indziej.
Albo błąd w bibliotece (mało prawdopodobne), albo UB, które ma takie dziwne konsekwencje.

Odtwórz crash w IDE, znajdź okno "call stack" i skopiuj jego zawartość.

Zresztą twój kod jest przekombinowany i faktycznie ma UB.

Tu column1Vec może być puste.

        cout<<column1Vec[0].getPosition().x<<"  "<<column1Vec[0].getPosition().y<<endl;
....
        w.draw(column1Vec[0]);
0

Dziękuje Panowie za pomoc, faktycznie wysypywal się prawdopodobnie przy probie rysowania obiektu gdy faktycznie go tam nie było.

if (!column1Vec.empty())
            w.draw(column1Vec[0]);

Dodanie ifa załatwiło sprawe:)

Hmm kod może i przekombinowany, nie wiem, to dopiero początek, też dopiero jestem mega początkujący w programowaniu, programuje dla frajdy więc przyjme każde rady i krytyke:)

1

Nie lepiej zrobić tak:

for (auto &item : column1Vec) {
    w.draw(item);
}
0

Gdzieś obiła mi sie o uszy ta konstrukcja for, podobno wykonuje operacje dla wszystkich elementow, dla ktorych jest wywolywana, jeszcze jej nie cwiczylem ale czuje że moze byc wygodniejsza niz stworzenie petli rysujacej dla wszystkich obiektow recznie, znaczy z tym nie automatycznym iteratorem, jakkolwiek to brzmi:D Zainteresuje się nią pewnie prędzej lub później:)

1 użytkowników online, w tym zalogowanych: 0, gości: 1