0

I've been told not to make my variables public inside a class. I should always make a get and a set function. For example :

class Whatever
{

public:
  void setSentence(const std::string &str) { sentence = str; }
  void setAnInteger(const int integer) { anInteger = integer; }

  std::string getSentence() { return sentence; }
  int getAnInteger() { return anInteger; }

private:
  std::string sentence;
  int anInteger;

};

Why should I do that? Isn't just simply using those variables more convenient? Also, is that a good c++ programming style?

Timothy Shields
  • 75,459
  • 18
  • 120
  • 173
Davlog
  • 2,162
  • 8
  • 36
  • 60
  • 2
    Many people will also council you against getters and setters of member data *per se*, in favor of getters and setters of *features of the modeled object* (to preserve implementation independence). – dmckee --- ex-moderator kitten Jun 06 '13 at 17:09
  • You do it if you want to control access/hide implementation (pimpl, anyone?). And yes, if it's inline, there is no penalty. You just don't do it "for the sake of it". Only do it if you _really_ intend to change the implementation without changing the interface. – sehe Jun 06 '13 at 17:09
  • Properties are state. If your object needs to update state when its properties change (e. g. a view object may need to redraw itself upon being resized), then you may need to be able to execute code. –  Jun 06 '13 at 17:10

7 Answers7

6

The main reason is to increase encapsulation. If your class exposes those member variables, many functions in your client code will have a dependency towards those variables.

Suppose one day you want want to change the name of those variables, or you want to change the implementation of your class so that the type and number of member variables would be different than the current one: how many functions would be affected by this change? How many functions would you have to re-write (at least in part)?

Right, potentially infinite. You just can't count them all. On the other hand, if you have getters and setters, only those 4 functions will have access to the internal representation of your class. Changing the internal representation won't require any change to the code of your client functions; only those 4 member functions may have to be changed.

In general, encapsulation makes your life easier with respect to future changes. At a certain point in time you may want to log a message every time a certain property is set. You may want to fire an event every time a certain property is set. You may want to compute a certain value on the fly rather than reading it each time from a cache data member, or read it from a database, or whatever.

Having getters and setters allow you to implement any of those changes without requiring to change the client code.

Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
2

As far as general design philosophy is concerned, there is no "always" or "never" when it comes to implementing accessors versus not implementing accessors that the community as a whole agrees on.

Many will advise you to make all data members private and provide accessors & mutators. Always.

Others will tell you to make data members private if changing them from client code is undesirable, and leave them public otherwise.

Yet others will tell you that classes shouldn't have more than one or so data member at all, and all the data should be encapsulated in yet another object, preferably a struct.

You have to decide for yourself which is right, keeping in mind that this will depend not only on your approach, but also that of the organization for which you work.

If you ask me, my preference is to make everything public until I have a reason not to. Simple. But that's just me.

John Dibling
  • 99,718
  • 31
  • 186
  • 324
  • I think that's very reasonable. Especially for people learning, it's a good thing to know that I can go with public for now and if some time in the future I see the benefice of usage of private or another access modifier I can go and just use them. – Caio V. Jan 28 '22 at 17:36
1

You write explicit getters and setters as a sane plan for future development. If your class' users are directly accessing its members and you need to change the class in a way that is incompatible with that habit, you have to change every chunk of code that interfaces with you in this way. If you write a getter and setter, the compiler will optimize it to be time-equivalent to direct access (if that is all it does) and you can later change the logic if you need to - without having to change a ton of other code.

Sniggerfardimungus
  • 11,583
  • 10
  • 52
  • 97
1

When you make get or set method and use it 40 times in your code, you can handle future changes more easily. Imagine, that you use public variable and use it 40 times in your code. After a month of developing your program, you'll come up with a great idea: What if I divide this variable by 1000 and so I would have better values to calculate with! Wow, great, but now I have to find every single line, where I use it and change it. If I only had a get method :(

That's the main reason of getters and setters, even if they are very simple, it's better to have it. You will thank yourself once.

Michal Bukovy
  • 422
  • 3
  • 16
0

Data encapsulation is one of the major principles of OOP. It is the process of combining data and functions into a single unit called class. Using the method of encapsulation, the programmer cannot directly access the data. Data is only accessible through the functions existing inside the class so that the implementation details of a class that are hidden from the user. It's to protect both the caller and the function from accidentally changing the behavior of a method, or from needing to know how a method works.

justclaire
  • 177
  • 1
  • 2
  • 9
  • Hmm. could you post an example of how a method can be accidentally change the behavior when directly changing a variable? – Davlog Jun 06 '13 at 17:16
  • Bit too hard-lined for my tastes. One persons utopian OOP design guidelines is another person's pile of crap. – John Dibling Jun 06 '13 at 17:17
0

The textbook-ish answer recalled from me taking the first OOP class was: Get and set methods are used to wrap around private variables. Usually people compare between having get and set or just simply set those variables to be public; in this case, get and set approach is good because it protects those variables from being modified accidentally due to bugs and etc..

People (me when I took that class) might ask "isn't get and set also modify those variables, if so, how is that different than being modified as a public variable".

The rationale is: to have get and set function, you are asking the user or yourself to explicitly specify they want to modify the variable by calling those functions. Without calling those functions, the private variables will be less likely (still possible depends on implementation) modified unwillingly or accidentally.

grc
  • 716
  • 1
  • 5
  • 7
0

In short, you should not do that.

In general, I suggest to read Fowler's Refactoring, then you will have a picture what gets hindered by having naked data, and what kind of access aligns well. And importantly whether the whole thing applies to your cases or not.

And as you know pros&cons you can safely ignore "should do/don't" stuff like at start of this answer or others.

Balog Pal
  • 16,195
  • 2
  • 23
  • 37