在此代码段中,我分配了一个本地对象B,然后将其传递给另一个对象C的构造函数,该对象将其作为右值引用。然后,我将后者放入容器中。
当我检索C并将其成员static_cast返回B时,该值不正确(并且valgrind标识18个错误!)
#include <iostream>
#include <memory>
#include <vector>
class A {
public:
virtual ~A() {};
};
class B: public A {
public:
B(int foo) : _foo(foo) {}
int _foo;
};
class C {
public:
C(A&& a): _a(std::move(a)) {}
A&& _a;
};
std::vector<C> v;
void bar() {
v.emplace_back(B(12));
}
int main() {
bar();
C&& c = std::move(v.front());
std::cout << static_cast<B&&>(c._a)._foo << std::endl;
return 0;
}
我的理解是,由于C使用右值引用,因此不应有任何对象切片。我仍然应该能够检索完整的B对象。另外,我对std::move
的理解(很可能是有缺陷的)是,我可以将局部变量“移出”其上下文,并且通过使用右值引用,C可以拥有B的所有权。
输出是39931504
而不是12
。
任何人都可以向我解释发生了什么事?
我仍然应该能够检索完整的B对象。
如果控件不是到达bar
的右括号的那一刻,它就不存在了。您在C
中保留了一个引用,并且对临时对象的引用很快就会变得悬而未决。
快速解决方案是将C
的成员声明简单地更改为A a;
。