【发布时间】:2021-05-04 23:23:50
【问题描述】:
我是 C++ 新手,正在尝试掌握移动语义。以下代码是我编写的准系统结构。无论如何,它都不是软件工程的最佳示例,但仅用于学习目的。它拥有一个资源,删除了复制构造函数和复制赋值运算符,定义了一个移动构造函数和一个移动赋值运算符,有一个析构函数,并且有一个应该返回原始对象的方法:
struct HasAResource
{
int* arr;
HasAResource(int size):
arr(new int [size])
{}
HasAResource(const HasAResource& other) = delete;
HasAResource& operator=(const HasAResource& other) = delete;
HasAResource(HasAResource&& other):
arr(nullptr)
{
arr = other.arr;
other.arr = nullptr;
}
HasAResource& operator=(HasAResource&& other)
{
if (this != &other)
{
delete[] arr;
arr = other.arr;
other.arr = nullptr;
}
return *this;
}
~HasAResource() { delete[] arr; }
HasAResource& doStuff()
{
return *this;
}
};
int main(int argc, char const *argv[])
{
HasAResource x = HasAResource(42).doStuff();
return 0;
}
在主函数中,我尝试构造一个对象并立即调用它的方法。我的目标是修改我构建的临时对象,然后他们将其移动到 x 而不制作任何副本(这样资源只有一个所有者)。但是,编译器给了我一个与已删除的复制构造函数相关的错误。这意味着尽管我尽了最大努力,它仍在尝试制作副本。
我的问题是:
- 这里到底发生了什么?新对象在哪里是右值或左值,为什么?
- 如果可能的话,如何修改此程序以实现所需的行为?
再一次,我的目标是了解语言在做什么,而不是最好的软件工程实践(比如使用std::unique_ptr)。
【问题讨论】:
-
HasAResource x = (expression that evaluates to HasAResource&)你希望它使用什么操作,为什么? -
好吧,我不是专家,但您似乎是通过引用新对象的构造函数来传递临时值。这意味着一个复制构造函数。您可以按值传递,即使用 rvo 或尝试使用 std::move 强制转换为右值引用。
标签: c++ constructor move-semantics