C++11:移动操作会更改地址吗?

问题描述 投票:0回答:3

假设我有一个主类

SomeManager
用于跟踪另一个类
SomeClass
的实例。当
SomeClass
被构造时,它调用
SomeManager
的方法,将指针传递给自身。然后
SomeManager
获取该指针并将其推入向量中。
SomeClass
的析构函数调用
SomeManager
的另一个函数,该函数从向量中删除其指针。

所以,我的问题是。当

SomeClass
的实例通过移动运算符或构造函数移动时。它的地址是否发生变化,我必须删除旧地址并添加新地址?

我从读过的内容中对此有一些想法,但我不确定,我不想把事情搞砸。

c++ pointers c++11 move-semantics memory-address
3个回答
26
投票

简短的回答:不,移出对象的地址不会改变。 但旧对象可能不是有用的状态。

当您执行移动构造时,您正在创建一个新对象并将另一个对象的内容移动到新对象中。 新对象将始终在与旧对象不同的内存位置中构造。 移动赋值也会发生类似的情况:您只需将一个对象的内容移动到另一个对象,但仍然必须在两个不同的内存位置有两个不同的对象才能执行赋值(好吧,有自赋值,但我们将忽略它) 。 旧对象仍然存在(好吧,它可能是一个临时对象,在语句结束时被销毁),但很多时候你无法保证旧对象,除了它处于某种有效状态。

可以比喻为一间装满家具的房子。 搬迁施工就像建造一座新房子并将家具搬到里面。 搬家分配就像购买第二套现有房屋并将家具搬到其中。 在这两种情况下,新房子的地址与旧房子的地址不同,但旧房子仍然存在。 它可能只是没有处于有用的状态(很难住在没有家具的房子里!)。


3
投票

是的。 移动构造函数和赋值运算符帮助

SomeClass
的新实例取得旧实例状态的所有权,但新实例具有不同的地址。

您需要考虑的一个问题是,您是否希望从

SomeClass
实例中删除自身,因为它已从
SomeManager
中移出,还是等待销毁 - 这是否重要取决于您的确切代码。


3
投票

移动构造本质上意味着“这是一个对象X。通过窃取X的内部结构来创建一个新对象Y。”与移动分配类似。你不移动物体;你移动它的内容。

移出对象 X 的地址保持不变。它的内容可能会改变(例如,变空),也可能不会改变(例如,如果它是一个基本类型,而移动是其副本)。

尽管在您描述的方案中,您最好确保移动构造函数也注册它创建的对象...

© www.soinside.com 2019 - 2024. All rights reserved.