tags:

views:

327

answers:

5

I have a class with a lot of built-in type members with read/write access. Should I make them public members and provide get/set methods for each one? How about structures?

+3  A: 

Firstly, if your class has a lot of data mamebers it is probably not well designed. You may need to consider splitting it into multiple classes or storing the data in structures such as maps.

As regards providing accessors, the question is will you ever want to modify the access, possibly preventing it. If the answer is yes, then you need access functions. On the other hand, if your class is really just a bag of bits, with no behaviour, then make it a structure.

anon
A: 

Using get/set methods for private/protected data members is a bad design.

It causes client code to be dependent on the implementation details of your class.

Changes in your class causes changes in client code.

However get/set methods for public members can be used. But it is always good to avoid them.

Alien01
Why -3 downvoting?
Alien01
I upvoed it, so it is was at least 4 downvotes :) Seriously, I thought it was a common knowledge that getters/setters are a bad design. Scary.
Nemanja Trifunovic
OKay the question was if getter/setters can be used ? Its a bad design most of times and that what I answered. From most of answers above its the same conclusion.I am not sure its a common knowledge for all .
Alien01
+13  A: 

The whole reason to have accessors (getters) and modifiers (setters) is to provide yourself with an extra level of indirection.

This extra level of indirection allows you to provide a read only view of your variable to a public interface, while not allowing your data member to be changed. You could still use a private or protected setter.

Setters allow you to do special error checking, validation and corrections when a value is set. For example setDirectory(const std::string &strPath), you could make sure there is a terminating slash if the user didn't specify one. This ensures that your class state will always be valid.

Getters can also shield your members from having them exposed to allow pointers to them. By not allowing pointers to them from the outside, you can ensure that if your object goes out of scope it won't lead to a crash.

The extra level of indirection for getters/setters also allow you to be able to change the data member that they encapsulate.

With a getter you can also obtain different views of your data, example: getMinutes, when your data member is actually stored in seconds.

This is not the reason to use them, but a nice side effect of using getters and setters is that you can set a breakpoint inside your modifier for example to see exactly when it is changed.

Whether you should use them or not is a judgement call based on your need. If you have so many members that it is a huge pain to provide getters and settings you could consider storing the data members in a struct and using that struct inside your class instead. You could even provide getters/setters for an object for the whole struct at once.

Brian R. Bondy
+1  A: 

You should use public data members only

  • in structures, that you don't expose to client code (eg. bind-style functors) - it's useless to protect structures that noone outside will ever get
  • if their types encapsulate the logic of set/getting them (eg. if you create a class ObservableAttribute)
  • if they are const-members in an immutable structure (you can't do much except to read them if they're immutable)

If you create a public data member, you have to be sure that its value is fully orthogonal with other members of the class. Eg., you disable future possibilities of

  • observing changes to the member
  • making the member play any part in the class' invariant
  • disabling access to the member
  • changing the implementation of the member (eg. computed vs. cached vs. stored) if performance needs it
jpalecek
+5  A: 

If there are invariants you need to preserve, then yes. Otherwise, don't bother.

Nemanja Trifunovic
To the downvoters: I took the advice from Stroustrup himself: http://www.artima.com/intv/goldilocks3.html "Bjarne Stroustrup: My rule of thumb is that you should have a real class with an interface and a hidden representation if and only if you can consider an invariant for the class."
Nemanja Trifunovic
It definitelly does. Later in the same text: "Yes. If every data can have any value, then it doesn't make much sense to have a class. Take a single data structure that has a name and an address. Any string is a good name, and any string is a good address. If that's what it is, it's a structure.
Nemanja Trifunovic
Continued: "Don't have anything private. Don't do anything silly like having a hidden name and address field with get_name and set_address and get_name and set_name functions. Or even worse, make a virtual base class with virtual get_name and set_name functions and so on."
Nemanja Trifunovic
I think the downvoters (I was not one) may be considering that there are other issues besides invariance such as virtual behaviour, convenience, self-documentation etc.
anon
Although I agree it would be both polite and useful if they explained their down votes.
anon
I'm also not one of the down-voters, but I'd have liked to have seen the reasoning behind your answer rather than just a statement. That'd have earned an upvote. :)
sgreeve
Totally agree down-voters should at least give one liner comment for down voting.
Alien01