C++ 切片和虚拟析构函数
C++ slicing and virtual destructors
我得到了一个原始指针向量,我复制了它。这些指针指向的对象的所有权属于其他某个模块。我必须用指向新创建对象的新指针替换一些指针。所以最后我将有一个带有指针的向量,我需要在上面调用 delete 和其他我不需要的指针。我的想法是引入新的 classes 来实现这一点。
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
作为矢量类型而不是 Pointer*
。当我将派生的 class 实例添加到向量时,就会发生这种切片。
vector被析构时会调用哪些析构函数?由于向量的类型是 Pointer
我会说 class Pointer
的虚拟 table 将被使用并且 ~Pointer()
将被调用,但是当我运行 程序打印来自 ~NotOwnedPointer()
和 ~OwnedPointer()
的文本。
v.push_back(NotOwnedPointer(foo));
v.push_back(OwnedPointer(foo));
这两行创建临时对象(类型分别为 NotOwnedPointer
和 OwnedPointer
),然后将其切片并复制到向量中。
当临时对象被销毁时,将调用它们的析构函数(分别为~NotOwnedPointer()
和~OwnedPointer()
)。这个跟v
没有关系,后面就销毁了
我得到了一个原始指针向量,我复制了它。这些指针指向的对象的所有权属于其他某个模块。我必须用指向新创建对象的新指针替换一些指针。所以最后我将有一个带有指针的向量,我需要在上面调用 delete 和其他我不需要的指针。我的想法是引入新的 classes 来实现这一点。
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
作为矢量类型而不是 Pointer*
。当我将派生的 class 实例添加到向量时,就会发生这种切片。
vector被析构时会调用哪些析构函数?由于向量的类型是 Pointer
我会说 class Pointer
的虚拟 table 将被使用并且 ~Pointer()
将被调用,但是当我运行 程序打印来自 ~NotOwnedPointer()
和 ~OwnedPointer()
的文本。
v.push_back(NotOwnedPointer(foo));
v.push_back(OwnedPointer(foo));
这两行创建临时对象(类型分别为 NotOwnedPointer
和 OwnedPointer
),然后将其切片并复制到向量中。
当临时对象被销毁时,将调用它们的析构函数(分别为~NotOwnedPointer()
和~OwnedPointer()
)。这个跟v
没有关系,后面就销毁了