C++ 切片和虚拟析构函数

标签 c++ slice virtual-destructor

我得到了一个原始指针 vector ,我复制了它。这些指针指向的对象的所有权属于其他某个模块。我必须用指向新创建对象的新指针替换一些指针。所以最后我将有一个带有指针的 vector ,我需要在上面调用 delete 和其他我不需要的指针。我的想法是引入新的类来实现这一点。

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));
}

请注意,我使用 Pointer 作为 vector 类型而不是 Pointer*。这样,当我将派生类实例添加到 vector 时,就会发生切片。

vector被析构时会调用哪些析构函数?由于 vector 的类型是 Pointer 我会说类 Pointer 的虚拟表将被使用并且 ~Pointer() 将被调用,但是当我运行该程序时,它会打印来自 ~NotOwnedPointer()~OwnedPointer() 的文本。

最佳答案

v.push_back(NotOwnedPointer(foo));
v.push_back(OwnedPointer(foo));

这两行创建临时对象(类型分别为 NotOwnedPointerOwnedPointer),然后将其切片并复制到 vector 中。

当临时对象被销毁时,将调用它们的析构函数(分别为~NotOwnedPointer()~OwnedPointer())。这与v无关,后面会被销毁。

关于C++ 切片和虚拟析构函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50887648/

相关文章:

javascript - 如何连接 2 个切片数组?

c++ - 编译器在 GCC 和 MSVC 中生成析构函数和警告

c++ - 在第三方软件中派生没有虚拟析构函数的类

c++ - Windows GUI 和 native C++

C++ 类和重载运算符

python - 如何将 numpy 矩阵元素设置为具有给定索引的值

arrays - 根据条件切片二维 numpy 数组

c++ - 在 C++ 中删除 boost 包装器中的对象

c++ - 在数组 C++ 中查找特定值

c# - 监控 USB 流量