c++ - 未调用移动构造函数和复制构造函数

标签 c++

让我们采用以下 C++ 示例:

#include <iostream>

struct X
{
  std::string s;

  X() : s("X") { }

  X(const X& other) : s{other.s} { std::cout << "cpy-ctor\n"; }

  X(X&& o): s{o.s} { o.s = ""; std::cout << "move-ctor\n"; }

  X& operator=(const X& other) {
    std::cout << "cpy-assigned\n";
    s = other.s;
    return *this;
  }

  X& operator=(X&& other) {
    if (this != &other) {
      s = other.s;
      other.s = "";
    }
    std::cout << "move assigned\n";
    return *this;
  }
};

X f(X x) {
  std::cout << "f: ";
  return x;
}

X g() {
  std::cout << "g: ";
  X x;
  return x;
}

int main() {
  X x;
  X y;
  x = f(X());
  y = g();
}

如果我用 gcc 4.8.2 编译它,我得到以下结果:

f: move-ctor
move assigned
g: move assigned

我不明白为什么在调用 g 函数时没有调用复制构造函数。

我只是想了解何时调用复制或移动构造函数。

最佳答案

尽管您正确地确定在返回时从 g() 内部复制/移动了局部变量 x,但这是一个有用的C++ 的特点是它可以在许多情况下省略(即跳过)此操作,即使复制/移动会产生副作用。这是其中一个案例。执行时,这称为 named return value optimisation .

可以说它的用处不如我们拥有移动语义之前,但拥有它仍然很好。事实上,C++17 made it mandatory in some (select) cases .

关于c++ - 未调用移动构造函数和复制构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48954657/

相关文章:

iphone - Objective-C 和 C++ 中结构的大小

c++ - 如何调用具有结构的函数 (C++)

c++ - 在 C++ 中分离接口(interface)和实现

c++ - 为什么 return 会改变我的值(value)?

c++ - 与 gnu g++ 链接静态库,没有这样的文件或目录

c++ - 如何使用 range-v3 压缩 vector 的 vector

c++错误C2662无法将 'this'指针从 'const Type'转换为 'Type &'

c++ - 从可连接的线程中销毁线程的对象

c++ - 为 std::string 释放内存的异常(尝试在 UE4 中使用 YOLO/Darknet)

c++ - 扩展现有 ActiveX/COM 组件的正确方法是什么?