【问题标题】:Move semantics and operator + overloading移动语义和运算符 + 重载
【发布时间】:2020-01-15 16:00:05
【问题描述】:

我得到了一个简单的 CTab 类,其中包含一维数组的指针、数组的大小和以下复制构造函数等字段:

CTab::CTab(const CTab &cOther)
{
    pi_tab = new int[cOther.i_size];
    i_size = cOther.i_size;
    for (int ii = 0; ii < cOther.i_size; ii++)
        pi_tab[ii] = cOther.pi_tab[ii];
    std::cout << "Copy ";
}

关于move语义的需求,我也写了move contrucor:

CTab::CTab(CTab && cOther)
{
    pi_tab = cOther.pi_tab;
    i_size = cOther.i_size;
    cOther.pi_tab = NULL;
    cOther.i_size = 0;
    std::cout << "MOVE ";
}

以前,我被要求重载“+”运算符,以便返回 2 个数组的串联。现在,我正在努力使用移动语义进行修改以减少制作副本的数量。我不知道先前代码的哪一部分会产生不必要的副本,如果是这样,如何更改代码以使其满足给定任务的条件。有什么想法吗?

不使用移动语义的重载运算符:

CTab CTab::operator+(const CTab cOther)
{
    CTab newTab;
    newTab.bSetSize(i_size + cOther.i_size);
    for (int i = 0; i < i_size; i++)
        newTab.pi_tab[i] = pi_tab[i];
    for (int i = i_size; i < i_size+cOther.i_size; i++)
        newTab.pi_tab[i] = cOther.pi_tab[i - i_size];
    return newTab;
}

【问题讨论】:

  • "int i = i_size; i " 那么……你想循环零次吗?
  • FWIW,如果您将pi_tab 设为std::vector&lt;int&gt;,则可以摆脱i_size,然后您无需编写任何复制或移动构造函数/赋值运算符,因为@987654328 @“做正确的事”。
  • @NicolBolas 是的,应该是 i_size+cOther.s_size,愚蠢的错误
  • @NathanOliver 我不确定是否可以修改 CTab 的当前结构。
  • 不是描述成员,而是创建一个minimal reproducible example显示我们的定义。确保它是最小的 - 只包含足以证明问题的内容,但它必须是完整的 - 通过编译很容易检查。

标签: c++ move-semantics


【解决方案1】:

您的CTab 类型无法从其参数转移到operator+ 中获得任何好处。任何+ 操作的输出都必须创建一个新的CTab,它是其参数大小的总和。这意味着为这个新对象分配新内存,而不是能够从其中一个参数中借用存储空间。

因此,您应该将const &amp; 传递给参数并继续。

【讨论】:

  • 我想OP想知道移动语义与运算符的返回值有什么关系......
  • return std::move(newTab) 不是个好主意吗?当然,您也需要更改原型中的返回值...
  • 不,(几乎)没有理由移动返回值。由于返回值优化,不会发生复制。
猜你喜欢
  • 2013-04-14
  • 1970-01-01
  • 2011-11-19
  • 2020-12-28
  • 1970-01-01
  • 2021-08-18
  • 2016-02-19
  • 2012-11-26
相关资源
最近更新 更多