Set / get methods in C ++

Java programmers and APIs seem to prefer explicit set / get methods.

however, I got the impression that the C ++ community is frowning with this practice. If so, is there a specific reason (among other lines of code) why this is?

on the other hand, why does the Java community prefer to use methods rather than direct access?

thank

+11
java c ++ conventions
Sep 03 2018-10-09T00:
source share
13 answers

A well-designed class should ideally not have too many sets and sets. In my opinion, too many sets and sets basically indicate that someone else (and possibly many of them) needs my data to achieve their goal. In that case, why do I have this data in the first place? This violates the basic principle of encapsulation (data operations + in one logical unit).

So, while there are no technical limitations and (in essence, abundance) methods to “install” and “get”, I would say that you should pause and revise your design if you want too many such “get” and “set” in your class interface used by too many other objects on your system.

+14
Sep 03 '10 at 2:28
source share

There are times when getters / setters are suitable, but an abundance of getters / setters usually indicates that your project does not reach any higher level of abstraction.

As a rule, it is better (in terms of encapsulation) to demonstrate higher-level operations for your objects that do not make the implementation obvious to the user.

Some other possible reasons why this is not so common in C ++, as in Java:

  • The standard library does not use it.
  • Bjarne Stroustrup expresses his dislike for him (last paragraph):

    I especially don't like classes with many get and set functions. That is, it often indicates that he should not have been a class in the first place. It is just a data structure. And if it really is a data structure, make it a data structure.

+10
Sep 03 '10 at 8:01
source share

The usual argument to the get / set method is that if you have both and they are just trivial return x; and x = y; , then you did not encapsulate anything; you can also just make a public member that will save many templates.

Obviously, there are times when they still make sense; if you need to do something special in them, or you need to use inheritance or, in particular, interfaces.

The advantage is that if you implement getters / setters, you can change their implementation later without changing the code that uses them. I suppose that frowning to which you are referring is a kind of YAGNI , that if there is no expectation to ever change functions in this way, then there is little benefit from having them. In many cases, you can just deal with a case of changing the implementation later.

I did not know that the C ++ community frowned more or less than the Java community; I find that they are less common in languages ​​like Python, for example.

+6
03 Sep '10 at 1:59
source share

I think the reason the C ++ community frowns on getters and setters is because C ++ offers much better alternatives. For example:

 template <class T> class DefaultPredicate { public: static bool CheckSetter (T value) { return true; } static void CheckGetter (T value) { } }; template <class T, class Predicate = DefaultPredicate <T>> class Property { public: operator T () { Predicate::CheckGetter (m_storage); return m_storage; } Property <T, Predicate> &operator = (T rhs) { if (Predicate::CheckSetter (rhs)) { m_storage = rhs; } return *this; } private: T m_storage; }; 

which can then be used as follows:

 class Test { public: Property <int> TestData; Property <int> MoreTestData; }; int main () { Test test; test.TestData = 42; test.MoreTestData = 24; int value = test.TestData; bool check = test.TestData == test.MoreTestData; } 

Note that I added the predicate parameter to the property class. At the same time, we can get a creative, for example, property for storing the integer value of the color channel:

 class NoErrorHandler { public: static void SignalError (const char *const error) { } }; class LogError { public: static void SignalError (const char *const error) { std::cout << error << std::endl; } }; class Exception { public: Exception (const char *const message) : m_message (message) { } operator const char *const () { return m_message; } private: const char *const m_message; }; class ThrowError { public: static void SignalError (const char *const error) { throw new Exception (error); } }; template <class ErrorHandler = NoErrorHandler> class RGBValuePredicate : public DefaultPredicate <int> { public: static bool CheckSetter (int rhs) { bool setter_ok = true; if (rhs < 0 || rhs > 255) { ErrorHandler::SignalError ("RGB value out of range."); setter_ok = false; } return setter_ok; } }; 

and it can be used as follows:

 class Test { public: Property <int, RGBValuePredicate <> > RGBValue1; Property <int, RGBValuePredicate <LogError> > RGBValue2; Property <int, RGBValuePredicate <ThrowError> > RGBValue3; }; int main () { Test test; try { test.RGBValue1 = 4; test.RGBValue2 = 5; test.RGBValue3 = 6; test.RGBValue1 = 400; test.RGBValue2 = 500; test.RGBValue3 = -6; } catch (Exception *error) { std::cout << "Exception: " << *error << std::endl; } } 

Note that I also handled the wrong values ​​with the template parameter.

Using this as a starting point, it can be expanded in many ways.

