C++ Why should I use get and set functions when working with classes [duplicate] - c++

This question already has answers here:
Why use getters and setters/accessors?
(37 answers)
Closed 9 years ago.
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?

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.

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.

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.

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.

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.

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.

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.

Related

How to Avoid Using Getters/Setters in C++?

I understand the reason why we should avoid using getters/setters, but I don't know how to avoid using them.
For example, I have three classes as follows,
A (private: point_B)
B (private: point_C)
C (private: val_C)
A has a private member point_B which is a pointer that points to B, and B also has a private member point_C which is a pointer that points to C. And C has a private int value val_C.
How can I access val_C in A?
Update:
In this case,
A is a class called state, which has the address point_B.
B is a class called node, which has a pointer call pointer_C.
C is a class called base_file, which has two derived classes called file and directory.
Update 2:
Ty guys for you help. Some of you are really trying to help instead of acting like someone who knows everything. I appreciate it.
Sry I can't post the whole assignment here since its too large even without documents. I'll post professor's answer here if you guys are interested tomorrow.
Update 3:
Please find reference here
The right thing to do is to leave the implementation to specify class.
Update 4:
The answer is to not to access private value in each class, but to implement functions to use them. That explains why making them private at the first place.
Maybe a little clarification is in order -- getters and setters aren't meant to be avoided at all costs; they have their place. The reason people say they should be avoided is because one goal of good object-oriented program design is encapsulation -- that is to say, each class should keep the details of its own implementation as private as possible, so that users of that class don't need to know (or care) about how the class was implemented. This becomes increasingly important as the program gets larger and more complicated, because a human programmer can only keep so many details in his/her head at once, and if the programmer has to remember everything about how class C works while simultaneously writing/debugging class A, that's an additional/unecessary cognitive burden that at some point will cause the programmer's brain to explode.
So, getting back to the main question -- how to avoid getters and setters -- the way to do it is to define your classes' interfaces at a higher level of abstraction than as simple repositories for state variables. (After all, if you wanted a simple collection of state variables, there's no reason to use a C++ class at all, you could simply declare a C-style struct instead)
For example, if your class C was intended to represent, say, a slot machine, a poor interface to class C might include lots of getters and setters, like this:
int getNumCoins() const {return numCoins;}
void setNumCoins(int newCoinCount) {numCounts = newCoinCount;}
void setDisplayedResult(const string & displayStr) {result = displayStr;}
int getDisplayedResult() const {return result;}
... and the poor programmer who was forced to use class C would have to write code like this:
playersWallet--; // take a coin out of the player's wallet
c.setNumCoins(c.getNumCoins()+1); // insert the coin into the machine
string newResult = "10 J A"; // somehow figure out what the machine should display
c.setDisplayedResult(newResult); // and make the machine display it
if (c.getDisplayedResult() == "7 7 7")
{
cout << "YOU ARE WINNER!" << endl;
int numCoinsWon = 5000; // jackpot!
c.setNumCoins(c.getNumCoins()-numCoinsWon); // deduct from machine's balance
playersWallet += numCoinsWon; // add to player's balance
}
[... and so on...]
Note that in the above code, the programmer had to think about all of the internal mechanisms of the slot machine, and write his own code to handle each step of its operation. With good encapsulation, on the other hand, the slot machine's public interface would be much simpler and more opaque, like this:
// returns the number of coins the player won on this round
int pullTheBigLever();
... and the programmer who was using this API might write code like this:
playersWallet += (c.pullTheBigLever() - 1); // -1 for the coin the player put in
Note that there is only one line of code, and that the programmer didn't have to think at all about how the internals of the slot machine worked. This avoids exploding-programmer-brain-syndrome, and just as importantly it means you (or someone else) can go back later and change the private implementation of how the slot machine works without breaking the code that interacts with the slot machine.
So when are getters and setters acceptable? Answer: when there really isn't any higher level of abstraction to be had. If you are writing a class that represents a light switch, then just being able to examine the switch's current position, or specify a new position for it, may be all the functionality you need. But in many (most?) cases you are implementing the functionality of something more complex than that, and the more of that complexity you can hide behind your public interface, the happier users of that class (including you) will be.
Short answers, in OOP, classes should have "properties" as part of their public API. Properties can have have things like getters, setters and change notifications, as appropriate. Wether a getter directly returns a private member variable, that is an implementation detail, and could change as needed. Distinguish the concept of property from the concept of member variable.
When thinking about it like this, the direct answer to your question is, that there's nothing you should try to "avoid", other than having unnecessary readable properties.
Note that often there is no explicit syntax or support for properties in an object oriented language (popular counter-example: C#), so it's easy to think they are same thing as a member variable with a setter and a getter. But the overlap is sort of a coincident, and not something you should care about when using a class. In a way, there is no getter for a member variable, there is only a getter for the property, even if it happens to map 1:1 with a member variable.
How avoid using getters/setters in C++.
To avoid setter/getter, all code that accesses a data attribute of class C, must be part of a class C method.
Alternate wording: bring the code that uses the data attribute inside the class.
update 2016/01/25
Would an example help? I find it trivial to avoid getters and setters (and public data and friends, etc.) I suppose I'm just used to it.
I recently completed yet another implementation of the game-of-life. The whole game is the entertainment value of watching the cells change patterns. Impressively complex behaviour from a small set of rules.
My class Cell_t has ONLY private data, No getters, no setters, and no friends. No other class has access to any cells data.
Here is a snippet of that part of my game illustrating how easy it is to live without getters, setters and friends creating the undesirable coupling and cohesion:
// somewhere in GameOfLife exists
std::vector<Cell_t> m_ptCellVec; // a vector of cell ptrs
GameOfLife::exec(...)
{
// ... preliminary stuff
do {
// ... some preliminary stuff
// NOTE 1
for ( auto it : m_ptCellVec ) it->countNeighbor();
// NOTE 2
for ( auto it : m_ptCellVec ) { it->updateDisplay();}
// .... more stuff
if(timeElapsed > timeLimit) break;
if(m_generation > genLimit) break;
}while(1);
}
NOTE 1 -- The class GameOfLife does not count neigbors ... each cell does its own counting. The next state is computed from these counts.
NOTE 2 -- The class GameOfLife does not update the display ... each cell updates it's own little piece of the screen.
THUS, there is no getter of Cell_t state, or next state, or living-neighbour count, or dead-neighbour count, etc.
With respect to this aspect of these two classes
The cohesion (of Cell_t) is functional, the most desirable.
The coupling (of GameOfLife_t to Cell_t) is 'none', also the most
desirable.
Changing the name or type of a Cell_t private data attribute has no
impact on any other code.
Oh, and a debug routine I often add (for another example):
std::string Cell_t dump() {
std::stringstream ss;
ss << // .... anything you want to 'dump' from this instance
return (ss.str());
}
I use the method name dump() to indicate an intent for a 'deeper' investigation of the activity of a specific Cell_t ... I have sometimes generated tabular data of state changes, with time stamps.
I often have a very similar method called show(), which typically provides a string for the user ...
These two examples, perhaps, illustrate the idea that a getter is simply bypassing an important aspect of the design process - naming what you are doing.
I believe the question stated in Problem could be modified. The question should not be "How can I avoid getters and setters?". This question is also related to other questions like "Should this method be a non-static member, static member, friend or helper?" or "Should this property be private or protected?". A better question to ask yourself is rather, "Who needs to access a particular property".
One way of writing classes which are easy to maintain is to limit the number of functions which have access to a specific property. This does not necessarily mean that no function should ever have access to a private property or that getters/setters should never be used. Take for example the class std::vector. Which can be simplified to something like this (with a lot of reservartions). The actual implementation of vector is normally much more sophisticated and may have different internal implementation but this simplified construction will be used to show a point.
template<class T, class Allocator<T> a = basic_allocator<T>>
class vector {
size_t sz;
size_t cap;
Allocator a;
T* elem;
// ... private methods
public:
// public methods and operators.
}
This class lets the developer access all elements in the internal array, where data is stored. This is done either via the operator [] (unchecked) or via the function at (checked). The developer have full rights to read or write to these elements. Without this access the vector class would be fairly useless and people would revert to use arrays instead. The class also provides getters to sz and cap via methods size() and capacity(). However sz and cap is otherwise seen as internal information and the developer is not allowed to change these directly. Instead the developer can use methods like push_back(), pop_back(), shrink_to_fit(), resize(), ... To add or remove data, manage allocated memory, etc ... The reason is that these operations requires some quite advanced memory handling and modifying these variables would cause leaks and/or crashes. Further, the developer does really not need to bother about these abstractions, since the developer only need the elements in the array.
So to conclude encapsulation is good and need to be considered. However this does not mean that the developer is never allowed to directly modify properties of some classes.

Why not set class members to public in the first place? [duplicate]

This question already has answers here:
Why use getters and setters/accessors?
(37 answers)
Closed 9 years ago.
I can't understand why people keep saying that when you make a class you should make a get() method to get the variable in a class, and a set() method to set a variable in a class.
If you have a get()/set() method... then why not just make the variable public in the first place?
It's not as if you would accidentally change it anyway since you still need to type myClassName.variable
Am I missing something?
Using get/set functions gives you flexibility to change your class implementation later without having to change all code which accesses the class.
For example, you might change the type of one of your internal variables, or you want to add restrictions on what values a variable can be set to. Perhaps you might want to only calculate a value on demand.
Also, you can make a get/set function non-inline, and put a breakpoint on it.
Making public variables is a very bad practice(in OO), because if you want to add any functionality or restrictions you will have to find all the code that accesses your class and replace that.
Getters and setters solve the issue of having to change all that code, when you want do add a restriction to a value of a variable, to do a validation or another functionality.
But don't overuse get/set functions, getters and setters also break OO principles, because they are still exposing implementation. If you really want your code to be reusable on different projects, use get/set functions only when there's no other possible implementation.
If you don't believe me, read this old but still relevant articles, and take your own conclusions.
http://www.idinews.com/quasiClass.pdf
http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox.html
http://typicalprogrammer.com/?p=23

Should I use public or private variables?

I am doing a large project for the first time. I have lots of classes and some of them have public variables, some have private variables with setter and getter methods and same have both types.
I decided to rewrite this code to use primarily only one type. But I don't know which I should use (variables which are used only for methods in the same object are always private and are not subject of this question).
I know the theory what public and private means, but what is used in the real world and why?
private data members are generally considered good because they provide encapsulation.
Providing getters and setters for them breaks that encapsulation, but it's still better than public data members because there's only once access point to that data.
You'll notice this during debugging. If it's private, you know you can only modify the variable inside the class. If it's public, you'll have to search the whole code-base for where it might be modified.
As much as possible, ban getters/setters and make properties private. This follows the principle of information hiding - you shouldn't care about what properties a class has. It should be self-contained. Of course, in practice this isn't feasible, and if it is, a design that follows this will be more cluttered and harder to maintain than one that doesn't.
This is of course a rule of thumb - for example, I'd just use a struct (equivalent with a class with public access) for, say, a simple point class:
struct Point2D
{
double x;
double y;
};
Since you say that you know the theory, and other answers have dug into the meaning of public/private, getters and setters, I'd like to focus myself on the why of using accessors instead of creating public attributes (member data in C++).
Imagine that you have a class Truck in a logistic project:
class Truck {
public:
double capacity;
// lots of more things...
};
Provided you are northamerican, you'll probably use gallons in order to represent the capacity of your trucks. Imagine that your project is finished, it works perfectly, though many direct uses of Truck::capacity are done. Actually, your project becomes a success, so some european firm asks you to adapt your project to them; unfortunately, the project should use the metric system now, so litres instead of gallons should be employed for capacity.
Now, this could be a mess. Of course, one possibility would be to prepare a codebase only for North America, and a codebase only for Europe. But this means that bug fixes should be applied in two different code sources, and that is decided to be unfeasible.
The solution is to create a configuration possibility in your project. The user should be able to set gallons or litres, instead of that being a fixed, hardwired choice of gallons.
With the approach seen above, this will mean a lot of work, you will have to track down all uses of Truck::capacity, and decide what to do with them. This will probably mean to modify files along the whole codebase. Let's suppose, as an alternative, that you decided a more theoretic approach.
class Truck {
public:
double getCapacity() const
{ return capacity; }
// lots of more things...
private:
double capacity;
};
A possible, alternative change involves no modification to the interface of the class:
class Truck {
public:
double getCapacity() const
{ if ( Configuration::Measure == Gallons ) {
return capacity;
} else {
return ( capacity * 3.78 );
}
}
// lots of more things...
private:
double capacity;
};
(Please take int account that there are lots of ways for doing this, that one is only one possibility, and this is only an example)
You'll have to create the global utility class configuration (but you had to do it anyway), and add an include in truck.h for configuration.h, but these are all local changes, the remaining of your codebase stays unchanged, thus avoiding potential bugs.
Finally, you also state that you are working now in a big project, which I think it is the kind of field in which these reasons actually make more sense. Remember that the objective to keep in mind while working in large projects is to create maintainable code, i.e., code that you can correct and extend with new functionalities. You can forget about getters and setters in personal, small projects, though I'd try to make myself used to them.
Hope this helps.
There is no hard rule as to what should be private/public or protected.
It depends on the role of your class and what it offers.
All the methods and members that constitute the internal workings of
the class should be made private.
Everything that a class offers to the outside world should be public.
Members and methods that may have to be extended in a specialization of this class,
could be declared as protected.
From an OOP point of view getters/setters help with encapsulation and should therefore always be used. When you call a getter/setter the class can do whatever it wants behind the scenes and the internals of the class are not exposed to the outside.
On the other hand, from a C++ point of view, it can also be a disadvantage if the class does lots of unexpected things when you just want to get/set a value. People like to know if some access results in huge overhead or is simple and efficient. When you access a public variable you know exactly what you get, when you use a getter/setter you have no idea.
Especially if you only do a small project, spending your time writing getters/setters and adjusting them all accordingly when you decide to change your variable name/type/... produces lots of busywork for little gain. You'd better spend that time writing code that does something useful.
C++ code commonly doesn't use getters/setters when they don't provide real gain. If you design a 1,000,000-line project with lots of modules that have to be as independent as possible it might make sense, but for most normal-sized code you write day to day they are overkill.
There are some data types whose sole purpose is to hold well-specified data. These can typically be written as structs with public data members. Aside from that, a class should define an abstraction. Public variables or trivial setters and getters suggest that the design hasn't been thought through sufficiently, resulting in an agglomeration of weak abstractions that don't abstract much of anything. Instead of thinking about data, think about behavior: this class should do X, Y, and Z. From there, decide what internal data is needed to support the desired behavior. That's not easy at first, but keep reminding yourself that it's behavior that matters, not data.
Private member variables are preferred over public member variables, mainly for the reasons stated above (encapsulation, well-specified data, etc..). They also provide some data protection as well, since it guarantees that no outside entity can alter the member variable without going through the proper channel of a setter if need be.
Another benefit of getters and setters is that if you are using an IDE (like Eclipse or Netbeans), you can use the IDE's functionality to search for every place in the codebase where the function is called. They provide visibility as to where a piece of data in that particular class is being used or modified. Also, you can easily make the access to the member variables thread safe by having an internal mutex. The getter/setter functions would grab this mutex before accessing or modifying the variable.
I'm a proponent of abstraction to the point where it is still useful. Abstraction for the sake of abstraction usually results in a cluttered mess that is more complicated than its worth.
I've worked with complex rpgies and many games and i started to follow this rule of thumb.
Everything is public until a modification from outside can break something inside, then it should be encapsulated.(corner count in a triangle class for example)
I know info hiding principles etc but really don't follow that.
Public variables are usually discouraged, and the better form is to make all variables private and access them with getters and setters:
private int var;
public int getVar() {
return var;
}
public void setVar(int _var) {
var = _var;
}
Modern IDEs like Eclipse and others help you doing this by providing features like "Implement Getters and Setters" and "Encapsulate Field" (which replaces all direct acccesses of variables with the corresponding getter and setter calls).

Private set / get functions -- Why private and how to use?

I've read a lot of guides that explain why I should use "private" and the answer is always "Because we don't want anyone else setting this as something". So, let me ask the following questions:
Assuming that I want to have a variable that is set-once (perhaps something like a character name in a video game, ask once, then it's set, and then you just use the get variable(edit:function) for the rest of the game) how do I handle that one set? How would I handle the get for this as well?
What is the actual advantage of using a private access modifier in this case? If I never prompt the user to enter the name again, and never store information back to class.name shouldn't the data remain safe (moderately, assuming code works as intended) anyways?
I hope someone will help me out with this as the explanations I've googled and seen on here have not quite put my thoughts to rest.
Thanks!
The access specifiers mainly serve to denote the class interface, not to effectively limit the programmer's access or protect things. They serve to prevent accidental hacking.
If something is set once, then you should try to set it when it is created, and make it const.
If the interface doesn't need to be especially clear (for example, if few people need to learn it) then it doesn't make sense to spend effort engineering it. Moreover changes that don't make much difference in how the interface is used can be applied later. The exposed variable can be changed to a getter/setter using simple search-and-replace.
If it were a published binary interface, then you would want to get it right the first time. But you're just talking about the internals of your program.
And it's fairly unlikely that anyone will reset the player name by accident.
I won't try to justify the private set method as that sounds a bit weird to me. You could handle the one set by using a friend declaration. But then why would you define a setter when the friend could just set the value directly?
I generally avoid setters if I can at all manage it. Instead I prefer provide facility to set member variables via the constructor. I am quite happy to provide getters if they make sense.
class player_character_t {
std::string name_;
public:
player_character_t(std::string const& name)
: name_ (name)
{
}
std::string const& name() const { return name_; }
};
This forces you to delay construction of the object until you have all the information you require. It simplifies the logic of your objects (ie they have a trivial state diagram) and means you never have to check is something is set before reading it (if the object exists, it is set properly).
http://en.wikipedia.org/wiki/State_diagram
Marking things as private helps prevent accidents. So when you make a mistake and it is no longer the case that the "code works as intended" the compiler may help you detect it. Likewise const can be a big help in detecting when you are using objects incorrectly.
It's that last parenthetical that is important: assuming code works as intended.
In my mind it's similar to permissions in Linux systems. You know the root password and you can delete any file, but you don't stay logged in as root so you don't do anything by accident. Similarly, when you have a private variable characterNameString, and someone (or you) later tries to give it a new value, it will fail. That person will have to go look at the code and see that it's marked private. That person will have to ask themselves "why is this private? Should I be modifying it? Should I be doing this another way?" If they decide they want to, then, they can. But it prevents silly mistakes.
Don't confuse the private and the public interfaces of the class. In theory these are completely different interfaces, and this is just a design feature of C++ that they're located physically in the same class declaration.
It's perfectly ok to have a public getter/setter when the object property should be exposed via the public interface, so there is no rule such as 'setter is always private'.
More on that topic in the (More) Exceptional C++ books by Herb Sutter. It's an absolutely neccessary reading for someone who wants to understand C++ and be proficient with it.
If you have doubts over deciding whether to use getter/setters over the class variables, there are numerous explanations on the internet why getters/setters are better.
If the variable is 'write once then forever read only' I'd recommend making it a const member that is initialized during construction. There's no value in a private 'setter' function because it won't be used. Also you avoid people using the setter function to set the name when it's never meant to be set.
For example:
class Player
{
private:
const std::string m_name;
public:
Player(const std::string& name) : m_name(name) {}
};
Private getters and setters all make sense when the data in question involves several variables, have additional constraints you want to make sure you adhere to, and these operations are done several times in your class. Or when you plan further modifications to the data model and wish to abstract operations on the data, like using std::vector but planning to make it std::map or similar cases.
For a personal example, I have a smart pointer implementation with a private reset(T*, int*) method that is essentially a setter for the stored object and its reference count. It handles checking validity of objects and reference counts, incrementing and decrementing reference counts, and deleting objects and reference counts. It is called eight times in the class, so it made perfect sense to put it into a method instead of just screwing around with member variables each time, slowing programming, bloating code and risking errors in the process.
I am sure private getters can also make sense if you are abstracting the data from the model and/or you have to implement error checking, for example throwing instructions if the data is NULL instead of returning NULL.

Access members directly or always use getters

I personally find it weird/ugly when a class uses a getter to access its own member data. I know the performance impact is none but I just don't like to see all those method calls.
Are there any strong arguments either way, or is it just one of those things that's personal preference and should be left to each coder, or arbitrarily controlled in a coding standard?
Update: I'm meaning simple getters, specifically for a class' non-public members.
The reason you might want to use a getter/setter is because it conceals the implementation. You won't have to rewrite all of your code if you are using getters/setters in case the implementation does change, because those members can continue to work.
EDIT based on the many clever comments:
As for a class using setters and getters on itself, that may depend on the particulars. After all, the implementation of a particular class is available to the class itself. In the cases where a class is normally instantiated, the class should use the member values directly for its own members (private or otherwise) and its parent classes (if they are protected) and only use getters/setters in the case that those members are private to the parent class.
In the case of an abstract type, which will usually not contain any implementation at all, it should provide pure virtual getters and setters and use only those in the methods it does implement.
Willingness to use getters/setters within class member implementation is the canary in the mine telling that your class is growing unreasonably. It tells that your class is trying to do too many different things, that it serves several purposes where it should serve one instead.
In fact, this is usually encountered when you are using one part of your class to store or access your data, and another part to make operations on it. Maybe you should consider using a standalone class to store and give access to your data, and another one to provide a higher view, with more complex operations with your data.
THE OBVIOUS
getters and setters for protected members makes as much sense as for public... derived classes are just another form of client code, and encapsulating implementation details from them can still be useful. I'm not saying always do it, just to weight pros and cons along the normal lines.
getters and setters for private members is rarely a net benefit, though:
it does provide the same kind of encapsulation benefits
single place for breakpoints/logging of get/set + invariant checks during dev (if used consistently)
virtual potential
etc...
but only to the presumably relatively small implementation of the same struct/class. In enterprise environments, and for public/protected member data, those benefits can be substantial enough to justify get/set methods: a logging function may end up having millions of lines of code depedent on it, and hundreds or thousands of libraries and apps for which a change to a header may trigger recompilation. Generally a single class implementation shouldn't be more than a few hundred (or at worst thousand) lines - not big or complex enough to justify encapsulating internal private data like this... it could be said to constitute a "code smell".
THE NOT-SO OBVIOUS
get/set methods can very occasionally be more readable than direct variable access (though more often less readable)
get/set methods may be able to provide a more uniform and convenient interface for code-generated member or friend methods (whether from macros or external tools/scripts)
less work required to transition between being a member or friend to a freestanding helper function should that become possible
implementation may be rendered more understandable (and hence maintainable) to people who're normally only users of the class (as more operations are expressed via, or in the style of, the public interface)
It's a bit out of scope for the question, but it's worth noting that classes should generally provide action-oriented commands, event-triggered callbacks etc. rather than encouraging a get/set usage pattern.
It seems most people didn't read your question properly, the question is concerning whether or not class methods accessing its own class' members should use getters and setters; not about an external entity accessing the class' members.
I wouldn't bother using getter and setter for accessing a class' own members.
However, I also keep my classes small (typically about 200-500 lines), such that if I do need to change the fields or change its implementations or how they are calculated, search and replace wouldn't be too much work (indeed, I often change variable/class/function names in the early development period, I'm picky name chooser).
I only use getter and setters for accessing my own class members when I am expecting to change the implementation in the near future (e.g. if I'm writing a suboptimal code that can be written quickly, but plans to optimize it in the future) that might involve radically changing the data structure used. Conversely, I don't use getter and setter before I already have the plan; in particular, I don't use getter and setter in expectation of changing things I'm very likely never going to change anyway.
For external interface though, I strictly adhere to the public interface; all variables are private, and I avoid friend except for operator overloads; I use protected members conservatively and they are considered a public interface. However, even for public interface, I usually still avoid having direct getters and setters methods, as they are often indicative of bad OO design (every OO programmers in any language should read: Why getter and setter methods are Evil). Instead, I have methods that does something useful, instead of just fetching the values. For example:
class Rectangle {
private:
int x, y, width, height;
public:
// avoid getX, setX, getY, setY, getWidth, setWidth, getHeight, setHeight
void move(int new_x, int new_y);
void resize(int new_width, int new_height);
int area();
}
The only advantage is that it allows changing internal representation without changing external interface, permitting lazy evaluation, or why not access counting.
In my experience, the number of times I did this is very, very low. And it seems you do, I also prefer to avoid the uglyness and weightyness of getter/setters. It is not that difficult to change it afterwards if I really need it.
As you speak about a class using its own getter/setters in its own implementation functions, then you should consider writing non-friend non-member functions where possible. They improve encapsulation as explained here.
An argument in favor of using getters is that you might decide one day to change how the member field is calculated. You may decide that you need it to be qualified with some other member, for instance. If you used a getter, all you have to do is change that one getter function. If you didn't you have to change each and every place where that field is used currently and in the future.
Just a crude example. Does this help?
struct myclass{
int buf[10];
int getAt(int i){
if(i >= 0 && i < sizeof(buf)){
return buf[i];
}
}
void g(){
int index = 0;
// some logic
// Is it worth repeating the check here (what getAt does) to ensure
// index is within limits
int val = buf[index];
}
};
int main(){}
EDIT:
I would say that it depends. In case the getters do some kind of validation, it is better to go through the validation even if it means the class members being subjected to that validation. Another case where going through a common entry point could be helpful is when the access needs to be essentially in a sequential and synchronized manner e.g. in a multithreaded scenario.
Protecting a member variable by wrapping its access with get/set functions has its advantages. One day you may wish to make your class thread-safe - and in that instance, you'll thank yourself for using those get/set functions
this is actually for supporting the object oriented-ness of the class by abstracting the way to get(getter). and just providing its easier access.
Simple answer. If you are writing a one shoot program, that will never change, you can leave the getters at peace and do without any.
However if you write a program that could change or been written over time, or others might use that code, use getters.
If you use getters it helps change the code faster later on, like putting a guard on the property to verify correctness of value, or counting access to the property(debugging).
Getters to me are about easy possibilities(free lunch). The programmer who write the code does not need getters, he wants them.
hope that help.
My thoughts are as follows.
Everything should be static, constant, and private if possible.
As you need a variable to be instanced meaning more than one unique
copy you remove static.
As you need a variable to be modifiable you remove the const.
As you need a class/variable to be accessed by other classes you remove
the private.
The Usage of Setters/Getters - General Purpose.
Getter's are okay if the value is to ONLY be changed by the class and
we want to protect it. This way we can retrieve the current state of
this value without the chance of it's value getting changed.
Getter's should not be used if you are planning to provide a Setter
with it. At this point you should simply convert the value to public
and just modify it directly. Since this is the intent with a Get/Set.
A Setter is plain useless if you are planning to do more then simply
"this.value = value". Then you shouldn't be calling it "SetValue"
rather describe what it is actually doing.
If let's say you want to make modifications to a value before you
"GET" it's value. Then DO NOT call it "GetValue". This is ambiguous
to your intent and although YOU might know what's happening. Someone
else wouldn't unless they viewed the source code of that function.
If let's say you are indeed only Getting/Setting a value, but you are
doing some form of security. I.e. Size check, Null Check, etc.. this
is an alternative scenario. However you should still clarify that in
the name E.g. "SafeSetValue" , "SafeGetValue" or like in the "printf"
there is "printf_s".
Alternatives to the Get/Set situations
An example that I personally have. Which you can see how I handle a
Get/Set scenario. Is I have a GameTime class which stores all kinds
of values and every game tick these values get changed.
https://github.com/JeremyDX/DX_B/blob/master/DX_B/GameTime.cpp
As you will see in the above my "GETS" are not actually "GETS" of
values except in small cases where modification wasn't needed. Rather
they are descriptions of values I am trying to retrieve out of this
GameTime class. Every value is "Static Private". I cannot do Const
given the information is obtained until runtime and I keep this
static as there is no purpose to have multiple instances of Timing.
As you will also see I don't have any way of performing a "SET" on any of this data, but there are two functions "Begin()" and "Tick()" which both change the values. This is how ALL "setters" should be handled. Basically the "Begin()" function resets all the data and loads in our constants which we CANT set as constants since this is data we retrieve at runtime. Then TICK() updates specific values as time passes in this case so we have fresh up to date information.
If you look far into the code you'll find the values "ResetWindowFrameTime()" and "ElapsedFrameTicks()". Typically I wouldn't do something like this and would have just set the value to public. Since as you'll see I'm retrieving the value and setting the value. This is another form of Set/Get, but it still uses naming that fits the scenario and it uses data from private variables so it didn't make sense to pull another private variable and then multiply it by this rather do the work here and pull the result. There is also NO need to edit the value other then to reset it to the current frame index and then retrieve the elapsed frames. It is used when I open a new window onto my screen so I can know how long I've been viewing this window for and proceed accordingly.