让我们采用以下 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/