C++ 在“this”上为普通对象调用placement new安全吗?

C++ 在“this”上为普通对象调用placement new安全吗?,c++,placement-new,C++,Placement New,我知道这个问题已经被问了好几次了,但我找不到这个特定案例的答案 假设我有一个普通类,它不拥有任何资源,并且有空的析构函数和默认构造函数。它有几个成员变量,带有类内初始化;其中没有一个是const 我想重新初始化这个类的对象,而不用手工编写deInit方法。这样做安全吗 void A::deInit() { 新(本)A{}; } 我看不出它有任何问题-对象始终处于有效状态,此仍然指向同一地址;但它是C++,所以我想确定。< P>类似于的合法性。删除这个< /C> >,按照我所知,也允许新的 >

我知道这个问题已经被问了好几次了,但我找不到这个特定案例的答案

假设我有一个普通类,它不拥有任何资源,并且有空的析构函数和默认构造函数。它有几个成员变量,带有类内初始化;其中没有一个是
const

我想重新初始化这个类的对象,而不用手工编写
deInit
方法。这样做安全吗

void A::deInit()
{
新(本)A{};
}

我看不出它有任何问题-对象始终处于有效状态,
仍然指向同一地址;但它是C++,所以我想确定。

< P>类似于<代码>的合法性。删除这个< /C> >,按照我所知,也允许新的<代码> > < <代码> >。此外,关于以后是否可以使用
,或其他预先存在的指针/引用,有一些限制:

[基本生活]

如果在对象的生命周期结束后,在重用或释放对象占用的存储之前,在原始对象占用的存储位置创建了一个新对象,一个指向原始对象的指针,一个引用原始对象的引用,或者,原始对象的名称将自动引用新对象,并且在新对象的生存期开始后,可用于操纵新对象,如果:

  • 新对象的存储正好覆盖原始对象占用的存储位置,并且
  • 新对象与原始对象的类型相同(忽略顶级cv限定符),并且
  • 原始对象的类型不是const限定的,如果是类类型,则不包含任何类型为的非静态数据成员 常量限定或引用类型,以及
  • 原始对象和新对象都不是可能重叠的子对象([intro.object])
在本例中,前两个是满意的,但后两个需要考虑

关于第三点,假设函数是非常量限定的,那么假设原始对象是非常量应该是相当安全的。如果康斯特内斯已被抛弃,则故障在呼叫方。关于常量/引用成员,我认为可以通过断言这是可分配的来检查:

static_assert(std::is_trivial_v<A> && std::is_copy_assignable_v<A>);
static_assert(std::is_private_v&&std::is_copy_assignable_v);
当然,由于可分配性是一项要求,您可以简单地使用
*this={}我希望生成相同的程序。一个可能更有趣的用例可能是将
*this
的内存重新用于另一种类型的对象(这将不符合使用
this
的要求,至少不需要重新解释)


删除此
类似,此
的新位置很难被描述为“安全”。

包含此内容的规则在

程序可以通过重用对象占用的存储或显式调用类类型对象的析构函数来结束任何对象的生存期。对于类类型的对象,在重用或释放该对象占用的存储之前,程序不需要显式调用析构函数;但是,如果没有显式调用析构函数,或者如果没有使用删除表达式来释放存储,则不会隐式调用析构函数,并且依赖析构函数产生的副作用的任何程序都具有未定义的行为

如果在对象的生命周期结束后,在重用或释放对象占用的存储之前,在原始对象占用的存储位置创建了一个新对象,一个指向原始对象的指针,一个引用原始对象的引用,或者,原始对象的名称将自动引用新对象,并且在新对象的生存期开始后,可用于操纵新对象,如果:

  • 新对象的存储正好覆盖原始对象占用的存储位置,并且

  • 新对象与原始对象的类型相同(忽略顶级cv限定符),并且

  • 原始对象的类型不是常量限定的,如果是类类型,则不包含任何类型为常量限定的非静态数据成员或引用类型,以及

  • 原始对象和新对象都不是可能重叠的子对象([intro.object])


因为你的对象很琐碎,你不必担心[basic.life]/5,只要你满足[basic.life]/8中的要点,那么它是安全的。

对象常量有成员吗?如果这是有效的,它是否等同于
*this=A{}?@Amomum
*这=A{}
表示,
this->operator=(A{}),即创建一个临时对象并将其分配给
*this
,用临时对象的值替换所有数据成员的值。因为这是你想要的,而且(在我看来)比一个新的位置更具可读性,所以我会选择它。@Kevin哦,我的错,你是对的。Than-我认为如果省略了copy应该是相等的?与其用文字解释这个类,不如编写完整的类,而不仅仅是一种方法。看有趣的。是否有可能通过对某些类型特征的静态断言来确保所有这些条件都得到满足?不确定是否有关于const成员的内容…@Amomum我不认为成为子对象是可以测试的。const或reference成员将使类不可赋值,我认为对于一个平凡的类,这是不可能发生的。这是否意味着严格的别名