jack_carver
jack_carver

Reputation: 1526

Is it ok to return a reference?

I have something like

class X
{
    private:
    someclass obj;

    public:
    someclass& get()
    {
        return obj;
    }
};

I dont want to make obj public, so i get a reference of it and pass it around to functions. Is this a good/ok practice or is it outright evil ?

Upvotes: 2

Views: 306

Answers (6)

Nikko
Nikko

Reputation: 4252

It's not evil. It is how it is supposed to be done: you can return references to internal data members. You don't need to do it through pointers or by value if you don't want a copy: references were made to do this.

If you don't want it to be modified, you have to return a "const" reference to your internal data member:

public:
const someclass & get() const
{
    return obj;
}

Note that then I added const at the end of the get() method to instruct that using this method will not modify the class.

Upvotes: 6

Emilio Garavaglia
Emilio Garavaglia

Reputation: 20730

What you did is technically correct: you get a reference to an internal part of X you use to change it.

The only thing you have to take care is that X itself lives longer than the place you store the returned reference.

There is nothing evil with this.

The evil thing is another: you allow full access to obj to whoever can cal get() (practically everyone). You are at all effect making public obj itself, giving the illusion it is still private.

If you accept everyone can modify obj... just make it public. If you want "someone" can, keep it private an make someone a friend. If you want anyone access obj in read-only ... return a const& fron a const function.

Upvotes: 2

Nicola Musatti
Nicola Musatti

Reputation: 18218

I consider it evil. obj will be destroyed when the containing instance of X will be destroyed and you have no way to force callers of X::get() to take this into account:

someclass & evil() {
  X x;
  return x.get();
}

It definitely is evil ;-)

The only things that are safe to return by reference are either *this in a member function or arguments that were taken by reference in the first place.

If obj is small enough return it by value, otherwise implement some way of sharing its ownership. Boost.SharedPtr, now part of the C++ standard, may be of help.

Upvotes: 0

Dan
Dan

Reputation: 13382

If you pass a non-const reference as in your code then obj can be modifed from outside your class. If you wish that it cannot be changed from outside X you must return a const ref,

const someclass& get();

Note with this case it is worth adding another const after the function name

const someclass& get() const;

which tells the compiler that calling get() on an X won't change its internal state. (This is not true of your example)

Upvotes: 7

Metaller
Metaller

Reputation: 514

Many books advice not to have direct access to variable and to use GET/SET methods like:

class SetandGet
{
public:
    void Set(int x){
        TheVariable = x;
    }
    int Get(){
        return TheVariable;
    }
private:
    int TheVariable;
}

Upvotes: 1

Šimon Tóth
Šimon Tóth

Reputation: 36433

It is OK.

Just consider making the reference constant, or at least making two get() methods (one for normal and one for constant objects).

Upvotes: 5

Related Questions