右值引用和局部变量的移动

问题描述 投票:2回答:1

在此代码段中,我分配了一个本地对象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

任何人都可以向我解释发生了什么事?

c++ move rvalue-reference
1个回答
0
投票

我仍然应该能够检索完整的B对象。

如果控件不是到达bar的右括号的那一刻,它就不存在了。您在C中保留了一个引用,并且对临时对象的引用很快就会变得悬而未决。

快速解决方案是将C的成员声明简单地更改为A a;

© www.soinside.com 2019 - 2024. All rights reserved.