我们可以明确地称呼虚拟的“操作员删除”吗?

时间:2018-08-18 10:04:00

标签: c++ clang++ automated-refactoring

出于我不希望在这里深入讨论的原因,我需要在庞大的现有代码库中充分利用自动operator newoperator delete来规范分配和释放。为此,我将使用new X(...)重写(使用clang前端遍历)每次出现new (allocate<X>()) X(...),其中allocate<X>的默认实现会调用特定于类的{{1} }(如果存在),否则为operator new。我知道这不是100%的声音,但对于我要定位的代码库来说,它“足够好”。

现在,我正在尝试为::operator new引入类似的拦截行为,但是由于虚拟delete的怪异特性,这比预期的要难。来自https://en.cppreference.com/w/cpp/memory/new/operator_delete

  

在多态类上对特定于类的operator delete的调用是唯一通过动态分派调用静态成员函数的情况。

考虑以下示例:

T::operator delete

理想情况下,我想将代码库中每次出现的struct A { virtual ~A() { cout << "~A" << endl; } static void operator delete(void* ptr) { cout << "A::operator delete" << endl; ::operator delete(ptr); } }; struct B : public A { virtual ~B() { cout << "~B" << endl; } static void operator delete(void* ptr) { cout << "B::operator delete" << endl; ::operator delete(ptr); } }; 替换为delete x,默认情况下它等效于deleteWrapper(x),但是我可以添加额外的工具并专门化必要时,将其用于某些类型的delete x

我以为可以做到这一点:

x

但是(除了调用未定义的行为之外),这不等于template <typename T> void deleteWrapper(T* x) { x->~T(); // The deallocation behavior here should "tweakable" for certain types // of T, for example I might need different implementations for // std::pair<int, int> and std::pair<std::string, int> x->operator delete(x); } :在上述类型层次结构中,delete x调用deleteWrapper(static_cast<A*>(new B))而不是A::operator delete。在不使用B::operator delete的情况下,是否可以通过给定多态指针来调用正确的重载?

如果存在涉及一定数量的源代码重写的解决方案,由于我已经在使用经过修改的clang,因此我也很想听听它。

0 个答案:

没有答案