移动构造函数会将内存更改为“ this”的内存。指向?

发布于 2025-01-20 06:57:20 字数 372 浏览 3 评论 0原文

我对 C++ 移动构造函数有一些困惑。如果编译器隐式合成一个移动构造函数,这个移动构造函数会做什么?它会让“this”指向用于初始化的对象吗? 有一个例子:

struct Foo {
    int i;
    int *ptr;
};

Foo x;
Foo y(std::move(x));

隐式合成的移动构造函数会让 y 中的 this 指向 x 所在的内存吗?如果是这样,如何确保x在移动后可被破坏(如果x被破坏,y中的成员是否有效)?如果不是,y 的移动构造函数如何工作?

I have some confusions about C++ move constructor. If the compiler is implicitly synthesizing a move constructor, what will this move constructor do? Will it just make "this" point to the object that is used for initialization?
there's an example:

struct Foo {
    int i;
    int *ptr;
};

Foo x;
Foo y(std::move(x));

will the implicitly synthesized move constructor just make this in y point to the memory that x is in? If so, how to ensure that x is destructible after the move (if x is destroyed, will members in y be valid)? if not, how does the move constructor of y work?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

左岸枫 2025-01-27 06:57:20

隐式合成的移动构造函数只需在y中对x的内存进行操作?

综合移动ctor Will memberwise-move 其参数的数据成员(x在此处)创建(<代码> y 在此处)。

另外,请注意,对于int之类的内置类型,移动与复制相同。


如何确保移动后X可破坏

因为移动与复制内置类型相同,xy彼此独立。因此,当X被销毁时,y将不会受到影响。


合成的移动构造函数是否会设置ptr x to nullptr


不,综合移动CTOR不会为您做到这一点。它将正当将数据成员移动。对于内置类型,这意味着与复制相同。


如果不执行此操作,则ptr x仍将指向ptr的内存y点,那么您不能安全销毁x

在这种情况下,您需要编写用户定义的MOVE ,该MOVE 明确设置ptr x x to nullptr < /code>,因此当x被销毁时,y不影响。

will the implicitly synthesized move constructor just make this in y point to the memory that x is in?

The synthesized move ctor will memberwise-move the data members of its arguments(x here) to the object being created(y here).

Also, note that for built-in types like int, move is the same as copying.


how to ensure that x is destructible after the move

Since move is the same as copying for built in types, x and y are independent of each other. So when x is destroyed y will not be affected.


will the synthesized move constructor set the ptr of x to nullptr?

No, the synthesize move ctor will not do that for you. It will just memberwise move the data members. For built in types this means the same as copying.


if it does not do this, then the ptr of x will still point to the memory to which the ptr of y points, then you cannot safely destroy x.

In that case, you'd need to write a user-defined move ctor which explicitly sets the ptr of x to nullptr so that when x is destroyed, the y is not affected.

一萌ing 2025-01-27 06:57:20

隐式合成的移动构造函数会让 y 中的 this 指向 x 所在的内存吗?

正如 Anoop 所指出的,它将在要移动到目标成员(ythis 如果您想象自己在合成的移动构造函数“内部”)。

因此,在您的示例中:

  • int xi 将移动到 yi (this->i)
  • < code>int* x.ptr 将被移动到 y.ptr (this->ptr)。

请注意,这些特定的移动将通过复制来执行。

如何保证x移动后可被破坏(如果x被破坏,y中的成员是否有效)?

它总是可以被破坏的。至于是否“有效”,则要看情况。默认的移动结构实际上是一个副本。现在有两个对象指向 x.ptr 所指向的任何内容。如果该 intx“拥有”的资源(也许该资源是堆上以 0 结尾的整数字符串),那么您刚刚“共享”了该资源资源。

如果您不想“共享”它,那么您可以显式地为 Foo 编写一个移动构造函数,该构造函数会重置“移出”对象的指针,或者以某种方式将其标记为无效。

struct Foo {
  ...
  Foo(Foo&& other) {
    this->i = other.i;
    this->ptr = other.ptr;
    other.ptr = nullptr;
  }
}

一般来说,最好根本不要依赖“移出”的对象,即确保它们尽快被销毁。

will the implicitly synthesized move constructor just make this in y point to the memory that x is in?

As Anoop noted, it will memberwise call the move constructor on every member of the source to be moved (x) onto the members of the destination (y or this if you imagine yourself "inside" that synthesized move constructor).

So in your example:

  • the int x.i will be moved onto y.i (this->i)
  • the int* x.ptr will be moved onto y.ptr (this->ptr).

Note that these particular moves will be performed by copying.

how to ensure that x is destructible after the move (if x is destroyed, will members in y be valid)?

It's always destructible. As to if it's "valid", it depends. The default move construction was actually a copy. Two objects now point at whatever x.ptr pointed to. If that int was a resource "owned" by x (maybe the resource was a 0 terminated string of ints on the heap), then you've just "shared" that resource.

If you don't wish to "share" it then you could have explicitly written a move constructor for Foo that resets the pointer of the "moved-from" object, or somehow marks it invalid.

struct Foo {
  ...
  Foo(Foo&& other) {
    this->i = other.i;
    this->ptr = other.ptr;
    other.ptr = nullptr;
  }
}

In general, it's best not to rely on "moved from" objects at all, i.e. make sure they are destroyed as soon as possible.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文