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

Author Topic: Classes and using static  (Read 2046 times)

0 Members and 1 Guest are viewing this topic.

Kiblinix

  • Newbie
  • *
  • Posts: 15
    • View Profile
Classes and using static
« on: July 17, 2011, 11:01:28 pm »
For the past two days I have been trying to create a bullet class which can then be used to let the player fire bullets.

I have been struggling to get the bullet class to use the same image that only has to load once instead of loading it every time a bullet is created, but this leads to some problems.

I had a look in the 1.6 sprites tutorial: http://www.sfml-dev.org/tutorials/1.6/graphics-sprite.php , specifically the Images and Sprite management section, more specifically, this piece of code:

Code: [Select]
class Missile
{
public :

    static bool Init(const std::string& ImageFile)
    {
        return Image.LoadFromFile(ImageFile);
    }

    Missile()
    {
        Sprite.SetImage(Image); // every sprite uses the same unique image
    }

private :

    static sf::Image Image; // shared by every instance

    sf::Sprite Sprite; // one per instance
};


I do not understand this part:
Code: [Select]
static bool Init(const std::string& ImageFile)
    {
        return Image.LoadFromFile(ImageFile);
    }


I understand the rest of the class, but I am not sure what I am meant to do with this function, do I use it after I have created the bullet?

Code: [Select]
Missile missile1;
missile1.Init("Missile.png");


Like so? Because if I just copy the Missile class exactly into my code (I wouldn't normally do this but I've been working on it for a while now), and then try to just create a Missile, I get this error:

error LNK2001: unresolved external symbol "private: static class sf::Image Missile::Image" (?Image@Missile@@0V0sf@@A)

Here is my program that produces the problem:

Code: [Select]
#include <SFML/Graphics.hpp>

class Missile
{
public :
    static bool Init(const std::string& ImageFile)
    {
        return Image.LoadFromFile(ImageFile);
    }

    Missile()
    {
        Sprite.SetImage(Image);
    }

private :
    static sf::Image Image;
    sf::Sprite Sprite;
};

int main()
{
sf::RenderWindow App(sf::VideoMode(640, 480), "Space Shooter");
App.SetFramerateLimit(60);

Missile missile1;

while (App.IsOpened())
{
sf::Event Event;
while (App.PollEvent(Event))
{
if (Event.Type == sf::Event::Closed)
App.Close();
}

App.Clear(sf::Color::White);
App.Display();
}

return 0;
}


Any help would be greatly appreciated, and as a side note, I'm using SFML 2.0.

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Re: Classes and using static
« Reply #1 on: July 18, 2011, 12:48:17 am »
Quote from: "Kiblinix"
I do not understand this part:
Code: [Select]
static bool Init(const std::string& ImageFile)
    {
        return Image.LoadFromFile(ImageFile);
    }


I understand the rest of the class, but I am not sure what I am meant to do with this function, do I use it after I have created the bullet?

Code: [Select]
Missile missile1;
missile1.Init("Missile.png");


Like so?
No the other way around :
Code: [Select]
Missile::Init("...");
Missile m1;

C++ will allows you to use 'someMissile.Init(...)' but I recommend using Missile::Init(...) because Init is a static function. (Search google about static function)

Now, you have to use Init first and then only you can create an instance of Missile because this instance will require some data loaded by Init.

Quote from: "Kiblinix"
I get this error:

error LNK2001: unresolved external symbol "private: static class sf::Image Missile::Image" (?Image@Missile@@0V0sf@@A)

Every static field "static Type name" of a given class C needs a corresponding "Type C::name(ctors arguments);" in (only) one compilation unit (.cpp). Here you need to add before your main function the following :
Code: [Select]
sf::Image Missile::Image;
Googlize for "C++ static field" or something.
SFML / OS X developer

Kiblinix

  • Newbie
  • *
  • Posts: 15
    • View Profile
Classes and using static
« Reply #2 on: July 18, 2011, 09:05:16 pm »
Thanks Hiura, that was a massive help :)

Quick question, would it be possible to use this static image loading function for an Entity class, and then derive a player, enemy, and missile class from that? I was thinking that would make the code easier to read and simplify it a bit, but wouldn't it just cause all the classes to share the same image?

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Classes and using static
« Reply #3 on: July 18, 2011, 09:14:55 pm »
Yes, absolutely: they will share the same static field.

An image manager can be useful here. In each class constructor call something like Manager.GetImage("name") instead of using a static field. There are several Manager tools on the wiki. Here is the one I wrote some time ago.
SFML / OS X developer