Search code examples
c++clangshared-ptrsmart-pointersunique-ptr

C++11 Convert traditional pointer to smart pointer. Using up-to-date SVN Clang and libc++ from llvm


I've got a function inside a class (A) that essentially takes as a parameter a pointer to another class (B). The B class is inherited by multiple other classes which it should also accept.

What I would like to do is take ownership of this pointer to store for later use in the class, it won't be used outside the class again for anything else. While I would make the parameter a shared_ptr, I would like to avoid that as much as possible due to other people I work with who don't quite get the whole smart pointer thing. Is there any way to do this?

Here's a sort of example that I would like to do, although from what I've tested this doesn't work.

//In .h file
std::vector< unique_ptr< B > > data_store;

//In .cpp file
void A::add_data(B* NewItem)
{
    data_store.resize(data_store.size()+1);
    data_store[data_store.size()-1] = NewItem;
}

Second to that, I would like to maybe use a copy constructor or something similar to use a smart pointer inside the class: with what I'm having to do it could get a bit ugly if I have to do manual deletes. The problem with that is that I don't know whether it's the base class (B) coming in or whether it's a class that inherited from B. I'm not too sure how to deal with that without having to hard-code in some kind of checkable ID for the class and using the correct copy/move constructors, which I would like to avoid at all costs.

I'm using an updated Clang and libC++ from llvm which I updated about 10am UK time on 12th March 2012.


Solution

  • For any pointer that isn't supposed to be shared, which the class has sole ownership of the std::unique_ptr<T> is the correct choice. It will automatically delete the pointer when the owning object goes out of scope/is deleted. I would actually advice against using a shared pointer for this at all, as it would communicate to other developers that this member is supposed to be shared.

    So for the copying. Since you have a pointer to an object which might have subclasses you need to use the clone idiom instead of a normal copy constructor. It is normally implemented by having a virtual clone function which returns a pointer (or a smart pointer) to the class. This requires all subclasses to reimplement this, returning a copy of itself.

    class Base {
        ...
        virtual std::unique_ptr<Base> clone() const = 0;
        ...
    };
    
    class Subclass {
        ...
        virtual std::unique_ptr<Base> clone() const {
            return std::unique_ptr<Base>(new Subclass(*this));
        }
    };
    

    If the owning object has a copy constructor it will have to invoke this clone member function on the object it owns when creating a copy of itself.