Search code examples
c++referenceclass-members

Should I prefer pointers or references as data members?


This is a simplified example to illustrate the question:

class A {};

class B
{
    B(A& a) : a(a) {}
    A& a;
};

class C
{
    C() : b(a) {} 
    A a;
    B b; 
};

So B is responsible for updating a part of C. I ran the code through lint and it whinged about the reference member: lint#1725. This talks about taking care over default copy and assignments which is fair enough, but default copy and assignment is also bad with pointers, so there's little advantage there.

I always try to use references where I can since naked pointers introduce uncertaintly about who is responsible for deleting that pointer. I prefer to embed objects by value but if I need a pointer, I use std::auto_ptr as a data member of the class that owns the pointer, and pass the object around as a reference.

I would generally only use a pointer as a data member when the pointer could be null or could change. Are there any other reasons to prefer pointers over references for data members?

Is it true to say that an object containing a reference should not be assignable, since a reference should not be changed once initialized?


Solution

  • Avoid reference members, because they restrict what the implementation of a class can do (including, as you mention, preventing the implementation of an assignment operator) and provide no benefits to what the class can provide.

    Example problems:

    • you are forced to initialise the reference in each constructor's initialiser list: there's no way to factor out this initialisation into another function (until C++0x, anyway edit: C++ now has delegating constructors)
    • the reference cannot be rebound or be null. This can be an advantage, but if the code ever needs changing to allow rebinding or for the member to be null, all uses of the member need to change
    • unlike pointer members, references can't easily be replaced by smart pointers or iterators as refactoring might require
    • Whenever a reference is used it looks like value type (. operator etc), but behaves like a pointer (can dangle) - so e.g. Google Style Guide discourages it