首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >由另一个对象重用对象的空间

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

Stack Overflow用户
提问于 2019-07-11 02:57:15
回答 2查看 118关注 0票数 3

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

代码语言:javascript
复制
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

在对象的寿命已经开始之前但是在对象将占用的存储已经被释放(

)之后,或者在对象的寿命已经结束之后并且在对象占用的存储被重新使用或释放之前,可以使用表示对象将要或曾经位于的存储位置的地址的任何指针,但仅限于有限的方式。对于正在构造或正在销毁的对象,请参见class.cdtor。否则,这样的指针引用分配的存储(basic.stc.dynamic.deallocation),并且使用该指针就好像该指针是空*类型一样,是定义良好的。通过这样的指针进行间接定向是允许的,但是所得到的左值只能以有限的方式使用,如下所述。在以下情况下,程序具有未定义的行为:

(6.1)对象将是或曾经是具有非平凡析构函数的类类型,并且指针用作删除表达式的操作数,

(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 struct B{虚空f();空变异();虚~B();};结构体D1 :B{ void f();};结构体D2 :B{ void f();};结构相关部分开始*/ void B::/* (){ new (this) D2;//重用存储-结束*this f()的生命周期;//未定义的行为/*相关部分结束*/ ... =这;// OK,这指向有效的内存} void g() { void* p= std::malloc(sizeof(D1) + sizeof(D2));B* pb =/* (p) D1;pb->mutate();*pb;// OK: pb指向有效内存void* q= pb;// OK: pb指向有效内存pb->f();//未定义行为,*pb的生命周期已结束}

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-07-11 03:14:13

,但它显然在自己的代码片段中被重用了。

new ( this ) D2;//重用存储-结束*this f();//未定义的行为** ... = this;//确定,这指向有效内存

对,是这样。因为存储空间已经被重用,所以“否则”子句适用:

...否则,这样的指针引用分配的存储(basic.stc.dynamic.deallocation),并且使用该指针就好像该指针是空*类型一样,是定义良好的。

不能通过void*调用f(),因此该子句不允许这样做。否则,调用生命周期已结束的对象的成员函数是未定义的(在析构函数之外)。

另一方面,... = this;是可以通过void*完成的事情。

注意,(new (this) D2)->f()应该是定义良好的。

票数 2
EN

Stack Overflow用户

发布于 2019-07-11 03:15:34

当你这样做的时候

代码语言:javascript
复制
f();

在成员函数中,您真正要做的是

代码语言:javascript
复制
this->f();

所以在这个例子中,当他们这样做时

代码语言:javascript
复制
new (this) D2; 

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

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

代码语言:javascript
复制
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
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56977042

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档