我有一个简单的类,它包含一个std::向量,在按值返回类时,我希望从move语义(而不是RVO)中获益。
我以以下方式实现了移动构造函数、复制构造函数和复制赋值操作符:
class A
{
public:
// MOVE-constructor.
A(A&& other) :
data(std::move(other.data))
{
}
// COPY-constructor.
A(const A& other) :
data(other.data)
{
}
// COPY-ASSIGNMENT operator.
A& operator= (const A& other);
{
if(this != &other)
{
data = other.data;
}
return *this;
}
private:
std::vector<int> data;
};上述实现是否正确?
还有另一个问题:我是否必须实现这些成员中的任何一个,或者它们是由编译器自动生成的?我知道复制构造函数和复制赋值操作符是默认生成的,但是编译器也能自动生成移动构造函数吗?(我用MSVC和GCC编写了这个代码。)
谢谢您的建议。(我知道,已经有一些类似的问题,但对于这个确切的情况,不是这样的。)
发布于 2013-01-08 11:22:18
对于这个类来说,它们都是不必要的*,因为如果您没有声明其中的任何一个,它们就会有隐式的。
你的建筑工人很好。因此,下面的代码表面上调用了移动构造函数:
A f() { return A(); }
A a = f(); // move construct (not copy construct) from the return value of f实际上,移动省略可能会起作用,在这种情况下,实际上只调用无args构造函数。我假设您计划提供一些构造函数,而不是复制和移动;-)
您的副本分配很好,它与隐式分配的不同之处在于它具有自赋值检查,而隐式赋值检查则不会。我认为我们不应该争论是否值得进行自我分配检查,这并不是不正确的。
你还没有定义移动赋值操作符。考虑到您定义了其他内容,您应该这样做,但是如果您去掉了其余部分,则它是隐式的*。移动赋值运算符(无论是用户定义的还是隐式的)确保了以下代码将移动而不是复制:
A a;
a = f();*在一个已完成的C++11实现上,到目前为止还没有。您可以在每个编译器的基础上检查这个特性是否已经实现,并且可能会出现一些可怕的#define恶作剧,直到MSVC实现为止。
发布于 2013-01-08 10:16:18
对于这种情况,您不需要声明任何移动/复制/赋值函数。编译器将生成正确的默认值。
https://stackoverflow.com/questions/14212508
复制相似问题