问题描述
嗨,我想了解如何使用带有右值和左值引用作为参数的函数的重载版本。所以这是我写的例子,以更好地理解差异:
car.h
class Car{
private:
int number=1000;
string name="default name";
std::set<int> Carset;
public:
void pushtoset(int &);
void pushtoset(int &&);
}
car.cpp
#include "car.h"
void Car::pushtocar(int &x){
Carset.insert(x);
}
void Car::pushtocar(int &&x){
Carset.insert(x);
}
main.cpp
int main(){
Car object;
int x = 43;
object.pushtocar(x); //this calls pushtocar(int&) version(say version I)
object.pushtocar(54); // this calls pushtocar(int &&) version(say version II)
return 0;
我的问题是在版本 II 的情况下,当此成员函数的主体完成时,并且由于在函数主体内部,参数 x 是左值(对于函数而言是局部的),因此 x 将被销毁。这是否意味着我们插入到集合中的值也会被销毁?如果是这样,我如何防止推送到集合上的值不被销毁?我认为与第一个问题有关的第二个问题是,当我在版本 II 中编写 Carset.insert(x);
时,x 会被复制或移动吗?我认为它会被复制。因此,如果 x 被复制,那么 x 被销毁也没有问题,因为插入的元素和 x 是相互独立的。但是现在如果我写 Carset.insert(std::move(x));
那么 x 将被“移动”到集合而不是复制。所以在这种情况下,我们会遇到问题,函数体完成后,x 将被销毁,因此插入的元素也将被销毁。有什么方法可以防止在这个移动的情况下插入集合中的元素使 x 处于有效状态被销毁?我对这个概念的理解是否正确?
解决方法
版本 II 采用 'swap' [std::move] 所以完成后,传递给函数的参数是未定义的。你不能再使用它了。右值引用延长了对象的生命周期,它不会被立即销毁。 我采用左值的版本,所以它是复制构造函数。它的正确形式应该是
void Car::pushtocar(const int &x){
Carset.insert(x);
}