C++ C++;父子类的共享指针

C++ C++;父子类的共享指针,c++,destructor,smart-pointers,ownership-semantics,C++,Destructor,Smart Pointers,Ownership Semantics,我有一个场景,在这个场景中,我需要在一个集合中收集某个类型的所有对象,但我还需要它的一些继承类型的集合。例如: class Particle: public someClass { ... public: static std::vector<std::shared_ptr<Particle>> particleCollection; } class ChargedParticle: public Particle { ...

我有一个场景,在这个场景中,我需要在一个集合中收集某个类型的所有对象,但我还需要它的一些继承类型的集合。例如:

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;
}
我如何既能将子对象的集合存储在其静态容器中,又能让智能指针通过它们的父类指向它们

我也希望能够从父类创建对象,并使父类的静态智能指针向量成为这些对象的所有者


我的想法是,我以某种方式为父类智能指针定义了一个自定义删除器,当对象不是子类集合的元素时,它只调用析构函数。这可能吗?

每个
ChargedParticle
同时是一个
粒子
因此调用
Particle::particleCollection.clear()足以删除所有分配的对象

要在您的情况下使用共享指针,您需要有基类(或
someClass
Particle
)从中继承,因此从中创建的共享指针将共享同一计数器。在您的示例中,这是共享指针的两个不同实例,它们彼此一无所知


我不认为虚拟析构函数有任何理由不能满足您的需要。

如果您正确使用它,没有问题,类名与类名不一样,但我认为这并不重要:

#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();

}
#包括
#包括
#包括
#包括
#包括
结构基
{

Base(){std::cout为什么要使用static member来存储这些粒子?当正确使用
共享ptr
时,不应该发生双重析构函数调用。您应该显示更多的代码,可能是mcve:@АаааааЛаааааааааЛаа107如果您想知道所有其他带电粒子的位置,那么您可能应该只将粒子保留在基类中?而不创建可能的重复项?从cppreference,只允许在以前共享的对象上,即在由std::shared_ptr管理的对象上,从该对象调用shared_。否则,行为将未定义(直到C++17)std::bad_弱_ptr被抛出(由来自默认构造的弱_this的共享_ptr构造函数抛出)(从C++17开始)在清除单分子句之后,如果我循环它,它将包含悬空指针。我使用虚拟析构函数,但我从来没有听说过这个STD::Enable SysDyfRoFuff.这个类。我会查一下,谢谢:@ AdamHunyadi,你可以考虑使用<代码> STD::
,或从析构函数中的适当数组中删除项。在这种情况下,我如何使用std::weak_ptr?@AdamHunyadi弱指针的成员
已过期
,它可以判断对象是否已被删除。但这一切都取决于您希望如何管理我理解的所有权,但我如何将派生类的弱指针放置到向量不能使它们成为基类的弱ptr,因为我在派生对象集合中使用它们。我也不能使它成为派生的弱ptr,因为这样我就不能使它保持基类的共享ptr。这是不好的,因为在我的基类构造函数调用中,我不能有指向派生类的指针。@AdamHunyadi这意味着您需要AdamHunyadi登记,你的问题是,当构造函数没有完成时,对象不存在,如果构造函数抛出,对象不存在,那表示你的向量有一个不存在的对象,考虑使用工厂设计模式。instead@AdamHunyadi更清楚地说,
std::enable\u shared\u from_this
抱怨
差-弱\u ptr
,如您所见
#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();

}