Reputation: 1526
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
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
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
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
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
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
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