在(虚拟)parent class 中的新位置

placement new in a (virtual) parent class

我有这个 CRTP:

template <class T>
struct S {
  void clear() { new (this) T; }
};

class SS : public S<SS> {
  int i = 5;
};

int main() {
  SS s;
  s.clear();
}

clear()是否保证按预期工作? S 是否为虚拟是否重要?

就此而言,我们可以假设所有继承 S 的 类 除了基本类型或 POD 类型之外没有任何其他类型,因此没有花哨的构造函数和析构函数。

我用 gcc 编译,valgrind 似乎没有抱怨,但感觉很奇怪。

要在内存中的正确位置重新创建子类型,您必须转换 this 指针。

此外,如果您不调用析构函数,则必须断言该类型是可平凡破坏的:

template <class T>
struct S {
    void clear() {
        static_assert(std::is_base_of_v<S, T>);
        static_assert(std::is_trivially_destructible_v<T>);
        new (static_cast<T*>(this)) T;
    }
};

Valgrind 没有发出任何警告,因为来自基础的 this 与派生的 class 相同,您没有覆盖分配的任何内存。

除了 static_cast<T*>(this),我还建议先在对象上调用 dtor。

template <class T>
struct S {
    void clear() {
        auto this_ptr = static_cast<T*>(this)
        this_ptr->~T();
        new (this_ptr) T();
    }
};