请考虑以下代码:
#include <iostream>
#define P_(x) std::cout << x << std::endl
class B {
public:
B() { P_("B::B()"); }
B(const B&) { P_("B::B(const B&)"); }
B(B&&) { P_("B::B(B&&)"); }
~B() { P_("B::~B()"); }
B& operator=(const B&) { P_("B::op=(const B&)"); return *this; }
B& operator=(B&& b) { P_("B::op=(B&&)"); return *this; }
};
class Foo {
public:
void setB(const B& b) { mB = b; }
private:
B mB;
};
B genB() {
return B();
}
int main() {
Foo f;
f.setB(genB());
}
假设B
是一种难以复制构造的类型。我想生成一些B
(使用函数genB
)并将其存储在Foo
中。由于genB
返回临时结果,我希望可以使用移动构造函数。
但是,当我运行代码时,我得到了这个输出:
B::B()
B::B()
B::op=(const B&)
B::~B()
B::~B()
这清楚地表明两个B被创建和销毁,但第二个是副本,而不是第一个。
尽可能使用移动构造函数的最佳方法是什么?
B&
和B&&
答案 0 :(得分:3)
您可以重载setB
函数:
class Foo {
public:
void setB(const B& b) { mB = b; }
void setB(B&& b) { mB = std::move(b); }
private:
B mB;
};
或者,您可以使用“按值传递”方式:
class Foo {
public:
void setB(B b) { mB = std::move(b); }
private:
B mB;
};
此处,参数b
将在可能时移动构造或以其他方式复制构造。
答案 1 :(得分:0)
第一个B
实例是在创建Foo
实例时创建的实例:
Foo f;
这是因为您的Foo
班级有一个名为B
的{{1}}成员。
第二个mB
实例是B
调用创建的实例。
由于您在genB()
函数中执行的赋值:
Foo::setB
没有机会使用副本或移动构造函数。