What's the point of private class members and methods(C++)

Started by
18 comments, last by davepermen 11 years, 10 months ago
When I'm writing classes in C++, I never make anything private. Why?

Because it makes me have to write more code to interface between the public and private parts of the class. This, in turn, increases the time I spend on the project for no gain. I know how the class works and how to use it because I wrote it.

I like to have everything public so that If i'm using the class later, and I need it to do something a little different, It may be possible by tinkering with methods and members that should be private.


If you are using a class that someone else wrote, I still belive that you would benifit from having everything public. You would still learn how to use the class through the usual means of looking at the documentation, reading tutorials and reading header files. The only difference is that you would have alot more freedom in how you use it.


To be honest, I think I'm missing something big, can someone enlighten me?
Advertisement
Freedom also comes with responsibility. When you have direct access to a class' members, you also have to ensure that its invariants are not invalidated. Restricting direct access to members is a way to ensure that its invariants are not invalidate.

If you can only interface with a class through a very limited set of points (its member functions, and not anywhere in the user's code), then you also have a very limited set of places where you have to ensure the class' invariants.
One aspect of it of course is being able to make sure your class functions correctly at all times, which comes down to as Brother Bob said making sure your class invariants remain valid at all times. If you are able to formally prove that your class will behave correctly at all times you'll have a much easier time debugging said class, and since a huge amount of development is spent debugging this is a good thing.

When you look at it less formally it pretty much comes down to making sure that you don't do or that someone else using your code doesn't do anything majorly stupid. Try to assume that the people using your code (and yes that includes yourself) have no idea what they're doing. This could well be true if you're working on a large project, and if you have to deal with code you have written a year ago and which you haven't touched since. The chance of touching a function which could possibly mess with the validity of your class will become quite large, with the result that you'll introduce some very nasty and hard to find bugs.

So in the end, use the private modifier where needed, it'll save you from a lot of headaches in the end smile.png

I gets all your texture budgets!

To be honest, I think I'm missing something big, can someone enlighten me?[/quote]

Private state encapsulates class invariants.

Here's a good criteria - if I take any public member and modify it, can I leave class in broken/inconsistent/invalid state? If yes, that's variable is class invariant and it must be hidden away as public.

struct String {
char * data;
size_t length;
}

String s;
...
s.length = 2000; // oops, we say we have 2000 characters, but data was only allocated for 60


Another example:struct Person {
std::string name;
std::string address;
}

Person p;
p.name =""; // fine
p.name = "akstgh;a jfdgh;siodhfg; oainhrg; oa he;orgha n;odih a;oiga ;oi"; //fine
p.address = "42 Wallaby Way"; // fine
Nothing I can do in this case can break the class. All values are valid, all class invariants are enforced by string itself. Some values might not make sense, but that's for rest of application to enforce.


Another good criteria is this:
If I take any public member and assign it completely random value, will the class break? Then it cannot be public.
Systems with everything being public will most likely turn into an unmaintainable mess.
Exposed implementation details mean you can't change them without affecting lots of dependent stuff.
Having a huge public interface introduces a massive amount of coupling, side effects and resulting efforts to maintain them.
Lean interfaces mean less possible points to break things.
Well thought interfaces are also implicit documention (and forces you to think and rethink about requirements and finding optimal solutions instead of just typing p-u-b-l-i-c and going on)

All in all, this is one of the biggest no-nos you can think of.
Writing software is just too complex - you have to introduce shields and safety guards.

Another good criteria is this:
If I take any public member and assign it completely random value, will the class break? Then it cannot be public.

Yeah, but perhaps phrase that as "If I take any public member and assign it completely arbitrary value, will the class break?"

Another reason could be that you don't want the user to be taking the address of a member for whatever reason, so your getter function will only return a by-value copy
You might also want to later add code to the getters and setters to check for the validity of the value or something like that if its a more complex class.

o3o


I know how the class works and how to use it because I wrote it.


That's going to change when your code starts getting to tens of thousands of lines. I have code that I wrote years ago and haven't touched since. I can't remember how it works and even if I scan the code and start to remember the general flow, there is no way I can remember all of the intricacies.

Making everything public means that anyone using that code (including you) has to know exactly how it works and exactly what changing any variable would do. You can get away with making everything public for a tech demo or proof of concept, because they are programs which will get coded and never touched again. But for anything else, "an ounce of prevention is worth a pound of cure"
I had the same initial reaction to using private when I first heard about it, maybe 20 years ago. During this time I have learned that there is real value making the public interface be what you want anyone to be able to do with your class, while details of how those things are achieved can be kept private and changed at any time, without having to worry about breaking the caller's code.

Another type of seemingly artificial constraint that is really useful is `const'. Just as it is with `private', if you use it correctly the compiler will stop you from accidentally doing things that you are not supposed to be doing, and you will have many fewer bugs in your code.
At the end of the day even if you encapsulate something someone can still get in there and change its value if they really want to through some terribly hacky techniques. You can't stop THAT level of stupidity but what you can do is hinder most people doing most stupid things and that's a good thing.

I don't know where I am on this topic yet really. I have seen a lot of cases in the games industry where 'solid' OO practices such as inheritance, encapsulation, overloading, overriding, templates and so on hinder productivity through over engineering and that is a bad thing. Although there is some sound advice in this thread it would be good for you to find out through attempting to use your own codebase as it grows larger and larger and learn your lessons that way. I can't tell you how many iterations of coding style and approach i have been through while feeling out what I personally think is the best way.

Your opinion will no doubt change as you become more experienced.

This topic is closed to new replies.

Advertisement