使用派生的右值引用初始化基
Initializing base with rvalue reference of derived
在下面的代码中:
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 的移动构造函数而不调用 B 的移动构造函数?这里到底发生了什么?
Why is the move constructor of A called but not that of B?
因为您正在构造一个 A
,所以只会考虑 A
的构造函数。特别是,func()
返回的临时B
可以绑定到A&&
,然后使用A
的移动构造函数构造a
;换句话说,a
是从临时 B
.
中切出的
Why isn't the move elided?
Copy elision 在这种情况下是不允许的,a
必须从临时 B
.
构造
First, if T
is a class type and the initializer is a prvalue expression whose cv-unqualified type is the same class as T
, the initializer expression itself, rather than a temporary materialized from it, is used to initialize the destination object: see copy elision
func()
returns 一个 B
,与 A
完全不是同一类型。
在下面的代码中:
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 的移动构造函数而不调用 B 的移动构造函数?这里到底发生了什么?
Why is the move constructor of A called but not that of B?
因为您正在构造一个 A
,所以只会考虑 A
的构造函数。特别是,func()
返回的临时B
可以绑定到A&&
,然后使用A
的移动构造函数构造a
;换句话说,a
是从临时 B
.
Why isn't the move elided?
Copy elision 在这种情况下是不允许的,a
必须从临时 B
.
First, if
T
is a class type and the initializer is a prvalue expression whose cv-unqualified type is the same class asT
, the initializer expression itself, rather than a temporary materialized from it, is used to initialize the destination object: see copy elision
func()
returns 一个 B
,与 A
完全不是同一类型。