Sign in to follow this  

Proper C++ Programming

This topic is 4839 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I just wanted some peoples' opinions on what they thought about the proper way to organize classes when programming games in C++. In all the classes I've taken, the instructions were always "all variables and some functions should be private, and only other functions should be public. However, in games, do you think it matters to make an object's world position public, so that it can be quickly accessed during the game without having to make a function call as opposed to making Get/Set functions that do the same thing? After all, many people program games in straight C, which uses no classes at all. I was just hoping to get some peoples' opinions on this, as I am a relatively new coder when compared to most programmers, and I'm trying to avoid bad programming habits.

Share this post


Link to post
Share on other sites
I think get/set functions are a good idea, you should have them inline meaning they'll be no overhead using them at all just like if you'd accessed them directly (unless your compiler really sucks). The advantge of get/set functions is that if you decide to alter how something is represented inside a class you only have to change the get/set functions and not every piece of code that uses the class. A good rule of thumb is that when designing a class it should made it such a way that if you want to alter how something works within the class, code that uses the class should not have to be altered.

Share this post


Link to post
Share on other sites
The get/set function overhead is insignificant when compared to the rest of the game. Plus, you may want to add functionality to the get or set function later on in development, this way you only have to make one change rather than everywhere the variable is accessed.

EDIT: What Monder said...

Share this post


Link to post
Share on other sites
Personaly I don't use get/set methods, however, I have never made a really big project. Everytime I try get/set they quickly start to annoy me. While in theory you may want to do something special to happen when you access a variable, it rarely happens in practice.

Share this post


Link to post
Share on other sites
I've readed somewhere paper by Stroustrup himself where he says that overuse of getXXX/setXXX thingies sometimes may be a sign that something is going wrong. As i understand he mean that if you need many get/set things, you aren't working with class from outside as with highter abstraction level than it's components, and it's not good, and get/set is not a solution...

it's not an issue with Delphi, where you have "properties" that can be mapped to variables or to function, and you can swich to using properties at any stage of work, when you'll think it's needed.

edit: but i would prefer get/set things for my "CoordSys" class , so i will be able to cache matrix it corresponds to and do some other optimizations.
(my CoordSys class contains one 3-vector and one quaternion, and among other things have functions like "GetTransformTo" and "GetTransformFrom" that returns 4x4 matrices. So i'll be able to automatically cache that matrices, and will improve speed at little typing cost.)

Share this post


Link to post
Share on other sites
Quote:
Personaly I don't use get/set methods

Maybe that's what I was trying to get at -- how many people actually make use of get/set methods. They sound like nice ideas, but whenever I write them, they're usally just returning a variable (which I think is the point). Maybe its that I'm just lazy and think that less typing is easier, so I often just make variables public, and access the variables directly in other files.

Share this post


Link to post
Share on other sites
Quote:
Original post by wyrzy
I just wanted some peoples' opinions on what they thought about the proper way to organize classes when programming games in C++. In all the classes I've taken, the instructions were always "all variables and some functions should be private, and only other functions should be public.

However, in games, do you think it matters to make an object's world position public, so that it can be quickly accessed during the game without having to make a function call as opposed to making Get/Set functions that do the same thing? After all, many people program games in straight C, which uses no classes at all. I was just hoping to get some peoples' opinions on this, as I am a relatively new coder when compared to most programmers, and I'm trying to avoid bad programming habits.


Unless your compiler is absolutely horrible, your function calls should be inlined and will be equally as fast as accessing public data directly.

I wrap up everything in classes when I use C++, and my C++ code is almost always faster than the equivalent C program. I never use public data.

To write fast code, you must write flexible code. If your code is flexible, you will be able to optimize it much more effectively later on. You will always be able to optimize flexible code. If you used global variables all over your program because you thought it would be faster (even though it is not), then you will have an absolutely horrible time trying to optimize because your code will be so rigid.

You must first get something working correctly, written in a flexible way. Then benchmark and profile and prove to yourself what needs to be optimized. Now you can optimize effectively since you know what parts need it, and you have written flexible code that will allow easier modification.

This is the best advice anyone has ever given me on writing fast code. I'm going to be late to work for taking the time to write this, but it's important [wink]

Quote:

Never, never, never, never, never optimize a program before it is working correctly. And when I say never, I mean not ever.

The only exception to this rule is in the choice of algorithms. There is no sense in picking a bad algorithm to start with. And even if you did happen to pick the wrong algorithm, then it is not hard to change it.

Premature optimization does absurdly more harm than good. For every ounce of benefit, there are a trillion gallons of downside. When you start programming ANYTHING, write clear, simple code that best expresses the algorithm in the most straightforward manner.

Now, let's go farther. Suppose that you have chosen some fundamentally bad data structures. If your program is written in an abstract enough manner, it won't matter. And the more abstract you make it, the less it will matter.

My point:
1. Write clear code
2. Choose good algorithms
3. Write abstract code that hides the implementation details when possible
4. When everything works well, profile it.
5. Speed up the stuff that will benefit from it.

Share this post


Link to post
Share on other sites
Quote:
Original post by wyrzy
However, in games, do you think it matters to make an object's world position public, so that it can be quickly accessed during the game without having to make a function call as opposed to making Get/Set functions that do the same thing? After all, many people program games in straight C, which uses no classes at all. I was just hoping to get some peoples' opinions on this, as I am a relatively new coder when compared to most programmers, and I'm trying to avoid bad programming habits.


Before you start thinking in terms of public data vs. simple accessor/mutator, think:

Why do I want to know this object's world position? Why can't it just react to its environment?

Why do I want to tell this object its world position? Even if it can't be responsible for moving itself, maybe I should just be telling it which way to move, and let it make the attempt itself?

Share this post


Link to post
Share on other sites
For collision detection, you'll want to know the positions of at least two objects, the code that does the collision detection will have to get the position of at least one of the objects, no matter where the code is located.

Share this post


Link to post
Share on other sites
Quote:
Original post by MonkeyCookie
For collision detection, you'll want to know the positions of at least two objects, the code that does the collision detection will have to get the position of at least one of the objects, no matter where the code is located.

But do you really need accesors for that?
Depending on the architecture, the object might just as well notify the collision sub-system about world position changes.

Share this post


Link to post
Share on other sites
Quote:
Original post by Dmytry
it's not an issue with Delphi, where you have "properties" that can be mapped to variables or to function, and you can swich to using properties at any stage of work, when you'll think it's needed.
)


