用另一个对象重用对象的空间

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (3)

我希望从这个指针重用基类中的已分配空间,并且C ++ Standart不同意。但是,该标准的措辞似乎是错误的。它提出了一个条件“并且在对象占用的存储空间被重用或释放之前”,但它显然在它们自己的代码片段中被重用。哪里弄错了?

void B::mutate() {
  new (this) D2;    // reuses storage — ends the lifetime of *this!! REUSED AS WELL SO CONDITION SO RESTRICTIONS DON'T HOLD ANYMORE!
  f();              // undefined behavior

在对象的生命周期开始之前,但是在对象将占用的存储之后已经分配了41,或者在对象的生命周期结束之后,在对象占用的存储被重用或释放之前,任何表示对象的地址的指针可以使用对象将位于或位于的存储位置,但仅限于有限的方式。对于正在构建或销毁的对象,请参阅[class.cdtor]。否则,这样的指针指的是已分配的存储([basic.stc.dynamic.deallocation]),并且使用指针就像指针的类型为void *一样,是明确定义的。允许通过这样的指针的间接,但是得到的左值可以仅以有限的方式使用,如下所述。如果出现以下情况,该程 (6.1)对象将是或具有非平凡析构函数的类类型,并且指针用作delete-expression的操作数, (6.2)指针用于访问非静态数据成员或调用对象的非静态成员函数,或 (6.3)指针被隐式转换([conv.ptr])到指向虚拟基类的指针,或 (6.4)指针用作static_cast的操作数,除非转换是指向cv void的指针,或指向cv void的指针,随后指向cv char,cv unsigned char或cv std :: byte([cstddef.syn]),或 (6.5)指针用作dynamic_cast的操作数。 [例如: #include <cstdlib> struct B { virtual void f(); void mutate(); virtual ~B(); }; struct D1 : B { void f(); }; struct D2 : B { void f(); }; **void B::mutate() { new (this) D2; // reuses storage — ends the lifetime of *this f(); // undefined behavior** ... = this; // OK, this points to valid memory } void g() { void* p = std::malloc(sizeof(D1) + sizeof(D2)); B* pb = new (p) D1; pb->mutate(); *pb; // OK: pb points to valid memory void* q = pb; // OK: pb points to valid memory pb->f(); // undefined behavior, lifetime of *pb has ended }

提问于
用户回答回答于

当你这样做

f();

在一个成员函数中,你真正在做的是

this->f();

所以在他们这样做的例子中

new (this) D2; 

它结束了事物指针的生命周期,thisD2在它的位置创建了一个新的。这让你认为这this->f();是可以的,因为this现在指向一个已经开始生命的对象,但是你忘记了这this是一个指向一个已经终止它的对象的指针。您不能使用它来引用您创建的新对象。

为了能够f()合法地调用您需要做的是捕获返回的指针new并使用它来访问新对象

void B::mutate() {
  auto np = new (this) D2;    // reuses storage — ends the lifetime of *this
  f();              // undefined behavior**
  np->f()           // OK, np points to a valid object
  ... = this;       // OK, this points to valid memory
}

热门问答

无服务器云函数可以通过api直接接收formdata的图片吗?

Mason-Serverless

腾讯 · 产品经理 (已认证)

推荐
通过网关上传前,需要先自己做base64 encode,然后在event里直接读body,转成文件。 控制台上有demo参考:图片转文字 local_path = u'/tmp/{}'.format(file_name) with open(local_path, 'w...... 展开详请

MySQL还要另外购买吗?

蒋小爱

腾讯云 · 技术支持 (已认证)

推荐已采纳
您好,您可在服务器中自建MySQL ,同时腾讯云提供数据库 MySQL(TencentDB for MySQL)让用户可以轻松在云端部署、使用 MySQL 数据库。MySQL 是世界上最流行的开源关系数据库,通过云数据库 MySQL,您在几分钟内即可部署可扩展的 MySQL ...... 展开详请

腾讯一句话语音识别为什么识别不了微信公众号临时下载的语音?

腾讯云智能语音服务员

腾讯 · 社区FAQ (已认证)

推荐

如果只是单纯的转换后缀,那么仍然还是没办法识别的,需要用特定的工具转化为正常的wav类型音频。识别结果为空有可能是采样率不匹配,目前一句话识别只支持8k和16k的采样率的音频识别。

实时语音识别支持c#平台吗?

支持的。虽然SDK没有C#的,但是可以通过API进行请求

腾讯云日志服务,如何多人查看日志?

何小路焊过板子,搬过砖,想不开,转行做了产品汪
推荐

智能钛 tensorflow如何升级?

腾讯智能钛AI开发者

腾讯云 · 智能钛产品团队 (已认证)

腾讯智能钛产品团队官方运营账号。分享产品最新动态,第一时间解答用户疑问。
推荐
可以升级的,方法示例如下: import os os.system("pip install tensorflow-gpu==1.12") import tensorflow as tf print(tf.__version__) image.png ... 展开详请

所属标签

扫码关注云+社区

领取腾讯云代金券