在以下代码中:
struct A {
A() {}
A(A &&) { printf("moving A\n"); }
~A() { printf("destructing A\n"); }
};
struct B : A {
B() {}
B(B &&) { printf("moving B\n"); }
~B() { printf("destructing B\n"); }
};
B func() {
B b;
return b;
}
int main() {
A a = func();
printf("hello\n");
}
产生以下输出:
moving A
destructing B
destructing A
hello
destructing A
为什么不放弃这一举动?为什么调用A的move构造函数而不调用B的move构造函数?这里实际上发生了什么?
为什么调用A的move构造函数而不调用B的move构造函数?
由于正在构造A
,因此仅考虑A
的构造函数。特别是,由B
返回的临时func()
可以绑定到A&&
,然后使用A
的move构造函数构造a
;换句话说,a
是从临时B
中切出的。
为什么不放弃这一举动?
在这种情况下不允许使用[Copy elision,必须从临时a
构造B
。
[首先,如果
T
是类类型,并且初始化程序是cv不合格类型与T
属于同一类的prvalue表达式,则使用初始化程序表达式本身而不是从其实例化的临时表达式目标对象:请参见copy elision
[func()
返回一个B
,它与A
的类型完全不同。