All modern C++ compilers have a property extention - C++ Builder works the same way Delphi does!

Share this post


Link to post
Share on other sites
Quote:
Original post by darookie
Quote:
Original post by MonkeyCookie
For collision detection, you'll want to know the positions of at least two objects, the code that does the collision detection will have to get the position of at least one of the objects, no matter where the code is located.

But do you really need accesors for that?
Depending on the architecture, the object might just as well notify the collision sub-system about world position changes.


This garuantees a duplication of data which almost always horrendous bad and sometimes just really bad.

The OO belongs at a higher-level. Use it hook the objects to the services they need, then let the data flow uninhibited. With C++ you don't have to use OO and virtual methods to decouple the components.

Share this post


Link to post
Share on other sites
Quote:
Original post by Magmai Kai Holmlor
All modern C++ compilers have a property extention - C++ Builder works the same way Delphi does!

Last I heard GCC refused to implement it, which is a huge shame. Of course, they support typeof() just fine. I think one of the arguments leveled against properties was the fact that you can contort templates into doing it for you...which is impressive but you end up having to store member function pointers all over the place. :(

Share this post


Link to post
Share on other sites
The reason why we encapsulate data meaning making data members private to enforce access and update through member functions i.e. getters & setters are:

1. You determine that your type's represenstation is variable, meaning its data members can change over-time be it the name or the type of the memeber, if you did not encapsulate the variant then clients of your type will be tightly coupled to its representation thus if your type's represenstation changes then all clients are forced to update there code to reflect the changes and then recompile it all.

By encapsulating the variant you make loose coupling by indirection, enforcing clients to access/update through an invariant interface i.e. member functions.

2. You determine that your type has a state invariant meaning that the representation has range of valid values but clients are allowed to update the representation so to enforce the state invariant you make the representation private and enforce clients to use the interface i.e. member functions to update without putting the instance of that type in an undefined state. If the represenstation is public how could you ever maintain the state invariant from clients? exactly you couldn't clients could easliy set invalid values into public data members.

So to summarize this:



  • encapsulate the variation/variant and provide invariant interface to it <-- important is the first key to abstraction


  • if your type has a state invariant then encapsulate it by making it private and enforce access/update through the interface i.e. member functions, there-for never putting an instance of that type in an undefined state.



If your type has none of these criteria then there is no reason to make it private, your type probably is not a real type and is nothing more than an aggregate/compound data structure.

A very good example of a type that does not encapsulate its data members and nor does it need to is the standard library type std::pair, a pair has 2 members and this will never change it has no state invariant to maintain there-for its members are public.

Also note if your type has lots of small fine grained accessor methods i.e getters/setters then again you've modelled your type at the wrong or mixed the levels of abstraction and you've probably got nothing more than a an aggregate/compound data structure. If its mean't to really represent a proper type then perhaps your type's representation should be grouped into new types.

Share this post


Link to post
Share on other sites
It's the best advise to give. You can ignore it in many scenerios without serious regret, but sometimes you will severely regret not following it. How severely depends on how doggedly you ignore it. If at the first sign you shouldn't have done that you change it then not too severely. If you are determined to not do it then you can create one hell of a mess when you work around the problems it caused instead of fixing the problem.

Share this post


Link to post
Share on other sites

This topic is 4839 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this