Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: [SOLVED]"Pure Virtual Function Called" - problem while drawing  (Read 3021 times)

0 Members and 1 Guest are viewing this topic.

Brax

  • Newbie
  • *
  • Posts: 39
  • Wannabe C++ Game Developer
    • View Profile
[SOLVED]"Pure Virtual Function Called" - problem while drawing
« on: November 01, 2015, 11:04:16 pm »
Hi!

First of all, I am sorry for posting a general C++ question, but the origin of the problem made me believe that this would be the best place. I also searched the forum and web, but didn’t found satisfying solution or guideline (or I just suck at searching :-\).
Also bear in mind that I am inexperienced in C++, (but learning new things steadily  :D )

Basically, I am making use of polymorphism during drawing.
I made a abstract base class (derived from sf::Drawable and sf::Transformable) and several derived classes. The objects from derived classes are updated, but not drawn.
Then I made a special deque in which are stored raw pointers of base class. These pointers point to the objects of derived classes and are used for drawing.

So instead of writing something like this:
window.draw(object_1);  //  object of derived class 1;
window.draw(object_2);  //  object of derived class 2;
window.draw(object_3);  //  object of derived class 3;
window.draw(object_4);  //  object of derived class 4;
for (const auto& it: cont_1)  // container of X objects of derived class 5;
   window.draw(it);
for (const auto& it: cont_2)  // container of Y objects of derived class 6;
   window.draw(it);
// Now imagine that there are additional 50 more derived classes with at least one object below.
 
I can write it like this:

for (const auto& it: cont_of_pointers)  // container of X pointers of the base class that point to objects derived classes;
   window.draw(*it);
 

Neat!  ;D

When object is no longer useful and won’t be used any time soon. I need to delete it. Therefore, I need to delete both the pointer pointing to that object from the array and the object itself during runtime.

The deletion goes smoothly, but the program crashes when it starts drawing objects, with the message “R6025 – Pure Virtual function called”. The error seems to refer to a draw function inside sf::Drawable, which is the main reason why I posted topic on this forum.

The problem now is, what I managed to figure out, is that when I delete the object itself, the problem occurs. If I delete only the pointer, it works, but the object itself is still inside the memory and program takes him into account when dealing with logic, it is simply invisible because it is no longer being drawn.

(Maybe the lambda expression is the problem… I started using them just recently, thought I should point that out.  :-[ )

So my questions are:
1. What should I do in order to prevent the pure virtual function call in this method for drawing?
2. Should I even draw like this in the first place?
3. How is this error even possible? There are no dangling pointers nor calls to a pure virtual functions inside my base class constructor/destructor and the compiler won’t even run the program if there is a call to a pure virtual function somewhere else in the code, as far as I know.

Here is complete and minimal example that reproduces the problem:
(click to show/hide)
« Last Edit: November 02, 2015, 12:36:13 am by Brax »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: "Pure Virtual Function Called" - problem while drawing
« Reply #1 on: November 01, 2015, 11:18:33 pm »
When you remove from square_deque, the objects inside are possibly moved around (remember what std::remove_if does), invalidating the pointers in objects_for_draw.
Laurent Gomila - SFML developer

Brax

  • Newbie
  • *
  • Posts: 39
  • Wannabe C++ Game Developer
    • View Profile
Re: "Pure Virtual Function Called" - problem while drawing
« Reply #2 on: November 02, 2015, 12:35:44 am »
That didn't crossed my mind.  :-\

So, clearing entire object_for_draw deque and repopulating it with new pointers after the element has been deleted works.

Thanks.