下面是A类,它充满了不同类型的构造函数。 如果我对移动构造函数进行注释,则复制构造函数被调用两次:一次是通过值传递一个对象来实现函数的乐趣,另一次是从同一个函数返回。
代码段
A级{
int x;
public :
A() {
cout<<"Default Constructor\n";
}
A(A&& a) : x(a.x){
cout<<"Move Constructor\n";
a.x=0;
}
A(const A& a){
x=a.x;
cout<<"Copy Constructor\n";
}
A fun(A a){
return a;
}
};
int main(){
A a;
A b;
A c;
c=a.fun(b);
}
输出:
Default Constructor
Default Constructor
Default Constructor
Copy Constructor
Move Constructor
但是,如果存在移动构造函数,则调用它而不是复制构造函数。任何人都可以用一个很好的例子来阐述这一点,这样我就可以清楚这个概念。
感谢您的帮助。谢谢。
答案 0 :(得分:8)
该标准允许特殊情况用于return
语句中的表达式是自动持续时间变量的情况。在这种情况下,选择构造函数重载,就像return
中的表达式是rvalue
一样。
更准确地说,如果return
语句中的表达式是一个自动持续时间变量,它有资格进行复制省略,或者如果你忽略了它是一个函数参数的事实,那么,编译器为了超载分辨的目的,需要将其视为右值。请注意,在C ++ 11中,return
语句的表达式需要将cv-unqualified类型作为函数返回类型。这在C ++ 14中有所放松。
例如,在C ++ 11中,以下代码调用A
的复制构造函数,而不是移动构造函数:
class A
{
};
class B
{
public:
B(A a) : a(std::move(a)){}
A a;
};
B f(A a)
{
return a;///When this is implicitly converted to `B` by calling the constructor `B(a)`, the copy constructor will be invoked in C++11. This behaviour has been fixed in C++14.
}
答案 1 :(得分:4)
在函数A fun(A a)中传入的“副本”A基本上是一个临时变量。如果没有移动构造函数,则返回值是副本(即复制构造函数)。
如果有一个移动构造函数,那么编译器可以在临时变量“A a”上执行更有效的“移动”系统化。