您的位置:首页 > 编程语言 > C语言/C++

C++11学习笔记2---右值引用与移动构造函数

2015-10-28 10:35 411 查看
1.引入原因

(1)函数参数为什么要使用常量引用

因为函数在参数传递(实参--->形参)的时候会有两种形式,①值传递②引用传递

如果使用值传递,在遇到大的对象作为参数时会耗费大量时间与内存空间。

采用引用就不会有这个拷贝过程。所以使用引用。

而我们一般又希望作为参数的引用不要改变原来的对象的内容,所以采用常量引用(const &)。

(2)拷贝构造函数为什么使用常量引用

拷贝构造函数,首先是一个函数,其次它的任务就是借用一个本类型的对象,拷贝创建一个新的对象。

所以有如下的过程:实参--->形参--->新创建的对象

其中,形参--->新创建的对象,是拷贝构造函数这个函数所赋予的功能(新创建的对象要和作为参数的对象内容相同但是拥有独立的内存空间)。

当然你可以说,我们就是用普通的没有修饰符的对象作为参数,这时发生一个值传递,再return 一个形参,不还是只发生一次拷贝吗?

问题是,类的构造函数是没有返回值的,所以实参--->形参之后,还是需要一个形参--->拷贝初始化新对象的过程。

所以使用const &作为参数,就是会省下一个实参--->形参的拷贝过程,但是形参--->初始化新对象的过程是由这个函数的性质决定的,省不了。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

由(1)、(2)可知,常量引用为我们提供了

灵活性:①我们可以只是读取,所以不需要单独构建一个对象。所以用引用即可。

②当我们我们确实需要拷贝构建一个新的对象,那么用这个引用进行拷贝即可,还是省下了一个实参--->形参的拷贝。

安全性:由于是常量引用,所以并不能对传入的参数进行修改。

更详细的关于const的细节请看我之前的帖子:const

(3)移动构造函数为什么使用右值引用

首先还是为了不拷贝大对象,所以使用引用。

但是由于引用对象是右值(如字面值或者临时对象),因为这类值本身就是用于临时存储,所以窃取其值不影响程序正确性。

所以这样我们如果确实需要一个单独的传入的参数也不需要拷贝了,就直接将这个传入的参数“据为己有”即可。

总结起来的话,移动构造函数就是实参--->形参,形参--->新创建的对象,这两个过程的拷贝都省了。

注:临时对象表示没有名字的对象,比如int(3.14),

class A a;

(class A (a));

(class A (a))就是使用对象a初始化的一个临时对象。

2.出现形式与使用细节

(1)声明一个右值引用

int&& i = 42;

或者

class X

{

private:

int* data;

public:

X():

data(new int[1000000])

{}

~X()

{

delete [] data;

}

X(const X& other):

data(new int[1000000])

{

std::copy(other.data,other.data+1000000,data);

}

X(X&& other):

data(other.data)

{

other.data=nullptr;

}

};

(2)使用在拷贝构造函数

X x1;

X x2 = std::move(x1);

X x3 = static_cast<X&&>(x2);

(3)使用在函数模板

填入左值,推断为左值引用。

填入右值,推断为普通无修饰类型。

比如:

填入右值,推断为普通无修饰类型情况

foo(42);

foo(3.14159);

foo(std::string());

填入左值,推断为左值引用情况

int i=42;

foo(i);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: