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

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.

Related

What is the role of private members?

#include<iostream>
class student
{
private:
int roll_no;
int standard;
public:
void input();
void display();
};
I asked my teacher about the significance of making some class members private and some members public. He said that data members are usually made private for security reason. He said that no object can access private things of a class, thats why they are secure.
My question is:
When we will develop software, we will be distributing executable files to users. Users will not be able to edit the code. What type of security our teacher is talking about? When I have created the entire code, how someone can edit it? What is the need to think about security?
No your teacher would not be correct that encapsulation, as this is called, is for security. Encapsulation is actually there for a few other reasons:
Creates better maintainability of code. When all the properties are private and encapsulated, it is easy for the writers of the code to maintain the program simply by changing the methods.
Have a Controlled Environment. Encapsulation lets the users use the given objects, in a controlled manner, through objects. If encapsulation didn't exist, client code could use the members of your class in any way they wanted, while member functions limit this to a specific behavior.
Hide Complexities: Hiding the complexities irrelevant to the users. Sometimes, some properties and methods are only for internal use and the user doesn't have to know about these. This makes it simple for the user to use the object.
An example that illustrates what would happen if you didn't have encapsulation:
Suppose you had a class called Human, with a member called age that is public. Now, if someone wanted to modify this, say, based off input, then they would have to check to see if the input is not negative or not a huge amount every time, unless they make a function for it. Now if there was a member function instead that provided access to age, then it wouldn't be client code's problem anymore, since the setter for the field would take care of it as it would be the responsibility of the class to make sure its fields are valid.
This will not affect users of an application, but the teacher is trying to make you safe from your own mistakes.
Keeping member variables private, when possible, protects you from accessing and changing them accidentally from places in your code where you shouldn't do that.
It also makes is clear for the users of the code which variables and functions are intended to be used from outside the class and which are not, thus clearly defining the API of the class.
Just like each person knows their own secrets and it is somehow dangerous to tell others, private members are not exposed to other classes because it may break something in the class and other classes don't really need to know them.
However, people need to communicate to fulfill their needs. We talk, explain our thoughts to be understood.. well, public members are like this, they are needed for the class itself communicate with other classes.

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

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.

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).

Examples of why declaring data in a class as private is important?

I understand that only the class can access the data so therefore it is "safer" and what not but I don't really understand why it is such a big deal. Maybe it is because I haven't made any programs complex enough where data could accidentally be changed but it just a bit confusing when learning classes and being told that making things private is important because it is "safer" when the only time I have changed data in a program is when I have explicitly meant to. Could anyone provide some examples where data would have been unintentionally changed had that data not been private?
Depends what you mean by "unintentional changes". All code is written by someone so if he is changing a member variable of a class then the change is intentional (at least from his side). However the implementor of the class might not have expected this and it can break the functionality.
Imagine a very simple stack:
class Stack
{
public:
int Items[10];
int CurrentItemIndex;
}
Now CurrentItemIndex points to the index which represents the current item on top of the stack. If someone goes ahead and changes it then your stack is corrupted. Similarly someone can just write stuff into Items. If something is public then it is usually a sign that it is intended for public usage.
Also making members private provides encapsulation of the implementation details. Imagine someone iterates over stack on the above implementation by examining Items. Then it will break all code if the implementation of the stack gets changed to be a linked list to allow arbitrary number of items. In the end the maintenance will kill you.
The public interface of a class should always be as stable as possible because that's what people will be using. You do not want to touch x lines of code using a class just because you changed some little detail.
The moment you start collaborating with other people on code, you'll appreciate the clarity and security of keeping your privates private.
Say you've designed a class that rotates an image. The constructor takes an image object, and there's a "rotate" method that will rotate the image the requested number of degrees and return it.
During rotation, you keep member variables with the state of the image, say for example a map of the pixels in the image itself.
Your colleagues begin to use the class, and you're responsible for keeping it working. After a few months, someone points out to you a technique that performs the manipulations more efficiently without keeping a map of the pixels.
Did you minimize your exposed interface by keeping your privates private?
If you did, you can swap out the internal implementation to use on the other technique, and the people who've been depending on your code won't need to make any changes.
If you didn't, you have no idea what bits of your internal state your colleagues are depending on, and you can't safely make any changes without contacting all of your colleagues and potentially asking them to change their code, or changing their code for them.
Is this a problem when you're working alone? Maybe not. But it is a problem when you've got an employer, or when you want to open-source that cool new library you're so proud of.
When you make a library that other people use, you want to show the most basic sub-set of your code possible to allow external code to interface with it. This is called information hiding. It would cause more issues if other developers were allowed to modify any field they wanted, perhaps in an attempt of performing some task. An attempt that would cause unspecified program behaviour.
Generally you want to hide "data" (make vars private) so when people that aren't familiar with the class don't access data directly. Instead if they use Public modifiers to access and change that data.
Eg. accessing name via public setter could check for any problems and also make first character upper case
Accessing data directly will not do those checks and possible changes.
You don't want someone to suddenly fiddle with your internals, no? So do C++'s classes.
The problem is, if anyone can suddenly change the state of a variable that is yours, your class will screw up. It's as if someone suddenly fills your gut with something you don't want. Or exchanges your lung for someone elses.
Let's say you have a BankAccount class where you store a person's NIP and cash amount. Let's put all the fields public and see what could go wrong:
class BankAccount
{
public:
std::string NIP;
int cash;
};
Now, let's pretend that you leave it this way and use it throughout your program. Later on, you find a nasty bug caused by a negative amount of cash (whether it is from calculations or simply an accident). So you spend a couple of hours finding where that negative amount came from and fix it.
You don't want this to happen again, so you decide to put the cash amount private and perform checks before setting the cash amount to avoid any other bugs like the previous one. So you go like this:
class BankAccount
{
public:
int getCash() const { return cash; }
void setCash(int amount)
{
if (amount >= 0)
cash = amount;
else
throw std::runtime_exception("Cash amount is negative.");
}
private:
int cash;
}
Now what? You have to find all the cash references and replace them. A quick and dirty Find and Replace won't fix it so easily: you must change accessors to getCash() and setters to setCash. All this time fixing something not so important that could have been avoided by hiding the implementation details within your class and only giving access to the general interface.
Sure, that's indeed a pretty dumb example, but it happened to me so many times with more complex cases(sometimes the bug is much harder to find) that I've really learned to encapsulate as much as I can. Do your future-self and the viewers of your code a favor and hide private members, you never know when your "implementation details" will change.
When you are on a project where 2 or more people are working on the same project, but you work lets, say, 2 people work on Mondays, 2 on Tuesdays, 2 on Wednesdays, etc. The next people that will continue the project won't have to go bother the other coders just to explain what/when/why it has been that way. If you know TORTOISE you will see it's very helpful.

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.