Implement rule of 5 and destructor correctly

master
Manuel 1 month ago
parent
commit
3885c31ea2
1 changed files with 15 additions and 7 deletions
  1. +15
    -7
      Using-raylib-with-Cpp.md

+ 15
- 7
Using-raylib-with-Cpp.md

@ -37,7 +37,7 @@ private:
Texture2D m_texture = { 0 };
public:
MySprite(Texture2D texture)
:m_texture(texture);\
:m_texture(texture)
{
}
@ -56,14 +56,13 @@ MySprite aSprite(LoadTexture("Somefile.png"));
sprites.push_back(aSprite);
```
Push_back on the vector will make a copy of aSprite in the vector and then aSprite will go out of scope.
`push_back` on the vector will make a copy of aSprite in the vector and then aSprite will go out of scope.
The copy constructor for MySprite does not load a new texture, it just copies the ID values from the source texture.
So then you have (for a short time) two objects that point to the same texture. When aSprite goes out of scope, it will call UnloadTexture and remove the texture ID from the GPU. So now you have a copy of the sprite in the container that points to an unloaded texture. This will not work for drawing.
If you want to use this pattern, you need to ensure that you don't make copies of things that contain shared resources. The simplest way to handle this is to remove the assignment and copy constructor operators and use std::move or emplace features to ensure that the container owns the data and manages the lifetime.
```
class MySprite
{
```cpp
class MySprite{
private:
Texture2D m_texture = { 0 };
public:
@ -74,10 +73,19 @@ public:
MySprite(const MySprite&) = delete;
MySprite& operator = (const MySprite&) = delete;
MySprite(MySprite&& sprite){
m_texture = sprite.m_texture;
sprite.m_texture.id = 0;
}
MySprite& operator=(MySprite&& sprite){
m_texture = sprite.m_texture;
sprite.m_texture.id = 0;
}
~MySprite()
{
UnloadTexture(m_texture);
if(m_texture.id != 0){
UnloadTexture(m_texture);
}
}
};

Loading…
Cancel
Save