简体   繁体   中英

C++ slicing and virtual destructors

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM