-2

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

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

我怎样才能将子对象的集合存储在其静态容器中,并让它们的父类之一指向它们的智能指针?

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

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

4

2 回答 2

1

Every ChargedParticleis at the same time is a Particleso callParticle::particleCollection.clear();足以删除所有已分配的对象。

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

而且我认为虚拟析构函数不足以满足您的需求。

于 2016-11-05T11:10:15.850 回答
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();

}

Demo是从Cpp Reference中的示例扩展而来的

您无法创建自注册类,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 起)。

于 2016-11-05T11:21:13.303 回答