为什么要学习C++11?
C++11,是C++语言标准的一个重大更新。它在C++98标准的基础上进行了大量改进,修正了约600个语言缺陷,并添加了约140个新特性。这些更新使得C++11更像是从C++98/03中孕育出的一种新语言,为现代C++程序设计奠定了坚实的基础。
一、问题引入
1.问题背景
假设你用的编译器是一个非常古老的编译器,所以就不存在编译器对传参和传返回值的拷贝优化,也更不会存在对连续拷贝进行的合并优化。
- 请问下面两个函数调用的的构造次数是多少?
- addStrings():传参拷贝构造4次,传返回值拷贝构造2次,函数体构造一次
- generate():传返回值拷贝构造2次(但深拷贝,每次都是numsrow + 1),函数体构造(numsrow + 1)次
- 由此可见,在C++11之前和编译器不做任何优化的情况下,传值返回需要付出一定的性能消耗,甚至在某些深拷贝的情形下,代价会进一步增大。
- 如果你作为一名合格的C++程序员,你看到这么糟心的代码,你会作怎样的处理?
class Solution {
public:
string addStrings(string num1, string num2)
{
string str;
int end1 = num1.size() - 1, end2 = num2.size() - 1;
int next = 0;
while (end1 >= 0 || end2 >= 0)
{
int val1 = end1 >= 0 ? num1[end1--] - '0' : 0;
int val2 = end2 >= 0 ? num2[end2--] - '0' : 0;
int ret = val1 + val2 + next;
next = ret / 10;
ret = ret % 10;
str += ('0' + ret);
}
if (next == 1)
str += '1';
reverse(str.begin(), str.end());
return str;
}
vector<vector<int>> generate(int numRows)
{
vector<vector<int>> vv(numRows);
for (int i = 0; i < numRows; ++i)
{
vv[i].resize(i + 1, 1);
}
for (int i = 2; i < numRows; ++i)
{
for (int j = 1; j < i; ++j)
{
vv[i][j] = vv[i - 1][j] + vv[i - 1][j - 1];
}
}
return vv;
}
};
int main()
{
string ret = Solution().addStrings("12345649", "9872131");
vector<vector<int>> ret = Solution().generate(5);
return 0;
}
2.解决方案一:传统方法

- 这样的代码,确实解决了拷贝次数过多的问题,在一定程度了提高了程序的性能。但是代码的可读性却受到了当头一棒。如果在当时那个历史背景下,C++委员会无作为,编译器也不做任何改进。可能也只好为了效率去舍弃代码的可读性了。
- 但问题总有得到解决的那一刻:
- 编译器对传参和传返回值的拷贝优化,以及对连续拷贝进行的合并优化.
- 以及C++11带来的右值引用与移动语义,使得传值返回的问题得到了很好的解决.
- 传值返回问题的解决方案二:编译器的优化,我们已然早已熟知,则本篇文章的重头戏即将开幕:右值引用和移动语义,也就是我们的传值返回问题的解决方案三。
- 移动语义的定义:它允许对象的资源在被移动的时候,避免不必要的拷贝,从而提高程序的性能。即,将当前对象指向的资源的所有权转给另一个对象——你对某个对象指向的资源的感兴趣,你通过某种手段(下面要讲的移动构造和移动赋值),进行资源的窃取(实现移动语义)。
二、右值引用和移动语义
1.左值和右值的定义(C++98)
- 左值:可以取地址,可以出现在赋值操作符的左端和右端,通常是变量和解引用的指针,其具有持久性——所有可以定位的值(可以进行取地址操作)
- 右值:不可以取地址,只能出现在赋值操作符的右端,通常是常量、临时对象(类型转换的中间值,表达式计算结果)、匿名对象,通常其生命周期很短——指那些不持有对象身份的值。
- 左值的缩写lv,右值的缩写为rv,现在很多人都会为lv解读为 located value(有位置的值),将rv解读为 read value(只能读的值,反而言之不能寻其地址)。由此可见左值和右值的核心区别是是否可以取地址.而lv,rv的含义解读,更能帮助我们去理解左值与右值。


最低0.47元/天 解锁文章
590

被折叠的 条评论
为什么被折叠?



