Pure virtual method called, terminate... Crash.

Odpowiedz Nowy wątek
2019-02-10 19:40
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;
}
edytowany 3x, ostatnio: Spark_of_hope, 2019-02-10 20:38
metody 'pure virtual' występują w klasach abstrakcyjnych - AnyKtokolwiek 2019-02-10 20:04

Pozostało 580 znaków

2019-02-11 10:26
      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?

edytowany 1x, ostatnio: _0x666_, 2019-02-11 10:29

Pozostało 580 znaków

2019-02-11 10:44
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]);

Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 3x, ostatnio: MarekR22, 2019-02-11 10:49

Pozostało 580 znaków

2019-02-11 15:18
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:)

Pozostało 580 znaków

2019-02-11 15:24
1

Nie lepiej zrobić tak:

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

Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.

Pozostało 580 znaków

2019-02-11 15:29
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:)

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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