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

Author Topic: Drawable object inheritance  (Read 2701 times)

0 Members and 1 Guest are viewing this topic.

jeans123

  • Newbie
  • *
  • Posts: 3
    • View Profile
Drawable object inheritance
« on: March 17, 2017, 01:39:34 pm »
I have class Menu that inherits from public Drawable and override draw method and owns Button class instance.

class Menu  : public sf::Drawable
{
    public:
        Menu();
        virtual ~Menu();
    protected:
    private:
        virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const;

        Button* m_Button_3x3;
        Button* m_Button_9x9;
        Button* m_Button_16x16;
        Button* m_Button_99x99;

        sf::Sprite* m_Sprite3x3;
        sf::Sprite*  m_Sprite_9x9;
        sf::Sprite*  m_Sprite_16x16;
        sf::Sprite*  m_Sprite_99x99;

        sf::Texture m_texture;
};
 
It uses constructor to define Sprites and Buttons:
Menu::Menu()
{
    m_texture.loadFromFile("menu.png");

    m_Sprite3x3 = new sf::Sprite(m_texture, sf::IntRect(0,0,400,300));

    m_Sprite_9x9 = new sf::Sprite(m_texture, sf::IntRect(400,0,800,300));
    m_Sprite_9x9->setPosition(400, 0);

    m_Sprite_16x16 = new sf::Sprite(m_texture, sf::IntRect(0,300,400,600));
    m_Sprite_16x16->setPosition(0, 300);

    m_Sprite_99x99 = new sf::Sprite(m_texture, sf::IntRect(400,300,800,600));
    m_Sprite_99x99->setPosition(400, 300);


    Button* m_Button_3x3 = new Button(m_Sprite3x3);
    Button* m_Button_9x9 = new Button(m_Sprite_9x9);
    Button* m_Button_16x16 = new Button(m_Sprite_16x16);
    Button* m_Button_99x99 = new Button(m_Sprite_99x99);
}

It contains Buttons that I want to display by using theirs overridden function draw:

class Button    : public sf::Drawable
{
    friend class Menu;
    public:
        Button(sf::Sprite* sprite);
        virtual ~Button();
    protected:
    private:
        virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const;
        sf::Sprite m_sprite;

};
 
Here's function draw with global extern window (window is only one so I think it's not too bad to have it as a global var):
void Button::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
    extern sf::RenderWindow app;
    app.draw(m_sprite);
}

but somehow I cannot call Buttons::draw in Menu::draw : - causes Segfault
void Menu::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
    extern sf::RenderWindow app;

    m_Button_3x3->draw(app, states);
    }
 
that causes Segfault as well:
void Menu::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
    extern sf::RenderWindow app;

   app.draw(*m_Button_3x3);
}
 

works only that but it's not elegant - moreover - it displays correctly but causes segfault when app is closing:
void Menu::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
    extern sf::RenderWindow app;

   app.draw(*m_Sprite3x3);
}
 

So what is correct way to inherit Drawable in dervied class? Like
app.draw(menu) ->
   menu::draw(){app.draw(button)}->
      button::draw(){app.draw(member_button_sprite)}
Is it a more elegant, clever way to do that?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Drawable object inheritance
« Reply #1 on: March 17, 2017, 01:52:15 pm »
Quote
    Button* m_Button_3x3 = new Button(m_Sprite3x3);
    Button* m_Button_9x9 = new Button(m_Sprite_9x9);
    Button* m_Button_16x16 = new Button(m_Sprite_16x16);
    Button* m_Button_99x99 = new Button(m_Sprite_99x99);
You're declaring new local variables instead of assigning the class members. So the latter stay uninitialized, and crash when you try to use them.

PS: C++ is not Java nor C#, no need to allocate everything with "new" ;)
PPS: inside the draw function, no need for "extern sf::RenderWindow app", just use the "target" argument
Laurent Gomila - SFML developer

jeans123

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: Drawable object inheritance
« Reply #2 on: March 17, 2017, 01:55:39 pm »
Woaaah, it was so obvious that I am angry at myself I didn't notice it.

Yes - thank you, you're right.

I use new operator because my class Button doesn't have default constructor, so I cannot declare it as a Menu class member like: Button b1 (it causes compilation error - no default constructor for Button class)

;)

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: Drawable object inheritance
« Reply #3 on: March 17, 2017, 02:38:30 pm »
I use new operator because my class Button doesn't have default constructor, so I cannot declare it as a Menu class member like: Button b1 (it causes compilation error - no default constructor for Button class)
Of course you can, you just have to use the initialization list.

I highly recommend to learn more about C++ itself first. You'll very quickly run into similar "issues" that can just be traced back to missing knowledge on C++ basics. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Drawable object inheritance
« Reply #4 on: March 17, 2017, 03:15:24 pm »
Quote
Of course you can, you just have to use the initialization list.
Except that the constructor arguments are the sprites, which could be ok, but they themselves depend on the texture, which cannot be loaded at the point where the initialization list is called.
Laurent Gomila - SFML developer