C++ 使用派生的右值引用初始化基
在以下代码中:C++ 使用派生的右值引用初始化基,c++,class,inheritance,constructor,move-semantics,C++,Class,Inheritance,Constructor,Move Semantics,在以下代码中: 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() {
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的移动构造函数?这里到底发生了什么
为什么调用了A的移动构造函数而没有调用B的移动构造函数
因为您正在构造一个A
,所以只会考虑A
的构造函数。特别地,由func()
返回的临时B
可以绑定到A&
,然后使用A
的移动构造函数来构造A
;在另一个单词中,a
从临时B
中切片
为什么这一举措没有被省略
在这种情况下是不允许的,a
必须从临时B
构造
首先,如果T
是一个类类型,并且初始值设定项是一个prvalue表达式,其cv非限定类型与T
是同一个类,则初始值设定项表达式本身,而不是它的临时物化,用于初始化目标对象:请参阅
func()
返回一个B
,该类型与a
的类型不同。当临时B
被销毁时,为什么对B
的析构函数调用发生在a
之前?@0x499602D2,首先调用B
的析构函数,然后调用它的基类,即A
的析构函数。如果一个对象被移动,为什么会被析构函数两次?@wispi第一次发生在临时B
被销毁时,其中包括B
的析构函数和A
的析构函数的发票。即使临时B
被移动,它仍然需要被描述。第二种情况发生在a
被销毁时。