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

Author Topic: [SOLVED] Window::onCreate not getting called in my derived class  (Read 4395 times)

0 Members and 1 Guest are viewing this topic.

Dada

  • Newbie
  • *
  • Posts: 3
    • View Profile
My problem is already solved but I thought I'd post it with the solution since I hadn't found anything on the topic when I did a search earlier.

I have a class derived from Window that overrides the onCreate function:

class MainWindow: public sf::Window
{
public:
    MainWindow();

protected:
    virtual void onCreate();
};

My original implementation of MainWindow's constructor looked like this:

MainWindow::MainWindow():
        sf::Window(sf::VideoMode(640, 480, 32), "SFML Window")
{
}

However my onCreate wasn't getting called. The reason is that virtual functions are not "in effect" until the instance is done initializing, which happens exactly at the opening { of the most derived constructor.

So the simple fix is this:

MainWindow::MainWindow()
{
    create(sf::::VideoMode(640, 480, 32), "SFML Window");
}

The Window sub-object is initialized with its default constructor first. That finishes the initialization of the complete object. Only then is the create function called, which calls the intended version of onCreate.

Hope that helps someone!

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: [SOLVED] Window::onCreate not getting called in my derived class
« Reply #1 on: July 01, 2013, 04:37:55 pm »
This is not a fix.

Calling virtual functions in the constructor is undefined behavior, independently of whether they are called in the initializer list or the body.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: [SOLVED] Window::onCreate not getting called in my derived class
« Reply #2 on: July 01, 2013, 04:40:27 pm »
Quote
Calling virtual functions in the constructor is undefined behavior, independently of whether they are called in the initializer list or the body.
Is it really? :o http://www.stroustrup.com/bs_faq2.html#vcall

Anyway, Laurent 'forbid' ;D using the onXXX functions in Window because they are undocumented and implementation detail, not meant for users.
Back to C++ gamedev with SFML in May 2023

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: [SOLVED] Window::onCreate not getting called in my derived class
« Reply #3 on: July 01, 2013, 04:48:02 pm »
Quote
Calling virtual functions in the constructor is undefined behavior, independently of whether they are called in the initializer list or the body.
I couldn't find a source mentioning a virtual call from the constructor of the derived class, the examples always do the call from the base class. I even found a source mentioning that the call would not go further than the currently constructed class -- which would be ok in this case.

I'm a little worried because I do the same thing in sf::RenderWindow ;D
Laurent Gomila - SFML developer

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: [SOLVED] Window::onCreate not getting called in my derived class
« Reply #4 on: July 01, 2013, 05:25:07 pm »

Too funny of a coincidence to pass up.
Back to C++ gamedev with SFML in May 2023

Dada

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: [SOLVED] Window::onCreate not getting called in my derived class
« Reply #5 on: July 02, 2013, 01:25:13 am »
The behavior is well defined, it just happens to be a little tricky and it tripped me up for a minute. That's why I posted about it.

As for onCreate being off-limits: I saw it in the docs and wanted to use it so... Y'all try and stop me  ;).

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: [SOLVED] Window::onCreate not getting called in my derived class
« Reply #6 on: July 02, 2013, 07:52:00 pm »
Ah you're right. In the constructor (or destructor), only pure virtual function calls from abstract classes or qualified calls to functions derived classes are undefined.

For completeness, here are the corresponding standard paragraphs (from n3337):
Quote from: §12.7/4
Member functions, including virtual functions (10.3), can be called during construction or destruction (12.6.2).
When a virtual function is called directly or indirectly from a constructor or from a destructor, including
during the construction or destruction of the class’s non-static data members, and the object to which the
call applies is the object (call it x) under construction or destruction, the function called is the final overrider
in the constructor’s or destructor’s class and not one overriding it in a more-derived class. If the virtual
function call uses an explicit class member access (5.2.5) and the object expression refers to the complete
object of x or one of that object’s base class subobjects but not x or one of its base class subobjects, the
behavior is undefined.
Quote from: §10.4/6
Member functions can be called from a constructor (or destructor) of an abstract class; the effect of making a
virtual call (10.3) to a pure virtual function directly or indirectly for the object being created (or destroyed)
from such a constructor (or destructor) is undefined.

Nevertheless, the way how SFML uses onCreate() is questionable. sf::Window calls this virtual function during create() or its constructor -- if it is called in the constructor, only the base class version sf::Window::onCreate() will be invoked, which leads to the problem seen here.

There is another design problem: Classes that derive indirectly from sf::Window (for example by deriving from sf::RenderWindow) and override onCreate(), will prevent the function in the middle class from being called. This case happens probably rarely, because users are not supposed to inherit sf::Window indirectly.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: [SOLVED] Window::onCreate not getting called in my derived class
« Reply #7 on: July 02, 2013, 08:10:39 pm »
I should really add to the documentation that these functions are for internal use only.
Laurent Gomila - SFML developer

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: [SOLVED] Window::onCreate not getting called in my derived class
« Reply #8 on: July 02, 2013, 08:31:05 pm »
Or don't document them at all; after all, it's the documentation of the public API ;)
(you can at least hide the comments for doxygen, using @internal or just plain // comments)

But isn't it also a problem for SFML itself? If a RenderWindow instance is created using the constructor, how will RenderWindow::onCreate() be called?
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: [SOLVED] Window::onCreate not getting called in my derived class
« Reply #9 on: July 02, 2013, 09:02:45 pm »
Quote
But isn't it also a problem for SFML itself? If a RenderWindow instance is created using the constructor, how will RenderWindow::onCreate() be called?
It is called from the constructor of RenderWindow, not Window. So RenderWindow::onCreate can be reached.
Laurent Gomila - SFML developer

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Back to C++ gamedev with SFML in May 2023

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: [SOLVED] Window::onCreate not getting called in my derived class
« Reply #11 on: July 02, 2013, 10:35:40 pm »
He he :P
Laurent Gomila - SFML developer