When are public variables in a class OK?

Started by
21 comments, last by dalep 18 years, 5 months ago
Quote:Original post by dxFoo
I use public variables if retrieving them is a speed concern.

You shouldn't.

*edit: I'll be a little less terse. If a variable should be private, and you are making it public just for speed reasons, you're microoptimizing at a dangerous level. Your compiler is extremely smart, and is more than capable of inlining your accessors/modifiers if neccessary. So function call overhead can be ignored. Anything in the body of the function needs to be there to ensure the object remains in a valid state, so it will be performed whether or not you use a function to access the variable. So that overhead can be ignored. But you might forget to call those validation functions, which means you've now increased the possibility of additional bugs without recieving anything in return.

CM
Advertisement
the correct choice to make is that one that will cause you less hassle. Usually this means making everything public. However, if you have an invariant that you want to maintain (the normalized vector was an excellent example), then you probably want to keep the data private, because some ignorant coworker (and that can be you, you are your own coworker!) might come along and screw things up.

So yeah, when in doubt make it public. It is the easier thing to do. Why spend your effort fixing problems that might not be there? We all make mistakes coding but we make different mistakes more often. So figure out which mistakes you make most often and focus on them. Me? I spell strings wrong. I once ruined a program that I had been working on trying to find a bug (oh how I wish that I had source control) that turned out to be that I loaded something like config.tx instead of config.txt! My brain almost exploded after I spend 30+ hours looking for it.
Quote:Original post by Glak
the correct choice to make is that one that will cause you less hassle.

So yeah, when in doubt make it public.
I'm not an expert c++ programmer, so anything I have to say on the subject can certainly be ignored. But I do have to say that I disagree with both of these statements. I don't know whether you mean hassle to code, or hassle to use, but in either case I don't know that avoiding hassle is a particularly good way to motivate software design decisions.

Also, I'd say when in doubt make it private. If you are going to make your variables public you should be sure that you'll never need to change the internal representation or implementation. Even the simple case of public xyz variables can backfire if, say, you later decide to templatize by dimension or otherwise take a more generic approach to your vector library. In this case it's not even about maintaining invariants; you can expose the variables through inline functions that return non-const references. What you're protecting is the implementation, which gives you the freedom to change or improve it without affecting existing code.

Just my $.02.
I have heard these arguments about interface vs implementation many times, and they would be right, were they not based on an assumption that in my experience is usually false. Sorry about that being so long winded. I find that I change interfaces more than I do implementation.

I generally attempt projects that are barely within my ability to accomplish, and I think that most game programmers do the same. Maybe there is some pro out there cranking out his 10th version of tetris, but I think that realisticaly most of us are attempting what is for us a very big project. This means that I don't have time to go back and optimize. I'll save that for when I finish the project, except that I might just move onto a grander project, or I might not even finish the current project. So chances are the implementation won't ever change. The interface might change though, as I might have made a poor design decision.
The point of interface vs implementation isn't necessarily that you need to compile less if you change the implementation, but that you specify a specific contract, expressed as pure virtual member functions, without having to put any implementation details in the contract.

In the implementation of the interfaces, you put the concrete class in a .cpp file, and make all your members public. This makes it really easy to unit test the class, and makes it easy to implement small, collaborating classes without having the befriend everything.

In my mind, there are three kinds of classes:

1) interface classes
2) concrete implementations
3) value classes

The "value class" is your typical Rect, Vertex, or Matrix. The difference between an interface (and its implementation), and a value class, is operator==(). If operator==() examines members and returns equality based on member values, then it's a value class. If it makes more sense to just do operator==() based on the pointer values, then it's an interface/concrete class.

I make the rule that value classes should not have virtual functions -- if you use virtual functions, chances are you want to overload the class, which means that a simple examination of members isn't usually a correct operator==().
enum Bool { True, False, FileNotFound };
Thanks for all the replys. I think I understand why the cone3d tutorial has used a struct for the frame class and made everything in the base class public, its because the sprite class is the one that the user actually deals with really, it has all of the functions for the user in it. Once you have set up the base you don't need to touch it again directly. I suppose someone could mess about with the spritebase but I don't see how I could by mistake. Sound good? Thanks
From my experience programmer who're new to OOP have difficulties with making all variables private and _don't_ add get&set-methods für them. But after some years of practice you'll write classes, that're using variables to store internal data and the public interface just don't need to give them out, because the class' user doesn't want to change that variable, he wants to use the class for the one thing it was written.

For example, take a look at the classes in the C++ standard library they've an interface that let you do everything you need (and more!) but they just don't need get/set-functions for their private variables, because they're only a detail of the implementation.
True I suppose. I guess the best thing to do is to get lots of practice in (which I am going to making this game) so I'l leave it alone for now and maybe re-do the code when I know what I'm doing :)
It depends, on what the variables and how it works.

First of all, is it safe to make it public? For a member to be public the class should expect any possible value for that member and work correctly with any possible value in that member.

Is that value independant? Some classes might not work correctly if you change a value to something without changing some other value. Also a new value could also mean that something else has happened.

Finally , encapsullation is one of the concepts of Object oriented programming, so people shouldn't have public class variables. But not everybody cares about that, in fact, I don't. And if a variable member works correctly being public then it would be a little speed performance and less members for the classes.
------ XYE - A new edition of the classic Kye
I know a surprising number of people that use the speed reason as the justification to make a bunch more stuff public than should be. It's been a while but I seem to remember comparing the code from a public variable to the code generated from an inline accessor to a private variable and they produced the exact same machine code. Assuming this is still true(it should be), speed is a completely wrong justification for making things public(in most cases).

This topic is closed to new replies.

Advertisement