Create a boost::shared_ptr to an existing variable

前端 未结 4 1166
星月不相逢
星月不相逢 2020-12-08 07:32

I have an existing variable, e.g.

int a = 3;

How can I now create a boost::shared_ptr to a? For example:

相关标签:
4条回答
  • 2020-12-08 07:45

    although you should put the variable into a managed pointer on it's creation to do it from an existing pointer.

    int *a=new int;
    boost::shared_ptr<int> a_ptr(a);
    

    That said you most definitely do not want to be putting stack variables into shared_ptr BAD THINGS WILL HAPPEN

    If for some reason a function takes shared_ptr and you only have a stack varaible you are better off doing this:

    int a=9;
    boost::shared_ptr<int> a_ptr=boost::make_shared(a);
    

    See here:

    http://www.boost.org/doc/libs/1_43_0/libs/smart_ptr/make_shared.html

    also it is worth noting that shared_ptr is in the c++11 standard if you are able using that. You can use auto in combination with make_shared like Herb Sutter notes in the build talk.

    #include <memory>
    
    int a=9;
    auto a_ptr=std::make_shared(9);
    
    0 讨论(0)
  • 2020-12-08 07:57

    First, you have an error because shared_ptr's will not automatically convert from a pointer of the appropriate type. You have to explicitly state that's what you want to do:

    int a = 3;
    ::boost::shared_ptr< int > a_ptr(&a); // DO NOT DO THIS!
    

    You have another problem though. Imagine the effect of this code:

    int a = 3;
    delete &a;
    

    In the first example I gave, this will inevitably happen, even if it's not quite so direct. shared_ptr's whole reason for existence is deleting things when all the pointers to it go away. This, of course, will cause all manner of strange behavior.

    You have two ways of dealing with this issue. One is to create something that can be deleted. The other is to make sure that shared_ptr doesn't actually delete the thing it points to. There are pros and cons to each.

    Making something that can be deleted:

    Pros:

    • Simple and easy.
    • You don't have to worry about object lifetimes.

    Cons:

    • A bit on the slow side, since it will involve a heap allocation or two.
    • The resulting shared_ptr will refer to a copy, so modifications to a will not be reflected in the value of the thing it points to.

    How to do it:

    ::boost::shared_ptr<int> a_ptr(::boost::make_shared(a));
    

    This is rather similar to (and this will also work):

    ::boost::shared_ptr<int> a_ptr(new int(a));
    

    But it's slightly more efficient. ::boost::make_shared does some magic to allocate the reference count and the object in contiguous memory which saves on calls to the allocator and improves locality of reference.

    Making it so that shared_ptr doesn't actually delete what it points to:

    Pros:

    • Faster, though it still involves a heap allocation for the reference count
    • Directly addresses the issue at hand (the thing you're pointing to can't be deleted).
    • The shared_ptr refers to a, so if you change its value things that access it through the pointer will see the new value.

    Cons:

    • Requires knowing a bit more about how shared_ptr works, which means the people reading your code have to know too.
    • If the thing you're pointing to goes out of scope before all shared_ptr's that point to it do, then those pointers become dangling, and that's bad.
    • The previous point makes this a very risky solution. I would generally avoid it.

    How to do it:

    Somewhere outside the function (probably in an anonymous namespace):

    void do_nothing_deleter(int *)
    {
        return;
    }
    

    And then in the function:

    int a = 3;
    ::boost::shared_ptr a_ptr(&a, do_nothing_deleter);
    
    0 讨论(0)
  • 2020-12-08 07:59

    What you wrote won't work because the constructor of shared_ptr you're looking for is explicit, so you'd need to write it like so

    boost::shared_ptr<int> a_ptr(&a); // Don't do that!
    

    The problem with that however, is that delete will be called on the stored value of a_ptr. Since in your example a has automatic storage duration, this is very bad. So we pass in a custom deleter too:

    boost::shared_ptr<int> a_ptr(&a, noop_deleter);
    

    An implementation of noop_deleter for C++11:

    auto noop_deleter = [](int*) {};
    

    C++03 version:

    // Can't be put in local scope
    struct {
        void
        operator()(int*) const
        {}
    } noop_deleter;
    
    0 讨论(0)
  • 2020-12-08 08:05

    You cannot create a boost::shared_ptr for an existing variable. Items stored in a boost::shared_ptr are stored at creation.

    You can however make a boost::shared_ptr that is a copy of an existing variable.

    For example

    int a = 3; // Existing variable
    boost::shared_ptr<int> aCopy = boost::make_shared<int>(a); //Create copy with value of a
    

    Note that you will need to include <boost/make_shared.hpp> for make_shared.

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