SFML community forums
Help => Graphics => Topic started by: xarxer on January 17, 2010, 03:50:20 pm
-
Hi, I'm going to try to explain this correctly..
Let's say I have a class CEntity, like this:
class CEntity : public sf::Drawable
{
private:
int mX, mY; //An entity always has a position
};
And then I have a class CObject, like this:
class CObject : public CEntity //Derived from CEntity
{
private:
sf::Sprite mTexture; // An object always has a texture
public:
//We want to draw this object via sf::RenderWindow::Draw()
virtual void Render(RenderTarget& Target) const
{
Target.Draw(mTexture);
}
};
Now, is this a bad thing to do?
And how should I do instead?
Let's say I call upon CObject::SetPosition(), there is no position to set?
I'm sorry if it's a bad example, but it was all that I could think of at the moment..
-
When deciding between aggregation and inheritance, you have to know that public inheritance expresses that each derived class object is a base class object. That implies that it makes always sense to treat a derived object as a base object, and a derived class object owns all properties and provides all methods of the base class. (Note: Polymorphism isn't required in all cases you inherit, but if you need it, inheritance is the only option).
If you want only a part of the object to form the public interface, or if it is more meaningful if the class semantically has a CEntity object, choose aggregation.
-
hmm I see your point, but still if I want an object like this:
class CObject
{
private:
sf::Sprite mTexture;
public:
void Move(float x, float y) { mTexture.Move(x,y); }
//Other cool functions and stuff here
};
And now I want to draw it.
Do I have to make a void Draw(sf::RenderWindow& App) function?
-
Do I have to make a void Draw(sf::RenderWindow& App) function?
That's a good solution, I'd do the same.
Note that if you have many functions from sf::Drawable to forward, it may be easier to use private inheritance rather than aggregation. This is semantically equivalent, but private inheritance allows nice syntax shortcuts.
class CObject : private sf::Sprite
{
public:
using sf::Sprite::Move;
using sf::Sprite::Rotate;
// etc.
};
-
hmm that seems like a good soloution Laurent..
But what is the purpose of the virtual void Render(RenderTarget& Target) const;?
-
But what is the purpose of the virtual void Render(RenderTarget& Target) const;?
You don't have to care about this one, it is used by classes that publicly inherit from sf::Drawable.
-
Oh very well then :D
I thought it was there for people to use it to easily make custom classes drawable..
Keep up the good work, SFML is a really nice API :)
-
I thought it was there for people to use it to easily make custom classes drawable..
Actually, it is. ;)
Nevertheless, that still doesn't mean that every object that can be drawn needs to inherit from sf::Drawable. One of the ways is your member function
void Object::Draw(sf::RenderWindow& Target);
An alternative would be to write a function outside your class, which takes your object as parameter and draws it. Either as a member of a class that is in charge of rendering, or as global function.
void Renderer::Draw(const Object& obj);
void DrawObject(sf::RenderWindow& Target, const Object& obj);
Just to show you some different approaches. What fits best for you, depends on your design preferences. I personally like the Renderer::Draw() way because it nicely separates graphics from logics.