Disclaimer : This is C++03. My apologies for not making that clear before. Also auto_ptr is out because of company guidelines.

Example code:

void foo(boost::ptr_vector<MyType>& iPtrVector)
{
    boost::scoped_ptr<MyType> aScopedPtr = new MyType();
    // lots of logic here

    if (condition)
        iPtrVector.push_back(*aScopedPtr);
} // eek! Resource is freed, but maybe referenced in iPtrVector now!

My issue with this is that the resource will be deleted when the scoped pointer goes out of scope, but actually I want the resource to be maintained in the ptr_vector if my condition is true. My approach would be to revoke ownership from the scoped_ptr if I decided I needed to hold it in the ptr vector. However, scoped_ptr doesn't permit this.

Thus I've built a simple class to handle it for me :

template <class T>
struct CustomScopedPointer
{
    CustomScopedPointer() : _targetPtr(NULL) { }
    ~CustomScopedPointer() { delete _targetPtr; }
    T* _targetPtr;

    // calling this with a null ptr will ensure the resource 
    // isn't deleted at dtor time
    CustomScopedPointer& operator=(T* rhs)
    {
        _targetPtr = rhs;
        return *this;
    }

};

Is there a way to do this without defining my own class, however? It seems overkill for a particular specific circumstance, and I was very surprised to find that there is no way to prevent a smart pointer from deleting its managed resource - even a reset or reassignment first frees the original resource.

(As for why I'm forced to handle it like this, it's because of business reasons. Suffice to say that the resource must be freed in case of exception, etc, but equally cannot be inside the ptr_vector except in some circumstances)

有帮助吗?

解决方案

Use std::unique_ptr:

auto aScopedPtr = make_unique<MyType>();
// lots of logic here

if (condition)
    iPtrVector.push_back(aScopedPtr.release());

You can search around for an implementation of make_unique to copy and paste. You can use:

std::unique_ptr<MyType> aScopePtr{ new MyType() };

If you really have to, but strongly prefer make_unique.


If you can't use C++11 features, you can do the same with std::auto_ptr:

std::auto_ptr<MyType> aScopePtr{ new MyType() };

Just be aware it's deprecated and has pitfalls.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top