2

我想要一个P具有静态delete_all成员函数的类,它将删除所有动态分配的类型实例P或从P.

这是我所拥有的:

#include <unordered_set>
using namespace std;

struct P
{
    static unordered_set<P*> pool;

    static void* operator new(size_t size)
    {
        void* p = ::operator new(size);
        pool.insert(static_cast<P*>(p));
        return p;
    }

    static void operator delete(void* p)
    {
        pool.erase(static_cast<P*>(p));
        ::operator delete(p);
    }

    static void delete_all()
    {
        while (!pool.empty())
            delete *(pool.begin());
    }

    virtual ~P() {}; // polymorphic
};

unordered_set<P*> P::pool;

一个示例用法是这样的:

struct D : P
{
    ...
};

int main()
{
    D d1;
    D* d2 = new D();
    D* d3 = new D();

    delete d2;

    P::delete_all(); // deletes d3, but not d1 or d2
}

我关心的部分是将void*指针静态转换为P*. 我有一种感觉,这在某些情况下会导致未定义的行为,例如,当在派生类上调用 new 时,P 基类子对象不是从派生类的开头开始的。内存块还不知道它是派生类类型,因此static_cast<P*>from void 不会给出 P 子对象的正确位置。

我是否正确,这是一个问题?我该如何解决?

另外,还有其他P我不知道的问题吗?

4

1 回答 1

0

由于您描述的确切原因,您的 static_casts 是一个问题是正确的。

除非我遗漏了一些明显的东西,否则你不需要整个 operator new/operator delete 跳舞。只需将 P 的构造函数存储this在池中,然后 P 的析构函数将其从池中删除。这样,您总是可以处理诚实的 P* 指针。确保在所有构造函数中执行此操作(回想一下,如果您不显式提供或禁用它们,编译器将生成复制和移动构造函数)。

于 2013-07-11T05:17:09.923 回答