【问题标题】:Is it possible use an rvalue to initialize a data member?是否可以使用右值来初始化数据成员?
【发布时间】:2020-06-14 09:59:24
【问题描述】:

我对 r-value 引用和移动语义非常陌生,但我读过的教程有这样的态度“既然临时是一个构造完美的对象,通常会被复制和销毁,为什么不延长它的生命周期并移动它周围?”

所以我正在想象这样一个场景:

class Foo
{
  Foo m_foo; // Could also be a reference or a unique_ptr of any sort
public:
  Foo() {}
  Foo(Foo &&v_foo) { /*initialize m_foo using v_foo.*/ }

};

int main() 
{
  auto foo = std::make_unique<Foo>( Foo() );
  return 1;
}

这样的事情可能吗?

更新:为了澄清,当我说“使用 v_foo 初始化 m_foo”时,我的意思是我想让 m_foo 指向或引用 v_foo 对象(临时创建的主要)。不要复制/移动它的字段,而是让它成为成员。

【问题讨论】:

  • 我想让 m_foo 指向或引用 v_foo 对象 --> 拥有指向临时对象的指针或引用很危险,不是吗?

标签: c++ c++14 unique-ptr move-semantics rvalue-reference


【解决方案1】:

您不能在类Foo 中保留Foo 类型的数据成员,因为该对象将无限大(因为Foo 类型的每个对象内部都会有另一个Foo 对象,该内部对象将具有里面还有一个Foo 对象,以此类推。

通过此更改,您可以拥有如下内容:

class Foo
{
   std::unique_ptr<Foo> m_foo; 
public:
   Foo() {}
   Foo(Foo &&v_foo) 
   { 
      m_foo = std::move(v_foo.m_foo); 
      v_foo.m_foo = nullptr;
   }

};

int main()
{
   auto foo = std::make_unique<Foo>(Foo());
   return 0;
}

【讨论】:

  • 我知道移动构造函数通常是什么样子的,我希望在主变成 m_foo中创建临时,而不是移动它的内容。
  • @NikosTsakas 你说的是什么意思:“在 main 中创建的临时变成 m_foo”?一般来说,如果你想让一个对象 o1 变成对象 o2,你应该把 o2 复制到 o1 或者移动它。
  • 在本例中,如果我调用声明为“auto foo”foo1 的对象,而 temporary 创建为“Foo()”foo2:则 foo2 的生命周期为扩展,因为它作为右值引用传递。是否可以让 m_foo 指向或引用同一个临时 foo2 以在 foo1 对象的整个生命周期内延长其生命周期而无需任何复制或移动?
  • 没有。函数参数无法延长用作其函数参数的临时变量的生命周期,即使您确实知道或假设它最初是临时变量。
  • 请注意,此示例代码导致 foo-&gt;m_foo 包含一个空指针。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多