Why don't I need to check if references are invalid/null?

前端 未结 11 2076
半阙折子戏
半阙折子戏 2020-12-23 11:20

Reading http://www.cprogramming.com/tutorial/references.html, it says:

In general, references should always be valid because you must always initi

11条回答
  •  离开以前
    2020-12-23 11:30

    I think you could benefit from a simple parallelism:

    • T & is similar to T * const
    • T const & is similar to T const * const

    References are very similar to const in their intent, they carry a meaning and thus help write clearer code, but don't provide different runtime behavior.

    Now to answer your question: yes it is possible that a reference be null or invalid. You can test for a null reference (T& t = ; if (&t == 0)) but it should not happen >> by contract a reference is valid.

    When to use reference vs pointer ? Use a pointer if:

    • you wish to be able to change the pointee
    • you wish to express the possible nullity

    In any other case, use a reference.

    Some examples:

    // Returns an object corresponding to the criteria
    // or a special value if it cannot be found
    Object* find(...); // returns 0 if fails
    
    // Returns an object corresponding to the criteria
    // or throw "NotFound" if it cannot be found
    Object& find(...); // throw NotFound
    

    Passing arguments:

    void doSomething(Object* obj)
    {
      if (obj) obj->doSomething();
    }
    
    void doSomething(Object& obj) { obj.do(); obj.something(); }
    

    Attributes:

    struct Foo
    {
      int i;
      Bar* b; // No constructor, we need to initialize later on
    };
    
    class Foo
    {
    public:
      Foo(int i, Bar& b): i(i), b(b) {}
    private:
      int i;
      Bar& b; // will always point to the same object, Foo not Default Constructible
    };
    
    class Other
    {
    public:
      Other(Bar& b): b(&b) {} // NEED to pass a valid object for init
    
      void swap(Other& rhs);  // NEED a pointer to be able to exchange
    
    private:
      Bar* b;
    };
    

    Functionally references and pointers play the very same role. It's just a matter of contract. And unfortunately, both can invoke Undefined Behavior if you delete the object they refer to, there's no winner there ;)

提交回复
热议问题