Let\'s say I have an object Employee_Storage
that contains a database connection data member. Should this data member be stored as a pointer or as a reference?
Adding to this question..
Class with reference data member:
It is almost never prefereable to store references as data members, and a lot of the time it is impossible. If the objects must be assignable (as they must to be stored in a standard library container), references cannot be used. Also, references cannot be reseated, so once a reference is initialised with an object, it cannot be made to refer to a different object.
See this question Should I prefer pointers or references in member data? for a more detailed discussion of the issue.
It's only preferable to store references as data members if they're being assigned at construction, and there is truly no reason to ever change them. Since references cannot be reassigned, they are very limited.
In general, I typically store as pointers (or some form of templated smart pointer). This is much more flexible - both for testing (as you mentioned) but also just in terms of normal usage.
I was trying to figure this out myself, so might as well post it. I conclude it doesn't seem to be a good idea to use reference data member because you could inadvertently create an alias when you go to initialize it.
#include <iostream>
using namespace std;
class stuff
{
public:
explicit stuff(int &a):x(a) //you have to initialize it here
{
//body intialization won't work
};
int& x; //reference data member
};
int main()
{
int A=100;
stuff B(A);//intialize B.x
cout<<B.x<<endl;//outputs 100
A=50;//change A;
cout<<B.x<<endl; //outputs 50, so B.x is an alias of A.
system("pause");
return 0;
}
Given a choice, I like to use the most constrained type possible. So if I don't need to support null objects I'd much prefer to declare a
Foo& m_foo;
member rather than a
Foo*const m_foo;
member, because the former declaration documents the fact that m_foo
can't be null.
In the short term, the advantage isn't that great. But in the long run, when you come back to old code, the instant assurance that you don't have to worry about the case of m_foo
being null is quite valuable.
There are other ways of achieving a similar effect. One project I worked on where they didn't understand references would insist any potentially null pointers be suffixed '00' e.g m_foo00
. Interestingly, boost::optional
seems to support references although I haven't tried it. Or you can litter your code with assertions.