【问题标题】:Move constructor and pre-increment vs post-increment移动构造函数和前增量与后增量
【发布时间】:2013-05-04 05:28:58
【问题描述】:

在 C++ 中,如果您有一个使用移动构造函数“复制” 用户定义类型的对象的 for 循环,那么使用 ++ii++ 作为循环计数器?

我知道这个问题似乎相当模糊,但我(我相信)在电话采访中被问到这个问题。我不确定我是否正确理解了这个问题,面试官认为这是我不知道答案,因此缩短了面试时间。

他到底想干什么?

【问题讨论】:

标签: c++ constructor move


【解决方案1】:

在 C++ 中,如果您有一个使用移动构造函数“复制”用户定义类型的对象的 for 循环 [...]

首先,移动构造函数用于移动构造,这通常意味着您不是“复制”:您可以将移动实现为复制-实际上是一个复制的类-可构造的也是可移动构造的——但是为什么要显式定义移动构造函数呢?

[...] 使用 ++i 或 i++ 作为循环计数器有什么不同吗?

这取决于i 是什么。如果是标量对象,比如int,那么就没有区别了。

如果i 是一个类类型的迭代器,另一方面,++i 应该更有效(在纯理论基础上),因为operator ++ 的实现将不必创建在迭代器本身递增之前返回的迭代器。

例如,这里是 stdlibc++ 如何为 std::list 的迭代器类型定义增量运算符:

_Self&
operator++()
{
    _M_node = _M_node->_M_next;
    return *this;
}

_Self
operator++(int)
{
    _Self __tmp = *this;
    _M_node = _M_node->_M_next;
    return __tmp;
}

如您所见,后缀版本(接受虚拟int)还有更多工作要做:它需要创建原始迭代器的副本以重新生成,然后更改迭代器的内部指针,然后返回副本。

另一方面,前缀版本只需要改变内部指针并返回(引用)自身。

但是,请记住,在涉及性能时,所有假设都必须有衡量的支持。在这种情况下,我不希望这两个函数之间有任何明显的区别。

【讨论】:

  • 在“复制”部分得到了它。我知道我不应该使用这个词。所以这与移动构造本身无关,对吧?它与整数与迭代器有关吗?
  • @Scott:虽然我认为 Andy 抓住了一个重要的案例,但我认为这个问题(如果你的措辞正确的话)很糟糕。
  • @Koushik:如果不知道循环中的实际内容、要从中移出的内容以及是否尝试在被移出的东西的状态...如果 rhs 是一个左值,这意味着程序员写了std::move(obj),人们应该相信他们不会在以后对obj 做不恰当的事情...
  • @NikBougalis:同意,除非面试官在提到移动构造函数时有其他意思。但是在没有实际描述循环中发生的事情的情况下,我不得不假设问题是关于 i++++i 的效率
  • @Scott:我知道当你接受采访时,很难说出来。但作为坐在桌子另一边的人,让我给你两个提示:如果我问你一个你不明白的问题,你应该要求澄清,如果你认为问题是荒谬的,您应该礼貌地这么说并解释原因。您正在接受一项需要您锻炼批判性思维并挑战您的分析能力的工作的评估。在评估期间不要关闭大脑的这些部分。
猜你喜欢
  • 2014-07-18
  • 2011-09-18
  • 2012-09-15
  • 2013-05-27
  • 2012-03-07
  • 1970-01-01
  • 2021-04-04
  • 2014-12-09
相关资源
最近更新 更多