gpt4 book ai didi

c++ - 另一个对象重用对象的空间

转载 作者:太空狗 更新时间:2023-10-29 20:33:09 24 4
gpt4 key购买 nike

我希望通过该指针重新使用基类中分配的空间,但 C++ 标准不赞成。但是,标准的措辞似乎是错误的。它提出了一个条件“并且在对象占用的存储被重用或释放之前”,但它在他们自己的代码片段中明确重用。我在哪里弄错了?

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

Before the lifetime of an object has started but after the storage which the object will occupy has been allocated41 or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any pointer that represents the address of the storage location where the object will be or was located may be used but only in limited ways. For an object under construction or destruction, see [class.cdtor]. Otherwise, such a pointer refers to allocated storage ([basic.stc.dynamic.deallocation]), and using the pointer as if the pointer were of type void*, is well-defined. Indirection through such a pointer is permitted but the resulting lvalue may only be used in limited ways, as described below. The program has undefined behavior if:

(6.1) the object will be or was of a class type with a non-trivial destructor and the pointer is used as the operand of a delete-expression,

(6.2) the pointer is used to access a non-static data member or call a non-static member function of the object, or

(6.3) the pointer is implicitly converted ([conv.ptr]) to a pointer to a virtual base class, or

(6.4) the pointer is used as the operand of a static_­cast, except when the conversion is to pointer to cv void, or to pointer to cv void and subsequently to pointer to cv char, cv unsigned char, or cv std​::​byte ([cstddef.syn]), or

(6.5) the pointer is used as the operand of a dynamic_­cast.

[ Example:

    #include <cstdlib>
struct B {
virtual void f();
void mutate();
virtual ~B();
};

struct D1 : B { void f(); };
struct D2 : B { void f(); };

/* RELEVANT PART STARTS */ void B::mutate() {
new (this) D2; // reuses storage — ends the lifetime of *this
f(); // undefined behavior
/* RELEVANT PART ENDS */
... = 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; 

它结束了 this 指向的事物指针的生命周期,并在它的位置创建了一个新的 D2。这让你认为 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
}

关于c++ - 另一个对象重用对象的空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56977042/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com