我正在学习 C++ 移动语义,但我无法理解下面的代码:
#include <iostream>
class A {
public:
A() { std::cout << "Default Constructor\n"; }
A(const A& other) { std::cout << "Copy Constructor\n"; }
A(A&& other) noexcept { std::cout << "Move Constructor\n"; }
// 仅仅是为了避免编译器优化而定义
A& operator=(const A& other) {
std::cout << "Copy Assignment Operator\n";
return *this;
}
A& operator=(A&& other) noexcept {
std::cout << "Move Assignment Operator\n";
return *this;
}
};
void func(A&& a) {
// Do something with 'a'
}
int main() {
A a; // 调用默认构造函数
func(std::move(a)); // 调用移动构造函数
func(A()); // 直接传递右值,调用移动构造函数
return 0;
}
输出为:
Default Constructor
Default Constructor
为什么移动构造函数没有被调用?为什么只调用两个默认构造函数?
编译器是“g++ 13.2”
void func(A&& a) { }
int main() {
A a; // default constructor
func(std::move(a)); // you are merely creating a reference that allows moving.
// Your func doesn't do anything with it, so no object is created/moved.
func(A()); // again, you create an object (default constructor), then pass it
// to func() as a reference that would allow moving.
return 0;
}
如果您将
func
更改为实际对象,情况将会非常不同:
void func(A a) { }
现在,您的动作实际上将用于填充新的
a
:
func(a); // copy your a into the function parameter
func(std::move(a)); // move your a into the function parameter
我想知道为什么移动构造函数不被调用?并且只调用了两个默认构造函数?
您的示例中没有任何内容需要对
A
类型的对象使用 move ctor。特别是,A a;
是默认初始化,因此将使用默认构造函数。
此外,调用
std::move
中的 func(std::move(a));
只是返回右值引用,实际上并不移动或创建对象。
最后,调用
func(A());
首先使用 A()
部分的默认构造函数,这会产生一个可以直接绑定到 A&&
参数的右值表达式。这里再次不需要调用/使用 move ctor。