You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++标准是否允许用placement new将this替换为其他类型对象?

关于placement new替换this指向对象的C++标准合规性

首先直接给结论:在满足特定前提条件的情况下,你示例中的操作是符合C++标准的,下面我会拆解细节和需要注意的边界:

核心规则依据

C++标准中关于对象生命周期的规则明确允许:在一个已存在对象的存储位置上,通过placement new构造另一个对象,只要满足以下要求:

  • 新对象的存储大小不超过原对象占据的内存大小(你的示例里用static_assert(sizeof(A) == sizeof(Derived))保证了这一点)
  • 新对象的对齐要求不超过原内存的对齐能力(示例里没显式检查,但如果Derived的对齐需求比A严格,即使大小相等也会是未定义行为)
  • 原对象的类型不是const-qualified、volatile-qualified的,也不是引用类型(示例里的A是普通非const类,符合要求)

当你执行new(this) Derived时,原A对象的生命周期会立即终止,新的Derived对象在同一块内存上开始生命周期——这完全符合标准规定。

关于this指针的后续使用

在placement new执行后,原this指针(类型为A*)现在指向的是一个Derived对象,这也是合法的:因为Derived是A的公有派生类(假设是公有继承,示例里没写但通常是这类场景),派生类对象可以被基类指针合法指向。

不过要注意:如果foo函数在placement new之后还有代码,那后续使用this时,访问的其实是新的Derived对象的成员。比如如果Derived重写了其他虚函数,此时调用那些函数会触发Derived的实现——这也是编译器无法对这类虚函数调用做去虚拟化优化的核心原因:编译器无法预判在虚函数执行过程中,对象的动态类型是否会被替换。

需要警惕的未定义行为场景

如果违反以下任一条件,你的代码就会触发未定义行为:

  • Derived的大小超过A的大小(示例里的static_assert已经避免了这一点)
  • Derived的对齐要求比A更严格(比如A是按4字节对齐,Derived因为有某个成员要求8字节对齐)
  • 原A对象是const类型(比如const A对象,你不能在其内存上构造新对象)
  • 继承是非公有的(此时基类指针A*无法合法指向私有/保护派生的Derived对象)

内容的提问来源于stack exchange,提问作者king_nak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:12:44