Problem with a function inside a class

Hello. I encountered a curious problem while working with SFML. I created the following class to manage an object's images and sprites:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class imagen {

	public:

		sf::Image foto;
		sf::Sprite spray;

		void load(std::string file)
		{
			foto.LoadFromFile(file);
		}

		void sprite_load(sf::Image pic)
		{
			spray.SetImage(pic);
		}

}clase_obj;


And then I used it to display some images on the screen:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int main()
{
	clase_obj.load("mono.jpg");

	//clase_obj.spray.SetImage(clase_obj.foto); // This one works fine
	clase_obj.sprite_load(clase_obj.foto);      // This one doesn't work

	clase_obj.spray.SetPosition(300,300);

	ventana.SetFramerateLimit(60);

	while (ventana.IsOpened())
	{
		salir();
		ventana.Clear();
		ventana.Draw(clase_obj.spray);
		ventana.Display();

	}
	return EXIT_SUCCESS;
}


To me, both ways of setting the image

clase_obj.spray.SetImage(clase_obj.foto);
clase_obj.sprite_load(clase_obj.foto);

are the same thing, but if I use the second one a white square appears, instead of the intended image.

I assume that there's a property of C++ classes that I'm not understanding, but I can't seem to figure it out.

Any help will be appreciated. Thanks!
closed account (1yvXoG1T)
The problem is that you're making a "copy" that doesn't actually point to the proper place in memory. Basically, when you first load the image file it's stored in memory slot A and when you try to pass it to your sprite_load you're copying the image information but not the location of the file in memory (pointing to slot B)

So what you can do is replace your sprite_load with this:
1
2
3
4
5
//This passes the address of the loaded image
void sprite_load(sf::Image& pic)
{
	spray.SetImage(pic);
}

Or you can bypass this function altogether and just make something like this:
1
2
3
4
5
void load(std::string file)
{
	foto.LoadFromFile(file);
	spray.SetImage(foto);
}


Hope this helps :)
Last edited on
Thanks a lot! I'm still understanding these concepts, but it works now. About your second suggestion, that's the way I was doing it so far, but since now I want to make an array of images as instances of the same class, I just want to load the image once. Correct me if I'm mistaken, but if I did this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class imagen {

	public:

		sf::Image foto;
		sf::Sprite spray;

		void load(std::string file)
		{
			foto.LoadFromFile(file);
			spray.SetImage(pic);
		}

}clase_obj[30];

int main()
{

	for (i = 0;i < 30; i++)
	{
		clase_obj[i].load("mono.jpg");
	}

//[... rest of the code ...]


the image would be loaded in memory 30 times. That's why I want the sprite and the image functions separated.

Thanks again for the reply!
closed account (1yvXoG1T)
Glad it helped :) And yes, you are right that it would load the file multiple times. You might consider looking in to creating some sort of storage place for your images. As in, a class that has a container and you can just load the image in to this manager-type object then reference it later.
Might I ask what you're working on? :D
I'm just getting familiarized with C++, and since my goal is to develop video games, I'm learning SFML along the way. The code is for a 2D platformer, serving no other purpose than presenting me with challenges to program. I made an Arkanoid clone before, but I decided to move to something a little more exciting.

(I know I should've completely finished Arkanoid first, but frankly this platformer is a far more enjoyable project.)
Topic archived. No new replies allowed.