Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Public variables bad practice vs Getters and Setters functions? [closed]

Tags:

c++

I came across this during his stream, and this stuck out to me like a sore thumb since. I thought maybe if I saved the video and come back to it in the future when I'm more proficient I'll understand it, but it just kept on bothering to just leave it be. Here's the video...

It automatically starts at 1:13:00 for you.

https://youtu.be/uHSLHvWFkto?t=4380

As a new programmer to C/C++ after hearing this its completely warped my way of thinking. With him being a professional and all I should take the advice, but I need some clarity. From sites, videos, to books, I've read that the use of public variables is a bad practice, but from what I'm getting from this video its saying otherwise. In the video he's uses a struct which by default has a access modifier of "public" vs a class which has a default access of "private". Is there something I'm not comprehending properly here.

I don't know what to do. If I make my variables public won't I risk ambiguity ? The way he's saying that he'll automatically fire someone for coding in format is getting to me haha! Which one should I truly use ? When and Why ?

like image 776
PrimRock Avatar asked Sep 17 '15 08:09

PrimRock


People also ask

Why do we use getters and setters instead of public variables?

Getters and setters are used to protect your data, particularly when creating classes. For each instance variable, a getter method returns its value while a setter method sets or updates its value. Given this, getters and setters are also known as accessors and mutators, respectively.

Should getter and setter methods be public or private?

Usually you want setters/getters to be public, because that's what they are for: giving access to data, you don't want to give others direct access to because you don't want them to mess with your implementation dependent details - that's what encapsulation is about.

Is it important to always define setters and getters for all the private variables?

It is not necessary to write getter or setter for all private variables. It is just a good practice. But without any public function you can not access the private data(variable) of the class.

Why is it not recommended to make all of a class variable public?

Public variables in general in a class are a bad idea. Since this means other classes/programs, can modify the state of instances.


2 Answers

In my experience people use getters/setters excessively for no good reason.

One can think of two major kinds of classes: the ones grouping together related data and the others providing behaviour.

Behaviour classes must be encapsulated with no public data members.

Data classes normally should have data members public and no behavior.

The grey area between these two is mutable data classes with invariants or dependencies between members, e.g. if member a is 1, then member b must be in range [1-10]. For such cases usage of getters/setters may be justified. For immutable data classes the constructor must establish the invariant.

like image 138
Maxim Egorushkin Avatar answered Sep 25 '22 03:09

Maxim Egorushkin


First of all, a struct is completely equivalent to a class, but with the default member access being public rather than private.

Now, in Object Oriented Programming (OOP), it's not considered good practice to have public data members (variables), because that makes all your code dependent on the internals of the class, and thus breaking a primordial principle of OOP, and that is...

Holy and Sacred Encapsulation

Encapsulation is the coding philosophy that states that a class should englobe both data and the code that manages it in a single tight entity. That is, you don't access data directy, but rather you use methods from the class to manipulate such data. This has several design advantages, such as that you'll know that no code except the one inside the class may incorporate bugs with respect to the manipulation of such information.

Now, get()ers and set()ers, otherwise known as accessors, are a complete lie! With accessors, you're tricking yourself into thinking that you're respecting encapsulation, when you're rather breaking it! It adds bloat, unnecessary verbosity, bugs, and everything but encapsulation. Instead of having a class Person with unsigned getAge() and void setAge(unsigned), have it with a unsigned getAge() and a void incrementAge() or however you want to call it.

Now, to your question's core...

"Plain old" structs

Encapsulation is not always desired. Although you should (usually) not do this on header files (again, for at least some bit of encapsulation), you may create static plain old structs that are private to a single translation unit. My recommendation is to make them even "older" than they already are, i.e...

  • All data members are public.
  • No methods.
  • No constructors (except implicit ones).
  • Inheritance is always public, and only allowed from other plain old structs.
  • I repeat, don't put them on header files!

Now, another use for plain old structs is (ironically) metaprogrammatic exporting of constexpr data and types, otherwise known as modern-hardcore-template-metaprogramming-without-having-to-type-public-everywhere, for example...

template<bool B, typename T>
struct EnableIf {};

template<typename T>
struct EnableIf<true, T> {
    typedef T type;
};

template<bool B, typename T>
using SFINAE = typename EnableIf<B, T>::Type;
like image 36
3442 Avatar answered Sep 23 '22 03:09

3442