Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return by reference or create a typical setter/getter? [duplicate]

Tags:

c++

I was wondering about good practices in C++, and I was facing the problem of making a getter/setter for a class member.

So, why don't simply return the member by reference so this way I can modify or access its value to read it? Specifically, this is my code:

class Chest : public GameObject
{
public:
    Chest();
    ~Chest();

    static int& num_chests();

private:
    static int num_chests_;
};

Is this a bad practice? Should I use these instead?

class Chest : public GameObject
{
public:
    Chest();
    ~Chest();

    static int num_chests();
    static void set_num_chests(int num_chests);

private:
    static int num_chests_;
};
like image 701
Puyover Avatar asked Apr 26 '13 20:04

Puyover


People also ask

Should a getter return a copy?

So the rule of thumb is: Do not return a reference of the original object in the getter method. Instead, it should return a copy of the original object.

Does a getter return a reference?

The reference-getter A reference-getter is a method that directly returns the reference to an attribute to access and edit it.

What is the return type of setter method?

For each instance variable, a getter method returns its value while a setter method sets or updates its value. Given this, getters and setters are also known as accessors and mutators, respectively. The getter method returns the value of the attribute.


2 Answers

Unless you feel very strongly against it, use getter and setter member functions.

The reason int& num_chests() or a public field is bad is that you are coupling client code that uses the num_chests value to the fact that it is actually a field (an internal implementation detail).

Suppose that later you decided you would have a std::vector<Chest> chests private field in your class. Then you wouldn't want to have a int num_chests field -- it's horribly redundant. You would want to have int num_chests() { return chests.size(); }.

If you were using a public field, now all of your client code needs to use this function instead of the previous field access -- every usage of the num_chests value needs to be updated, because the interface has changed.

If you were using a function that returns a reference, you now have a problem because chests.size() is a return by value -- you can't in-turn return that by reference.

Always encapsulate your data. It requires only a minimal amount of boilerplate code.

In response to comments saying you should just use public fields:

Keep in mind that the only benefit of using public fields (other than the remote possibility of some micro-optimization) is that you don't have to write the boilerplate code. "My teacher used to hate when I used public fields (and he was sooo annoying)" is a very poor argument for using public fields.

like image 110
Timothy Shields Avatar answered Oct 06 '22 00:10

Timothy Shields


The purpose of your interface is not to be the simplest to program, but the simplest to use and extend.

If you fail to provide setter and getter methods, you are setting yourself up for later headaches. For example:

  • what happens if you need to emit a notification whenever someone changes the value of num_chests?
  • what happens if you need to validate than num_chests cannot be negative?
  • what happens if you need to run the program in a multi-thread environment and need to lock the reads until the writes are ready?

As you can see, an interface that is transparent to the user is also simpler to protect against user errors, and also extend in the future; this advantage comes at very little (if any) extra cost.

On the other hand, sometimes you do want to return a reference or pointer to an internal member. For example, the container classes in the Standard Library often offer a data() method that retrieves a pointer to the underlying container (both in the const and non-const variations).

So, it is not a hard rule, but I would say that returning non-const references to private members defeats the purpose of OO programming.

like image 39
Escualo Avatar answered Oct 06 '22 01:10

Escualo