C++ 使用“在freestore中构造对象”;新的类类型(std::move(/*class_object*/)”;

C++ 使用“在freestore中构造对象”;新的类类型(std::move(/*class_object*/)”;,c++,c++11,new-operator,move-semantics,move-constructor,C++,C++11,New Operator,Move Semantics,Move Constructor,初学者问题: Class Quote { public: /* ..... */ virtual Quote* clone() const & {return new Quote(*this);} virtual Quote* clone() && {return new Quote(std::move(*this));} // (***) /* ..... */ } new分配的对象在免费存储中*这是调用clone()的任

初学者问题:

Class Quote {
    public:
    /* ..... */

    virtual Quote* clone() const & {return new Quote(*this);}

    virtual Quote* clone() && {return new Quote(std::move(*this));} // (***)

    /* ..... */
}
new分配的对象在免费存储中*这是调用clone()的任何对象,不一定是动态分配的对象

如果从和移动到的对象位于不同的内存区域中,移动机制如何工作?或者也许他们从来没有真正在不同的领域,我错过了什么

据我所知,move构造函数创建新的开销,链接到moved From对象的数据/内存部分。数据本身不会移动/更改。在上述情况下,这是如何工作的?如果它以同样的方式工作,那么在运行new之后,我们是否会有一个动态分配的对象位于免费存储区之外(无论*这个位于何处?)这是通过std::move()以某种方式解决的吗?我不太清楚std::move()如何/为什么工作,除了它强制返回一个对命名对象的右值引用,使其能够从该对象移动之外

据我所知,move构造函数会产生新的开销 指向已从对象移动的数据/内存部分的链接。数据 本身没有移动/更改

不是真的。一个典型的移动构造函数(我强调的是典型的,因为移动构造函数真的可以做类编写器希望它做的任何事情)将通过重新分配句柄(例如指向动态分配数组的指针)来“窃取”另一个对象远程拥有的资源(例如,动态分配数组)

当我说资源是远程拥有的时,我的意思是它实际上不是类的数据成员。然而,句柄是类的数据成员。句柄指的是资源。移动到对象和移动自对象有不同的地址和数据成员。它们的数据能够被有效地移动,因为它实际上不是它是类的一部分,由句柄引用。与资源不同,句柄小,复制成本低。“移动”实际上是将句柄从源对象复制到目标对象,然后使源对象中的句柄为空,以便其析构函数不会破坏资源

如果从移动到和移动到,移动机制如何工作 对象在不同的内存区域

(我再次提到的是一个典型的移动构造函数)这是不相关的。无论它们存储在哪里,它们仍然具有相同的内存布局。句柄被修改得完全相同。当调用moved to对象的析构函数时,资源将被释放(除非该对象也从中移动)。这意味着当对象超出范围时(如果它在堆栈上),或者当对指向它的指针调用
delete
时(如果它在空闲存储上)(还有其他可能性,但这两种可能性显然是最常见的)移动并不能移动所有内容。例如,内置数据类型(如int和指针)不能移动,只能复制。移动是纯语义的。最好的例子是
std::vector
std::string
。两者通常都包含指向某些动态分配内存和其他变量的指针。内存语义称为实际上属于
vector
对象,意味着它必须释放内存,它可能会改变其内容,它对它有控制权,是唯一可以释放内存的对象。常用术语是“code>vector拥有分配内存的所有权”。
现在,当你复制一个向量时,原始向量将保留该所有权,而副本将不得不分配它自己的内存。相反,当你移动一个向量时,移动构造的新向量被允许窃取分配的内存,一旦原始向量存在,就接管资源的所有权。这是可以做到的,因为原始向量tor无论如何都将超出范围,它不再需要该资源。
但是,移动的
向量的实际数据成员本身不会移动。因为它们是指针,也可能是int,所以只能复制它们。完成后,原始中的指针和int会以某种方式发生更改,从而在语义上终止其对已分配内存的所有权


简而言之:移动是一个语义问题,在较低的技术级别上,它主要是一个副本,并将原始设置为零。

这个示例不会编译,我认为您试图在无法调用c++11 magic的地方调用它。移动语义实际上是“移动”,所以你的克隆函数如果应该克隆,就必须复制对象。@dornhege我实际上也在想同样的事情。代码来自我正在阅读的一本书(c++primer第5版,chp 15.8)。如果你这样说,那么是的,拥有一个不克隆东西的克隆函数是没有意义的,但是idk。对于一个不拥有远程资源的类,移动构造函数通常与复制构造函数相同,或者移动构造函数被删除,而复制构造函数用于r值。这是否回答了问题你开始问,但被删除了?谢谢。这是我的想法,但无法用语言表达。我想知道,严格地说,在上面的例子中,如果类不管理动态内存,那么使用move构造函数就没有意义了,因为新类的构造方式与使用copy构造函数时的构造方式类似。这就清楚了。再次感谢您的时间和回答。