Advertisement

Classes, and the "correct" way to access private variables

Started by June 09, 2002 05:07 PM
10 comments, last by Peon 22 years, 5 months ago
Hey all I''m still working on my GDI "Tank Wars" type game, and am going with an object oriented approach. One problem I''ve been having is how I should be accessing private memeber variables. For example, each tank has variables such as position, current angle, current weapon, hull strength, etc... and each of these is a private variable. However, other functions (such as the outputting to screen what the angle is) need to know the value of these variables. This has caused me to have to add several acessor functions to my TankClass... queryAngle(), queryPosition(), etc... Just wondering, is there a more efficient or correct way of doing this? It seems kind of overkill Thanks in advance! Peon
Peon
If the tank stores all the angle, weapon, and hull strength data, it should probably be in charge of displaying it all itself. I'm no OOP expert, but I think if you encapsulate ALL the tank-related functionality in the tank class, then you'll have no need for all those accessors.

It seems to me that having a lot of outside functions access private members through accessors defeats the purpose of making them private in the first place. If they're private, things outside the class should not have to know about them.




Things are not what they are.


[edited by - myme15 on June 9, 2002 6:26:33 PM]
Advertisement
Depends on your personal style. You could make a member function embedded with the tank class that takes in a screen or HDC class, for example, and then draws to it, using it''s own access to the private variables. However, if you want some cross platform action, this may sorta prevent that. If you have a screen, or rendering class/function, you could make that class/function a friend of the tank''s class, that would give the rendering class complete access to private variables, but most people don''t like doing that, because it breaks encapsulation.

So it depends on whether or not the code''s going to be reused, if other people will be using it, personal preference, etc...

If you have the query methods inline, that''d technically, be the best way, allowing others to read those variables and with speed. But doing all those query methods does require more coding.
___________________________Freeware development:ruinedsoft.com
It depends on how much TankClass is a self-contained object. If it primarily consists of data members that other classes manipulate, then you may be better off making it a struct will public data. A few public helper methods will be acceptable as well. If, however, your tank handles a significant amount of work needed to handle movement, displaying, collisions and so on, then make data members private and provide accessors.
---visit #directxdev on afternet <- not just for directx, despite the name
Thanks for the help guys The reason I want to access the variables and not have the tank display it is because, well, I don''t know if a tank should be displaying anything. Hence, I created a "taskBar" class to take care of that. Perhaps this is not the best way to do it, hehe.

Another thing I was thinking of (and I think someone mentioned it above) would be to have a struct, called, say, tankStats that would be private, andthe advantage to this would be that I need only one query function to use it. As of right now, I''m querying for power/angle/etc seperately, which seems like a real waste. Are there any disadvantages to doing it this way (using a struct with all the data)?

Thanks again
Peon
nah, using a struct should be fine, it would be a good idea to return the data struct by const reference, unless your taskBar class actually needs to modify the tank variables.
___________________________Freeware development:ruinedsoft.com
Advertisement
quote: it would be a good idea to return the data struct by const reference, unless your taskBar class actually needs to modify the tank variables.


Thanks for your reply, once again! Just to clarify what you mean here... I would so this using pointers and such correct (sorry, don''t have enough experience with them, and want to make sure I''m trying to do the right thing )? If I''m understanding correctly, this would be like being able to determine what the values of the struct variables are, without having to return an actual struct?

If so, I think this would be ideal for communication bewteen several of my classes, since they need to interact with one another.
Peon
You should keep the accesors. They allow you to change the inner working of the tank class and still work with the outside.(for example, you might change the way the position is stored)
Furthermore set/get methods allow you to control the state the tank is put into. If the members are public someone might set its hitpoints to -10 which might be an invalid value(okay, it might not be too serious in this simple case). With a setHP-method you can disallow this behavior(either raising an error or just ignoring the command, keeping the tank instance in a valid state).
Stick with the get/set methods, just inline them.
The standard OOP approach is to keep data variables private and create accessors for them all. However, whoever said a game is standard. That way of designing things is useful in apps where the lifetime of the app is large, ie Microsoft Word, and you want to keep reusing components without rewriting the whole shebang. In game programming, there is less need for this, especially if you are the only one working on the project. Most game systems get rewritten in the next iteration anyway. So, until you learn the ins and outs of making a game engine, just concentrate on making your game work, then later on with some experience under your belt you will be able to see yourself some areas that require encapsulation and other areas don''t.

---
Make it work.
Make it fast.

"Commmmpuuuuterrrr.." --Scotty Star Trek IV:The Voyage Home
"None of us learn in a vacuum; we all stand on the shoulders of giants such as Wirth and Knuth and thousands of others. Lend your shoulders to building the future!" - Michael Abrash[JavaGaming.org][The Java Tutorial][Slick][LWJGL][LWJGL Tutorials for NeHe][LWJGL Wiki][jMonkey Engine]
Why not just make the tank a complete package, and when a function needs to know how the tank is doing, it sends a message to the tank and says "hey, whats up?" then the tank says "well, in this past loop i died, so sorry." or it says "The last time around i took a beating, but i just updated everything, so keep rollin'."

This is why you would want to create a class. Then, if you create a file (for example tank.h) you can reuse it in future code projects, or update it as necessary. all functionality of the tank class resides in the tank class. Your program just wants to know certian things from it, but doesn't rely on data in the class to make calculations unique to the tank. The tank does this.

Do you think Generals in the field command every aspect of every tank that they send out? Of course not. They send out a tank "package" and tell them to take out a building. The tank "package" worries about the details. Then later they send a message to this tank "package" askng how everything is going, or their current position.

This makes everything really easy. In fact, you could have an accessor function called tank::update() which would just update everything.

NOW....

This is cool if you plan on making a whole entourage of tank objects. But if you have two objects on the screen, then maybe a struct is much better. But think about this: how cool would it be if you encapsulated the tank AI code in the tank class, so when you called tank::update(), it updates it's own position based on some certain values? then when you are ready to draw to the screen, you just obtain the tanks new position calling tank:: Position()?

[edited by - MrBeaner on June 11, 2002 1:54:07 PM]
------------------------------------------VOTE Patrick O'GradyWrite in Presidential CandidateThe Candidate who Cares.

This topic is closed to new replies.

Advertisement