3

Recently I have a doubt in my work about the reference of a shared_ptr. Here is the code.

for (const auto & aRef : aVec) { THROW_RUNTIME_IFNULLPTR(aRef); // do sth } 

This is the code of my colleague. In my mind, aRef is a reference which can never be null. While I was told that (by auto &) aRef is still a pointer so it's possible that it's null. The reference is just to not increment the counter. I'm very confused about that.

However, it should be like

for (const auto & aRef : aVec) { // THROW_RUNTIME_IFNULLPTR(aRef); if ( aRef ) { aRef->getX(); } // do sth } 

Am I wrong about this? I don't think that aRef is a pointer.

7
  • 1
    In the example provided what is aVec? What type? Commented Mar 22, 2017 at 16:24
  • 1
    Sorry, it's a vector of shared_ptr Commented Mar 22, 2017 at 16:26
  • 1
    I suppose you could have a reference, to a pointer that is null. (edit: added a comma :>) Commented Mar 22, 2017 at 16:26
  • 1
    aRef is a reference, so it can never be null. It can be an alias to a valid pointer that is indeed null...if that's what you mean. Commented Mar 22, 2017 at 16:27
  • 1
    regarding: "The reference is just to not increment the counter. I'm very confused about that." A shared_ptr is a reference-counted pointer. Every time the shared_ptr is copied, the reference count is increased. Every time a copy is destroyed, the count is decreased. When the reference count hits zero, the pointer is deleteed. By usiung a reference, the shared_ptr is not copied, saving the copy construction and destruction and thus reference count overhead. Commented Mar 22, 2017 at 16:39

3 Answers 3

8

In my mind, aRef is a reference which can never be null.

Yes and no. A reference can be everything which the object it refers to can be. If that object is, say, an int or a std::string or a std::vector<double>, then of course it cannot be null (or nullptr, to be precise).

If that object, however, is a pointer, for example an int*, or a void*, or a MyClass*, then it can be nullptr because the pointer can be nullptr.

Now in your case, the object being referred to is a std::shared_ptr. It cannot technically be nullptr, but it can represent nullptr by being in a state in which get() returns nullptr.

While I was told that (by auto &) aRef is still a pointer so it's possible that it's null.

More precisely: aRef is still a std::shared_ptr, so it's possible that it still represents nullptr.

Sign up to request clarification or add additional context in comments.

Comments

5

std::shared_ptr has explicit operator bool(), so in this code

if ( aRef ) 

that operator will be called, and it returns true if underlying pointer is not null.

1 Comment

Just note that it also have template< class T > bool operator==( const shared_ptr<T>& lhs, std::nullptr_t rhs ); so if ( aRef == nullptr ) is also valid.
2

aRef is a reference. It is an alias for an object.

A pointer is a separate object that perhaps points to another object.

In this case aRef is a reference to an object of type std::shared_ptr<Something>.

The code is roughly equivalent to this:

auto first = aVec.begin(); auto last = aVec.end(); for( ; first != last ; ++first) { std::shared_ptr<Something> const& aRef = *first; if (aRef.get() != nullptr) { aRef->getX(); } else { // handle the case where aRef is not pointing at an object } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.