When is it preferable to store data members as references instead of pointers?

前端 未结 5 2294
耶瑟儿~
耶瑟儿~ 2021-02-20 16:33

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?

相关标签:
5条回答
  • 2021-02-20 16:38

    Adding to this question..

    Class with reference data member:

    • you must pass a value to the object at construction (not unexpectedly)
    • breaks the rule of encapsulation, as referenced variable can be changed from outside class, without class object having any control of it. (I suppose the only use case could be something like this though, for some very specialized reasons.)
    • prevents creating assignment operator. What are you going to copy?
    • you need to ensure the referred variable is not destroyed while your object is alive
    0 讨论(0)
  • 2021-02-20 16:45

    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.

    0 讨论(0)
  • 2021-02-20 16:49

    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.

    0 讨论(0)
  • 2021-02-20 17:00

    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;
    }
    
    0 讨论(0)
  • 2021-02-20 17:04

    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.

    0 讨论(0)
提交回复
热议问题