C++ 在(虚拟)父类中放置新对象
我有这个CRTP:C++ 在(虚拟)父类中放置新对象,c++,crtp,C++,Crtp,我有这个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类型,因此没有奇特的构造函数和析构函数 我用g
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与派生类的this相同,所以您没有覆盖任何超出分配的内存。要在内存中的正确位置重新创建子类型,您必须强制转换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与派生类的this相同,您没有覆盖任何超出分配的内存。除了静态\u cast之外,我还建议首先调用对象上的dtor
template <class T>
struct S {
void clear() {
auto this_ptr = static_cast<T*>(this)
this_ptr->~T();
new (this_ptr) T();
}
};
除此之外,我还建议首先对对象调用dtor
template <class T>
struct S {
void clear() {
auto this_ptr = static_cast<T*>(this)
this_ptr->~T();
new (this_ptr) T();
}
};
很好,谢谢。静态演员阵容有什么意义?它能改变这个的实际值吗?@user2717954是的。this指针可以指向基指针或派生指针,因为它们在内存中的偏移量可能不同,具体取决于它们的内容,或者是否使用了多重继承。std::is_minally_destructible要求T的析构函数不是虚的。如果S是虚拟的,或者即使SS继承S的类是虚拟的,而S本身不是虚拟的,是否有一些解决方法t@user2717954是的,它不能是虚拟的。如果您想要一个非平凡的或虚拟的析构函数,您必须在创建新的objectNice之前使用static_castthis->~T调用它,谢谢。静态演员阵容有什么意义?它能改变这个的实际值吗?@user2717954是的。this指针可以指向基指针或派生指针,因为它们在内存中的偏移量可能不同,具体取决于它们的内容,或者是否使用了多重继承。std::is_minally_destructible要求T的析构函数不是虚的。如果S是虚拟的,或者即使SS继承S的类是虚拟的,而S本身不是虚拟的,是否有一些解决方法t@user2717954是的,它不能是虚拟的。如果您想要一个非平凡或虚拟析构函数,则必须在创建新对象之前使用static\u casthis->~T调用它