我有一个场景,我需要收集集合中所有类型的对象,但我还需要一些其继承类型的集合。例如:
class Particle: public someClass
{
...
public:
static std::vector<std::shared_ptr<Particle>> particleCollection;
}
class ChargedParticle: public Particle
{
...
public:
static std::vector<std::shared_ptr<ChargedParticle>> chargedParticleCollection;
}
但是当我想要销毁这些对象时,我实际上每次为ChargedPartice调用析构函数两次:
Particle::particleCollection.clear(); // Okay
ChargedParticle::chargedParticleCollection.clear(); // Error: particles are already deleted
我怎样才能拥有存储在其静态容器中的子对象的集合,并且有一个智能指针指向它们的父类之一?
我希望能够从父类创建对象,并让父级的静态智能指针向量成为这些对象的所有者。
我的想法是,当对象不是子类集合的元素时,我以某种方式为仅调用析构函数的父类智能指针定义自定义删除器。这可能吗?
答案 0 :(得分:1)
每个ChargedParticle
同时是Particle
,因此调用Particle::particleCollection.clear();
就足以删除所有已分配的对象。
要在您的情况下使用共享指针,您需要从std:: enable_shared_from_this
继承基类(someClass
或Particle
),因此从它创建的共享指针将共享同一个计数器。在您的示例中,这些是共享指针的两个不同实例,彼此之间一无所知。
我认为虚拟析构函数不足以满足您的需求。
答案 1 :(得分:0)
如果你正确使用它,没有问题,班级的名字与你的班级名称不一样,但我认为这不重要:
#include <iostream>
#include <type_traits>
#include <tuple>
#include <vector>
#include <memory>
struct Base
{
Base() { std::cout << " Base::Base()\n"; }
// Note: non-virtual destructor is OK here
~Base() { std::cout << " Base::~Base()\n"; }
};
struct Derived: public Base
{
Derived() { std::cout << " Derived::Derived()\n"; }
~Derived() { std::cout << " Derived::~Derived()\n"; }
};
int main() {
std::vector<std::shared_ptr<Base>> base_vector;
std::vector<std::shared_ptr<Derived>> derived_vector;
auto d = std::make_shared<Derived>();
derived_vector.push_back(d);
base_vector.push_back(d);
// 2 function call below does not matter
base_vector.clear();
derived_vector.clear();
}
中的示例扩展而来
您无法使用std::shared_ptr
创建自我注册的课程,因为您需要继承std::enable_shared_from_this
,但您无法在构造函数中调用shared_from_this()
,因为:
允许仅在先前共享的对象上调用shared_from_this,即在由std :: shared_ptr管理的对象上。否则行为是未定义的(直到C ++ 17)抛出std :: bad_weak_ptr(由默认构造的weak_this中的shared_ptr构造函数)(因为C ++ 17)。