News for hackers. Stuff that matters.
Re:Ask HN: Why do you make class members private? by xboxnolifes on Monday July 25, 2022 @03:19PM (#32229577)
The reason is simple: to prevent objects from getting to an invalid state.

The set of property values of an object is its state, and you can model every possible valid state and state transition. Not every state is valid. If you allow all variables to be touched willy-nilly, you allow an object to be put into an invalid state.

The only variables and functions that should be public are those that cannot put an object into an invalid state.

Re:Ask HN: Why do you make class members private? by robalni on Monday July 25, 2022 @03:54PM (#32230059)
> The only variables and functions that should be public are those that cannot put an object into an invalid state.

That's an interesting one. So a reason to use private is to tell programmers that calling this function or changing this variable can leave the object in an invalid state? I guess invalid state then means that you can't call a public function on that object.

It might not be clear what an invalid state is though. I mean, every state has its place. Example, after I decrease the health of the player to 0 but before the death animation is played, is that a valid state? I should not be able to play in that state but it's a state that the player might be in for a frame and it will be visible on the screen.

Re:Ask HN: Why do you make class members private? by Jtsummers on Monday July 25, 2022 @04:05PM (#32230200)
Invalid state means invalid state. Suppose (going with my bounded stack example from another reply to you) you initialize the stack with:

  a_bounded_stack = new BoundedStack(100);
There are various actions applied, correctly, through the interface (push, pop, and peek). Somewhere, you decide to manually alter the size of the stack but not through its interface (resize)

  a_bounded_stack.limit = 50;
But you forget (someone came by with cookies) to actually shrink the backing array and also to change "top". So now you end up with this state:

  a_bounded_stack
    limit = 50
    array.size = 100
    top = 60
Oops, top is not allowed to be larger than limit, and array.size is supposed to be equal to limit. That is an invalid state, people can still use the public interface (push, pop, peek), but who knows what they'll get back.
Re:Ask HN: Why do you make class members private? by robalni on Tuesday July 26, 2022 @03:34AM (#32235428)
> But you forget (someone came by with cookies) to actually shrink the backing array and also to change "top".

Someone could come by with cookies while I'm writing a private function too. This is more of a reason for having a function for doing something. Is the reason to make those variables private then to tell the programmer that there is a function that changes them and that you have to look through all the functions of the class before you touch them to see if there is a function that does what you need?

Re:Ask HN: Why do you make class members private? by xboxnolifes on Monday July 25, 2022 @04:09PM (#32230258)
If it's intended to be in that state, then it's valid.

But following the example: if you made the player's health a public property, code could straight up just set it to a negative number. The game engine this is running in may not properly support a negative health value. If instead it was set using a public method, there can be added checks to lower bound health to zero. And depending on the architecture, all of the post death animation stuff could also be handled as a check in that function call.

Re:Ask HN: Why do you make class members private? by robalni on Tuesday July 26, 2022 @03:49AM (#32235512)
Ok, let's assume we only care about states that's always invalid, like negative health. So then my question is the same as for Jtsummers: is private a way to tell the programmer to look at all member functions to see if there is already a function that does what you need?
Re:Ask HN: Why do you make class members private? by xboxnolifes on Tuesday July 26, 2022 @07:45PM (#32245431)
From your other replay:

> Is the reason to make those variables private then to tell the programmer that there is a function that changes them and that you have to look through all the functions of the class before you touch them to see if there is a function that does what you need?

I'm not sure I understand the question.

A private property is a property that a class user should have no reason to want to directly write to. Or more accurately, it's a variable that directly writing to could invalidate the state of the object. They are intermediate values or implementation details that define the state of the object. Reading them should be fine, but allowing unrestricted writing is dangerous. If there is reason to directly change the value, there should be a public method that includes validation to prevent the user from invalidating the object.

On the other hand, private methods exist for code re-use convenience purposes. You could just as easily only have public methods and write all logic inside of them. But a lot of the time you have pieces of code that could be reused between methods, but on its own doesn't guarantee the object to be in a valid state at the beginning or end of the call. So, you make it private. It only exists as a means of avoiding code duplication and possibly improving readability.

Private methods may also have value in inheritance / abstract classes, but I'm focusing on invalid state.

Re:Ask HN: Why do you make class members private? by robalni on Wednesday July 27, 2022 @03:59AM (#32247971)
> A private property is a property that a class user should have no reason to want to directly write to.

What the user of a class has reason to do depends on what they need to get done. Maybe there is a function that already does what they need to do or maybe there isn't. So the choice is: call a function or write code that directly accesses the variable. This is a choice you would have both for private and public variables. But people say that they make things private because the class user should use already existing functions instead of touching the variable directly if there is already a function that does it. So does that mean that private is a way to tell the class user that there are functions that touch this variable, to increase the chances that the class user finds and uses them?

Re:Ask HN: Why do you make class members private? by xboxnolifes on Wednesday July 27, 2022 @04:17PM (#32256298)
> So does that mean that private is a way to tell the class user that there are functions that touch this variable, to increase the chances that the class user finds and uses them?

I would say private is a way to tell the user to not touch the variable, or to use an accessor function that has validation to prevent entering invalid state.

At this point I feel like I'm just repeating myself, as I can't imagine a concrete example of what you're asking. Could you give a hypothetical, or better yet real, example of what you're thinking of here? I can't think of any at all. I felt that the example by Jtsummers was a great illustration.

Re:Ask HN: Why do you make class members private? by robalni on Thursday July 28, 2022 @05:10AM (#32262007)
> I would say private is a way to tell the user to not touch the variable, or to use an accessor function that has validation to prevent entering invalid state.

That's what I meant, that it's a way to tell the programmer that you may not need to touch this variable directly because there are already functions that do that so please look at those functions to see if there is one that does what you need. Private then makes sure that all functions that touch the variable are added to the list because you can't use a private variable in a function not in the list. The list I'm talking about is the function declarations/definitions in the class.

This C++ code doesn't compile because `number` is private by default:

    class A {
        int number;
    };
    void zero(A &a) {
        a.number = 0;
    }
But this works because now `zero` is added to a list of functions inside the class and that way the function is easier to find for someone who wants to modify `number` (assuming the function and the class were not already defined right next to each other):

    class A {
        int number;
        void zero();
    };
    void A::zero() {
        number = 0;
    }
So the idea is that private can help with reusing code because it makes sure that all functions that modify the variable are listed in the class, which increases the chance of them being used.

Otherwise, what's the difference between my two examples that makes the second one better than the first one (other than that the first one doesn't compile)? The only difference is that the function has been added to a list inside the class and got a slightly different name.

Re:Ask HN: Why do you make class members private? by xboxnolifes on Friday July 29, 2022 @04:06AM (#32274274)
I think the disconnect between me and you here is that you're looking at the the "user" ("programmer" in your comment) in our hypotheticals as a person who is going to implement the class. In my mind, they are the person who is using the class. They will not be implementing unimplemented function signatures. In my mind, in my comments, they are library users. I'm thinking of someone who is using std::vector and using std::vector::pop_back instead of trying to access the underlying container, grabbing the value, deleting the value, and setting the private variables to match the new state.

> Otherwise, what's the difference between my two examples that makes the second one better than the first one (other than that the first one doesn't compile)? The only difference is that the function has been added to a list inside the class and got a slightly different name.

The second one is not better than the first one. I would say it's a completely pointless approach to a problem, and would be better served by just making number public. Leaving an empty zero function signature around so someone can come by and fill it in to do what they want serves absolutely no useful purpose at all here. If zeroing out the number property of class A is useful for A, then it should be an already implemented function.

That being said, the example given, in my eyes, is not useful. What is "number"? Why is it private? What does "A" do? What are it's expected states? What are it's failure conditions? If A cannot enter an invalid state by changing number, there is no reason for it to be private.

As I previously said, private exists to prevent objects from entering invalid states from external influence. If A#number has no invalid state, then it need not be private.

Re:Ask HN: Why do you make class members private? by robalni on Friday July 29, 2022 @08:26AM (#32276021)
> They will not be implementing unimplemented function signatures. In my mind, in my comments, they are library users.

I clarified in the question that I'm only asking about situations where everyone has access to all of the code. So are we assuming that the organization is structured so that only one person/team works on a class and that no-one else is supposed to touch it? Or why would the class user not write a new function that accesses the member variables? Is it because the variables are private, which tells them to look at existing functions, just like I described?

> That being said, the example given, in my eyes, is not useful.

Ok, let's do a more useful example, a string class, where we assume that `len` may never be negative (and we assume that there are other string functions defined in the same way as `truncate` to make the class more useful; I just didn't want to write them in this example).

Code 1:

    class Str {
    public:
        char *data;
        int len;
    };
    
    void truncate(Str *s) {
        s->len = 0;
    }
Code 2:

    class Str {
        char *data;
        int len;
    public:
        void truncate();
    };
    
    void Str::truncate() {
        len = 0;
    }
What's the difference between these two and why is code 2 better than code 1? As I currently understand it, the difference is that in code 2 the truncate function has been forced (because of private member variables) to be added to a list of functions inside the class, which makes it easier to find the function for someone who wants to truncate the string and therefore it reduces the risk that someone implements that function again when it already exists.
Re:Ask HN: Why do you make class members private? by dragonwriter on Wednesday July 27, 2022 @04:29PM (#32256448)
> is private a way to tell the programmer to look at all member functions to see if there is already a function that does what you need?

Private is a way of excluding the member so designated from any consideration at all by a consumer of the class. Assuming that they see it at all (which if it is in a compiled library using normal tooling they might well not at all), they are effectively told to treat it as if it does not exist.

There may exist mechanism to bypass this (especially in dynamic languages and/or those with robust introspection/metaprogramming), but that's breaking the warranty seal on the class.

All the functionality that a class provides to consumers is provided by its public members. That's what public members are.