NULL pointer with boost::shared_ptr?

后端 未结 6 1006
悲哀的现实
悲哀的现实 2020-12-12 20:35

What\'s the equivalent to the following:

std::vector vec;
vec.push_back(NULL);

when dealing with boost::shared_ptr

相关标签:
6条回答
  • 2020-12-12 20:55

    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.

    0 讨论(0)
  • 2020-12-12 21:10

    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;
    }
    
    0 讨论(0)
  • 2020-12-12 21:13

    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
    
    0 讨论(0)
  • 2020-12-12 21:13

    Yes, declare a global static null pointer.

    0 讨论(0)
  • 2020-12-12 21:14

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

    std::vector< boost::shared_ptr<Foo> > vec;
    vec.push_back(nullptr);
    
    0 讨论(0)
  • 2020-12-12 21:15

    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.

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