For example, suppose the property store is different from the public value type - therefore, the RGBValue above can use unsigned char for storage, but the interface is int.

Another example is to modify a predicate so that it can change the value of setter. In the RGBValue above, this can be used to fix values ​​in the range 0 to 255, and not to generate errors.

+6
03 Sep '10 at 9:39
source share

It is not unusual for C ++ to have explicit set / get methods. I saw this in a lot of C ++, it can be very useful not to allow direct access to data elements.

+2
Sep 03 2018-10-10T00:
source share

Properties as a concept of a common language technically precede C ++, for example. in Smalltalk, but they were never part of the standard. Getters and setters were a concept used in C ++ when it was used to develop a user interface, but, in truth, this is an expensive proposition for developing a user interface in what is actually a system language. A common problem with C ++ getters and setters was that since they were not a standard, everyone had a different standard.

And in system languages, where performance problems are high, then it just becomes easier to publish this variable, although there is a lot of literature that frowns a lot in this practice. Often you just see a richer exchange of information between instances of C ++ objects than simple elements.

You will probably get many points of view in answer to this question, but in general C ++ should have been C that made objects, making OOP available to developers who did not know the objects. It was hard to get virtual and templates in the language, and I think this is some time of stagnation.

Java is different in that in the beginning, with what Java brought to areas such as garbage collection, it was easier to promote a philosophy of robust encapsulation, i.e. external entities must keep their dirty paws away from the internal elements of the class.

I admit that this is largely an opinion - at this time I use C ++ for highly optimized materials, such as 3D graphics pipelines - I already need to manage my entire memory of objects, so I would dimly consider the fundamentally useless code that just serves in order to wrap access to the storage in additional functions, he said that basic runtime performance features like MSFT.net ILM make this a position that can be difficult to protect from time to time

Purely my 2c

+2
Sep 03 '10 at 1:59
source share

I don't think the C ++ community frowned on using getters and setters. They are almost always a good idea.

+1
Sep 03 2018-10-10T00:
source share

Check this box to explain why Java prefers them, and the reasons for C ++ are the same. In short: it allows you to change the way you access data items without having to recompile the client code (the code that uses your code). It also allows you to apply a specific policy to access data and what to do when that data is accessed.

+1
Sep 03 '10 at 1:52
source share

Using set / get methods, you can implement useful side effects in getter / setter (for example, when get / set is an object).

+1
Sep 03 '10 at 1:55
source share

I am surprised that no one mentioned Java introspection and beans.

Using get ... / set ... naming conventions combined with introspection allows for all sorts of clever tricks with useful classes.

I personally believe that the keyword "public" should be enough to trigger bean magic, but I'm not Ray Gosling.

I believe that in C ++ this is a pretty pointless exercise. You add at least six lines of code for testing and support that have no purpose and will be largely ignored by the compiler. It really does not protect your class from abuse and abuse unless you add a lot more coding.

+1
Sep 03 '10 at 8:12
source share

It relates to the basics of object-oriented programming - hiding the internal objects of an object from its users. Users of the object do not need to know (and not care) about the internal objects of the object.

It also gives you control over what is done whenever a user of your object tries to read / write it. Essentially, you open the interface to users of objects. They should use this interface, and you control what happens when the methods in this interface are called - getters and setters will be part of the interface.

It just makes debugging easier. A typical scenario is when your object lands in a strange state, and you debug it to find out how it got there. All you do is set breakpoints in your getters and setters and assume that everything else is in order, you can see how your object gets into a strange state. If your users of objects directly contact their members, figuring out when changes to the state of the object become much more difficult (although not impossible).

0
03 Sep '10 at 2:09
source share

I would say that C ++ requires getters / seters more than Java.

In Java, if you start with open access to the window, and later you change your mind, instead you want to use getter / setter, it is very easy to find all the ways to use the field and reorganize them into getter / setter.

in C ++, it is not so simple. The language is too complex, IDEs simply cannot reliably do this.

so in C ++ you better understand this the first time. In Java, you can be more adventurous.

0
Sep 03 '10 at 2:58
source share

Before java were added / installed. There are many reasons to use them, especially if you need to recount sth. wenn is changing the value. So the first big advantage is that you can watch for changes. But imho its bad to ALWAYS implement get and set - often getting enough. Another thing is that class changes will directly affect your customers. You cannot change the names of participants without forcing the refactoring of the client code to public members. Suppose you have an object with a length, and you change that member name ... mm. With a getter, you simply change your side of the code, and the client can sleep well. Adding get / Sets for members that should be hidden is, of course, nonsense.

0
Sep 03 '10 at 7:32
source share



All Articles