NULL pointer with boost::shared_ptr?

C++BoostNullPointersShared Ptr

C++ Problem Overview


What's the equivalent to the following:

std::vector<Foo*> vec;
vec.push_back(NULL);

when dealing with boost::shared_ptr? Is it the following code?

std::vector< boost::shared_ptr<Foo> > vec;
vec.push_back(boost::shared_ptr<Foo>());

Note: I may push back a lot of such objects. Should I declare a global static nullPtr object somewhere? That way only one of them would have to be constructed:

boost::shared_ptr<Foo> nullPtr;

C++ Solutions


Solution 1 - C++

Your suggestion (calling the shared_ptr<T> constructor with no argument) is correct. (Calling the constructor with the value 0 is equivalent.) I don't think that this would be any slower than calling vec.push_back() with a pre-existing shared_ptr<T>, since construction is required in both cases (either direct construction or copy-construction).

But if you want "nicer" syntax, you could try the following code:

class {
public:
    template<typename T>
    operator shared_ptr<T>() { return shared_ptr<T>(); }
} nullPtr;

This declares a single global object nullPtr, which enables the following natural syntax:

shared_ptr<int> pi(new int(42));
shared_ptr<SomeArbitraryType> psat(new SomeArbitraryType("foonly"));

...

pi = nullPtr;
psat = nullPtr;

Note that if you use this in multiple translation units (source files), you'll need to give the class a name (e.g. _shared_null_ptr_type), move the definition of the nullPtr object to a separate .cpp file, and add extern declarations in the header file where the class is defined.

Solution 2 - C++

Well, this is legal:

shared_ptr<Foo> foo;  /* don't assign */

And in this state, it doesn't point to anything. You can even test this property:

if (foo) {
    // it points to something
} else {
    // no it doesn't
}

So why not do this:

std::vector < shared_ptr<Foo> > vec;
vec.push_back (shared_ptr<Foo>);   // push an unassigned one

Solution 3 - C++

In C++0x, you can simply convert from nullptr to std::shared_ptr:

std::vector< boost::shared_ptr<Foo> > vec;
vec.push_back(nullptr);

Solution 4 - C++

You could declare a global nullPtr for shared_ptr<Foo>. But if you pollute the global namespace, what would you call the global nullPtr for shared_ptr<Bar>?

Typically I declare the null ptr as a static in the class of the pointer.

#include <boost\shared_ptr.hpp>

class Foo; // forward decl
typedef boost::shared_ptr<Foo> FooPtr;
class Foo
{
public:
    static FooPtr Null;
}
...
// define static in cpp file
FooPtr Foo::Null;
...
// use Foo Null
vec.push_back(Foo::Null);

That way each class has a static Null.

Solution 5 - C++

Here's something which I think is a bit simpler and works just fine

( remember that typedef is your friend ):

#include	<cstdlib>
#include    <vector>
#include    <iostream>
#include    <boost/shared_ptr.hpp>

typedef boost::shared_ptr< std::vector<char> > CharVecHandle;

inline CharVecHandle newCharVec(std::vector<char>::size_type size) {
    return CharVecHandle(new std::vector<char>(size));
}

inline CharVecHandle newCharVec(void) {
    return CharVecHandle();
}

int main ( void )
{
    CharVecHandle cvh = newCharVec();

    if (cvh == NULL) 
        std::cout << "It's NULL" << std::endl;
    else 
        std::cout << "It's not NULL" << std::endl;

    std::vector< CharVecHandle > cvh_vec;

    cvh_vec.push_back(newCharVec(64));
    cvh_vec.push_back(newCharVec());

    // or call the NULL constructor directly
    cvh_vec.push_back(CharVecHandle());

    return EXIT_SUCCESS;
}

Solution 6 - C++

Yes, declare a global static null pointer.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionFrankView Question on Stackoverflow
Solution 1 - C++j_random_hackerView Answer on Stackoverflow
Solution 2 - C++Larry GritzView Answer on Stackoverflow
Solution 3 - C++bdonlanView Answer on Stackoverflow
Solution 4 - C++m-sharpView Answer on Stackoverflow
Solution 5 - C++Robert S. BarnesView Answer on Stackoverflow
Solution 6 - C++Christopher DolanView Answer on Stackoverflow