3

There is something that I've been wondering for a while and I hope you guys can share your thoughts on the matter. I first discovered this problem around a half a year ago when I programmed a robot that was controlled by a PLC. In structured text I used get-functions to return an object from a class. This way I could do anything I wanted to a member/variable of that class (with the use of getters and setters). This saved me a lot of work, since I didn't have to make seperate functions to get something out of a deeper lying object.

At the moment I am programming something in Qt C++ and yet again I face this issue. I am not sure if I am being completely clear right now (I am not a native English speaker and am also not that competent in coding jargon), so I will try to make it clear with an example. Let's say i have an array/vector with multiple objects in it of the class School. Each object has it's own array with classes (I mean a class with students, not a programming class), each class has it's own array with students and they of course have a name, student id, age, etc.

Now I would like to get the name of a random student. In Qt C++ I would do it something like this:

QString randomName = schoolVector.at(randomNumber)->getClassVector().at(anotherRandomNumber)->getStudentVector().at(yetAgainARandomNumber)->getName();

You can see that I made some get-functions to return an object in a certain class. This way it makes it easy for me to manipulate an object or variable in a class. Here is the reason I am asking this question: Is this the way to go? In school they teached me that the use of getters and setters is important so that you cannot manipulate a variable when you don't want to or you don't want anyone else to. But when I use a getter to return a class in the classVector I can still manipulate anything in there.

Can anyone tell me common practice and also if it is normal to use for-loops to find a certain object in a vector? I would really appreciate it!

Cheers, Martijn

MartijnKor
  • 82
  • 1
  • 9
  • You might want to give this a read: https://stackoverflow.com/questions/32625274/public-variables-bad-practice-vs-getters-and-setters-functions – NathanOliver Sep 05 '17 at 18:51
  • Thanks for sending that link! It indeed looks a lot like the question I asked. So if I understand correctly not everyone thinks the same about the issue? But how do people do these kind of thinks when they ARE using getters and setters? – MartijnKor Sep 05 '17 at 19:05
  • Generally it would look like what you have. Really though what I think you should do is have a separate `student_list` in your `School` that has all the students that are enrolled and then you can simply pick a random student from that list. – NathanOliver Sep 05 '17 at 19:08
  • Isn't that sort of like my studentVector? – MartijnKor Sep 05 '17 at 19:36
  • Kind of, but insterad of living inside `Class` it lives inside `School`. – NathanOliver Sep 05 '17 at 19:43
  • Aah I see what you mean. And then fill the vector with pointers of the Students? – MartijnKor Sep 05 '17 at 19:44
  • Possibly. One issue with storing pointers is if you modify the vector you have pointers to then it could invalidate those pointers. This might be a use case for a `std::vector>` in `School` and a `std::vector>` in `Class`. – NathanOliver Sep 05 '17 at 19:48

1 Answers1

1

If I understood, you want to be able to access the objects (read them) in a way that preserves encapsulation. You can achieve that by defining a getter that returns a const reference to the internal object, e.g.:

const std::vector<Class>& getClassVector() const { return class_vector; }

Now you do have accesss to the underlying object without being able to modify it.

BTW maybe it's splitting hair and you know it, but it's not exactly true that setters/getters are implemented so that people cannot modify the underlying variables when you don't want them to - a setter can be called anytime and modify the variable and you can't prevent that. They are there so that any modification can be performed in a controlled way (e.g. by checking if the value about to be set is within the range that you expect and handle the case when it's not, or by recalculating some other variables dependent on the value you are setting, switching object's state, preventing possible data races etc.).

KjMag
  • 2,650
  • 16
  • 16