提问人:fizzbuzz 提问时间:6/29/2020 最后编辑:JFMRfizzbuzz 更新时间:7/1/2020 访问量:308
为什么称为复制构造函数而不是移动构造函数?
Why is copy constructor called rather than move constructor?
问:
我有以下代码:
#include <bits/stdc++.h>
using namespace std;
class A {
public:
A(const A& a) noexcept { cout << "copy constructor" << endl; }
A& operator=(const A& a) noexcept { cout << "copy assignment operator" << endl; }
A(A&& a) noexcept { cout << "move constructor" << endl; }
A& operator=(A&& a) noexcept { cout << "move assignment operator" << endl; }
A() { cout << "default constructor" << endl; }
};
vector<A> aList;
void AddData(const A&& a)
{
aList.push_back(std::move(a));
}
int main()
{
AddData(A());
return 0;
}
输出为 。请告诉我是否调用了右值引用?什么时候调用复制构造函数?default constructor copy constructor
push_back(T&&)
答:
8赞
JFMR
6/29/2020
#1
问题出在以下参数上:a
AddData()
void AddData(const A&& a) // <-- const reference!!!
{
aList.push_back(std::move(a)); // selects push_back(const A&)
}
上面的参数是常量
右值引用。您正在使用对象进行标记。a
std::move()
const
当涉及到移动语义时,使用 for moving 标记对象不起作用,因为您不能从对象中移动(即,您需要更改从中移动的对象,但它是限定的)。const
std::move()
const
const
右值引用不绑定到对象,但左值引用绑定到对象。因此,将选择重载而不是重载,因此将复制构造对象。const
const
push_back(const A&)
push_back(A&&)
A
溶液
请改用非右值引用:const
void AddData(A&& a) // <-- non-const reference
{
aList.push_back(std::move(a)); // selects push_back(A&&)
}
评论
1赞
Mooing Duck
7/1/2020
“用 std::move() 标记一个 const 对象进行移动没有效果” 从技术上讲,只需转换为 Rvalue,就会给你留下一个有效的 .它只是没有一个需要 的构造函数,所以回退到 .从理论上讲,人们可以用构造函数创建一个类。std::move
const&&
std::string
const&&
const&
const&&
1赞
JFMR
7/1/2020
@MooingDuck 是的,你是对的,总是有施法的效果。但是,我想说的是,在移动语义方面对对象没有影响,因为我认为右值引用参数函数(例如,类型)没有定义的语义。我希望或多或少清楚为什么选择过载——毕竟没有过载。std::move()
std::move()
const
const
const A&&
vector<A>::push_back(const A&)
vector<A>::push_back(const A&&)
2赞
Mooing Duck
7/1/2020
你的答案很好。我只是太迂腐了。右值引用参数函数没有为 std::string
或任何其他标准 C++ 类型定义的语义,但可以自由地为自己的类定义自己的语义。const
const&&
评论