To get/set or not to get/set...

Hi there!

So I'm reading about drawing 2D graphics with DirectX, and I've come to making a sprite pool. The author in the book use stuctures, but I thought it was a good idea to use classes instead because I can make constructors initialize the variables instead of making a boring function that loop through it all.

Now, I'm pretty sure I've read before that I should always use get/set functions instead of making the variables public, but I don't quite see how this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class GameSprite
{
public:
	GameSprite();
	inline float GetWidth() { return width; }
	inline float GetHeight() { return height; }
	inline float GetXPos() { return xPos; }
	inline float GetYPos() { return yPos; }
	inline bool GetVisible() { return visible; }
	inline void SetWidth(float newWidth) { width = newWidth; }
	inline void SetHeight(float newHeight) { height = newHeight; }
	inline void SetXPos(float newXPos) { xPos = newXPos; }
	inline void SetYPos(float newYPos) { yPos = newYPos; }
	inline void SetVisible(bool newVisible) { visible = newVisible; }

private:
	float width;
	float height;
	float xPos;
	float yPos;
	bool visible;
};


can be better than this:
1
2
3
4
5
6
7
8
9
10
class GameSprite
{
public:
	GameSprite();
	float width;
	float height;
	float xPos;
	float yPos;
	bool visible;
};


It just looks like more work and more confusing. So what is the best thing to use?
With the first approach you are able to later schange the inner workings of your class (if the need should arise) without having to change all the code that uses it.
I never understood the point of making a [simple] variable private if it has a getter ánd setter. If it needs to be read and written from outside, it should be public.

However, the bigger question is: does it need to be read and written from outside? If not, then there's no reason for either publicness or getters and setters.
I never understood the point of making a [simple] variable private if it has a getter ánd setter. If it needs to be read and written from outside, it should be public.


I certainly agree with the sentiment; I do sometimes do this as future-proofing, so that code written against library version X will still work against library version X+Y; even if the variable being set/got is removed, the functions can remain so something graceful can happen (either making equivalent changes in the class such that the user will never know the difference) or returning an error value. If the user can directly access the variable, it just breaks, and customers get upset, even if they did ignore all the warnings and instructions you gave them.

However, the bigger question is: does it need to be read and written from outside? If not, then there's no reason for either publicness or getters and setters.


My comment above notwithstanding, definitely. Whilst everyone has their own opinion, a plethora of get/set functions is to my mind indicative that the class needs redesigning.
closed account (1vRz3TCk)
For consistence sake if nothing else, I would say make your member data private and provide accessors.

Let's say you have the second version of GameSprite and you need a similar class only this one needs to keep a top limit on its Width. So you make its width data member private and provide accessors to enforce the width limit. Now you have two similar classes that have different ways of accessing the width member data and in one of them; different ways of accessing the other member data.
the book use stuctures, but I thought it was a good idea to use classes instead because I can make constructors

structures can have constructors too, they are not different from classes

as for the public interface of your class, it is supposed to reflect behavior, not internal structure. I would expect of a sprite to have a "move" behavior (which would change its x/y), and "scale" behavior (which would change its height/width).
structures can have constructors too, they are not different from classes


To emphasise what Cubbi says, apart from default public/private (which is carried through to inheritance as well), structures and classes are identical.
First, you can add constructors to structures. They are identical to classes in every way except that they default to public access rather than private.

Second, I don't see any reason to add a getter/setter when you can just make the member variable public.

I think getters/setters are important when you are dealing with an interface class. But if your class/struct is not to be used polymorphically then it seems a little redundant.

As a general rule I tend to use struct for pure data and class for entities that manage their own internal hidden state.

So I might be tempted to do something like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
struct sprite_info
{
	float width;
	float height;
	float xPos;
	float yPos;
	bool visible;
	
	sprite_info()
	: width(0.f)
	, height(0.f)
	, xPos(0.f)
	, yPos(0.f)
	, visible(false)
	{}
	
	sprite_info(width, height, xPos, yPos, visible)
	: width(width)
	, height(height)
	, xPos(xPos)
	, yPos(yPos)
	, visible(visible)
	{}
};

But if the sprite object is intended to manage itself somewhat (other than just initializaion):
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
26
27
28
29
30
31
32
33
34
35
36
37
class Sprite
{
private:
	sprite_data data;

public:
	Sprite() {}
	Sprite(const sprite_data& data): data(data) {}

	void draw(Graphics& g);
	void move();
	void save(std::ostream& os); /* save sprite_info to output */
	void load(std::istream& is); /* load sprite_info from input */
};

int main()
{
	// ...
	
	Graphics g;
	Sprite sprite(sprite_data(120.f, 60.f, 0.f, 0.f, true));
	
	while(!done)
	{
		sprite.move();
		sprite.draw(g);
		// etc...
	}
	
	// ...
	
	std::ofstream ofs("savedgame.data");
	sprite.save(ofs);
	
	// ...
}

Now the sprite_data doesn't need to be public because all of the functions that operate on the data are part of the Sprite class.
Topic archived. No new replies allowed.