使用静态 std::set 来管理 class 的所有实例的资源是否有目的?

Is there a purpose for using a static std::set to manage resources of all instances of a class?

我继承了一些我正在重构的代码,我遇到了一些我不确定意图的事情。许多(或多或少全部)类 已默认为以下模式,其中内存管理似乎旨在使用静态 std::set.

进行处理
class A
{
public:
    A()
    { 
        B_ = new B();
        All_A.insert(this);
    }

    ~A(){ delete B_; }

    static void DestructAll_A()
    {
        for (std::set<A*>::iterator Itr = All_A.begin(); Itr != All_A.end(); ++Itr) 
        {
            A* Obj = *Itr;
            delete Obj;
        }

        All_A.clear();
    };

    static std::set<A*> All_A;

    B* B_;
}

我最初的想法是这是不好的做法。据我所知,类 以这种方式使用并没有明显的优势。 .此外,DestructAll_A() 不调用 A 的析构函数,因此 B 永远不会被删除,除非事先调用 A 的析构函数,这会产生对操作顺序的依赖,我觉得这很混乱(尽管我认为这可以在 DestructAll_A()) 内完成。最后,我不清楚如何区分静态构造与动态构造(使用 new)的 A 实例。

我错过了什么吗?使用这种模式的一般目的或优势是什么?提前致谢。

DestructAll_A() does not call A's destructor

是的。 Obj 具有类型 A*,因此 delete Obj 将调用 A::~A() 析构函数。对于未使用标量 new A().

分配的任何实例,这是未定义的行为

Lastly, it's unclear to me how it would be differentiated instances of A that were statically vs dynamically constructed (using new).

它不会尝试区分...此 class 绝不能使用,除非用于标量动态分配。

在评论 OP 中询问“DestructAll_A() 是否有可能以某种方式隐式调用?”

不是真正隐含的方式,但几乎可以做到以下几点:

class A_Cleaner
{
    ~A_Cleaner(){
         A::DestructAll_A();
    }
}

void Main()
{
     A_Cleaner cleaner;

     .... //your program

     // just before reaching the end of main, cleaner dtor is called, so A::DestructAll_A() is called, even in case of exception;
}

我认为这是实施“穷人的垃圾收集”的尝试。以下是它在批处理情况下的工作方式:

  • 您获得了一批新的工作,并开始处理
  • 你在分配内存的同时忽略了释放它的需要
  • 批处理结束后,您调用DestructAll_XYZ收拾残局
  • 您的系统已为下一批做好准备

这种方法既快又脏,所以我肯定会建议在某个时候清理它。至少我会摆脱静态集,用更可控的东西代替它们——比如,BatchMemoryContext 中包含所有相关集。这样您就可以严格控制对象的生命周期,并避免可能出现的并发问题。