I get a vector of raw pointers, which I copy. The ownership of the objects pointed by these pointers belong to some other module. I have to replace some of the pointers with new ones which point to newly created objects. So in the end I will have a vector with pointers on which I need to call delete and others on which I do not. My idea was to introduce new classes which make this automatic.
template <typename T, class = std::enable_if_t<std::is_pointer<T>::value>>
class Pointer {
public:
Pointer(T p) : pointer_(p) {}
virtual ~Pointer() = default;
T operator->() { return pointer_; }
protected:
T pointer_;
};
template <typename T>
class NotOwnedPointer : public Pointer<T> {
public:
NotOwnedPointer(T p) : Pointer<T>(p) {}
~NotOwnedPointer() { std::cout << "not owned\n"; }
};
template <typename T>
class OwnedPointer : public Pointer<T> {
public:
OwnedPointer(T p) : Pointer<T>(p) {}
~OwnedPointer() { std::cout << "owned\n"; delete this->pointer_; this->pointer_ = nullptr; }
OwnedPointer(const OwnedPointer&) = delete;
OwnedPointer& operator=(const OwnedPointer& other) = delete;
};
struct Foo {
int i;
};
int main() {
Foo* foo = new Foo{42};
std::vector<Pointer<Foo*>> v;
v.push_back(NotOwnedPointer(foo));
v.push_back(OwnedPointer(foo));
}
Note that I use Pointer
for the vector type instead of Pointer*
. This way slicing will happen when I add a derived class instance to the vector.
Which destructors will be called when the vector is destructed? Since the type of the vector is Pointer
I would say that the virtual table for class Pointer
will be used and ~Pointer()
will be called, but when I run the program it prints the text from ~NotOwnedPointer()
and ~OwnedPointer()
.
v.push_back(NotOwnedPointer(foo));
v.push_back(OwnedPointer(foo));
These two lines create temporary objects (of type NotOwnedPointer
and OwnedPointer
, respectively), which are then sliced and copied into the vector.
When the temporary objects are destroyed, their destructors are called (~NotOwnedPointer()
and ~OwnedPointer()
, respectively). This has nothing to do with v
, which is destroyed later.