C++11:&&右值引用、std::ref与std::unique_ptr

非常容易混淆的三种语法,在新手看来含义似乎相同,都是在函数调用上参数的传递,但实际上有非常大的区别。下面我们来具体分析分析。
首先是&&右值引用,在说这个之前先得弄清什么是右值。右值也叫将亡值(这翻译简直(¬_¬)),顾名思义也就是说将会死亡的值。比如类似这样的代码:

1
std::string s = std::string("abc");

从原理上来说,这句代码的含义是,首先在等号右侧构建一个临时字符串对象,然后将右侧对象执行拷贝构造,拷贝至变量s中,然后释放等号右侧对象(实际的实现中,编译器通常会对这样的代码进行优化,直接在变量s中构建字符串对象)。
如果上面的例子不太明显那么再来一个例子,Gdi+中经常会出现这样的代码:

1
2
Gdiplus::Graphics g(&img);
g.DrawImage(&img2, &Gdiplus::Rect(0, 0, 10, 10), ...);

似曾相识的代码对吧?这儿的DrawImage函数在执行前首先构造匿名Gdiplus::Rect对象,然后作为参数传递,函数调用返回时,也就是这行代码执行完时,匿名对象将被释放。这也是它被叫做将亡值的原因。
既然这种对象在使用时生命周期短,拷贝至左值又可能会影响效率,那有没更好的引用方式呢?当然有,这叫右值引用。
继续阅读C++11:&&右值引用、std::ref与std::unique_ptr

C++11:智能指针

智能指针,顾名思义,也就是自动回收内存的指针形式,不用程序员刻意去释放,提高软件开发效率,同时也会提高软件鲁棒性。
C++11一共有4个智能指针,分别为auto_ptr、unique_ptr、shared_ptr、weak_ptr。其中auto_ptr由于存在设计问题,被标记为“已弃用”,将在未来某个C++版本中被移除。本文主要介绍其他三个指针形式。使用前首先包含 这个头文件
1、unique_ptr
这个智能指针的含义为,智能指针所管理的内存区域为独占状态,当另一个unique_ptr访问当前指针时,当前指针会失效,内存的控制权交给新指针。示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <memory>
using namespace std;
 
void test_ptr (unique_ptr<int> p) {
}
 
int main (int argc, char* argv []) {
    //构造一个unique_ptr
    unique_ptr</int><int> p = make_unique</int><int> (5);
    //打印指针内容
    cout < < *p << endl;
    //修改指针内容
    *p = 100;
    //打印指针内容
    cout << *p << endl;
    //将控制权交给函数参数
    test_ptr (move (p));
    //测试指针是否有效
    cout << p.get () << endl;
    return 0;
}

首先构造一个unique_ptr。unique_ptr构造方式以前一般为 unique_ptr p (new int); 这样的形式,构造时直接包含一个指针。后来在C++14中引入了make_unique,建议统一写成这样的格式。
构造时设置初始值为5,打印结果也为5,然后设置指针内容为100,这儿打印出来的结果也为100,然后使用移动语义,将控制权交给test_ptr函数,这时候main函数中p指针失效,然后函数什么也不做,当它返回时,实际上已经将指针指向的内存释放了。然后我们调用 get() 函数获取智能指针管理的指针地址,打印结果为00000000
可见智能指针用法上还是很简单的。
继续阅读C++11:智能指针