用智能指针可以简化内存管理。以树为例,如果用普通指针,通常是在插入新节点时用new,在析构函数中调用delete;但有了unique_ptr类型的智能指针,就不需要在析构函数中delete了,因为当unique_ptr类型的指针P生命结束时(比如对于局部变量,程序执行到局部变量的作用域范围之外),P会自动delete它拥有的资源(指针指向的空间)。对于shared_ptr,情况更加复杂一些,shared_ptr会维护一个use count,即有多少个指针共享这一资源,当use count为0时,资源被自动释放。
?
? ? 有一篇wiki专门解释了这种模式(将资源的获取与释放与对象的生命周期绑定),http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization
?
? ? 这篇文章主要关注unique_ptr,如果不熟悉,可以先读一下这个:http://www.cplusplus.com/reference/memory/unique_ptr/
?
? ? 这里用排序二叉树的简单实现来展示如何使用unique_ptr,我们只实现插入一个int,以及中序遍历输出所有数字的功能,这已经足以解释unique_ptr的使用方法(其实是,我不太会写二叉树的平衡- -)
?
? ? TreeNode代表一个树节点,包括一个int值,和指向左右子树的智能指针。我们在TreeNode和BST里都实现了insert(int)和inOrder(),BST中的方法基本上是调用TreeNode的对应方法(BST的方法只是一个wrapper,真正干活的是TreeNode里的对应方法)
?
复制代码
#include
#include
#include
#include
#include
using namespace std;
class TreeNode{
? ? public:
? ? unique_ptr left;
? ? unique_ptr right;
? ? int val;
? ? TreeNode(){}
? ? TreeNode(int value): val(value){}
? ? void insert(int value){
? ? ? ? if (value <= val) {
? ? ? ? ? ? if (left) {
? ? ? ? ? ? ? ? left->insert(value);
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? left.reset(new TreeNode(value));
? ? ? ? ? ? }
? ? ? ? } else {
? ? ? ? ? ? if (right) {
? ? ? ? ? ? ? ? right->insert(value);
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? right.reset(new TreeNode(value));
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? void inOrder(stringstream& ss){
? ? ? ? if (left){
? ? ? ? ? ? left->inOrder(ss);
? ? ? ? }
? ? ? ? ss << val << " ";
? ? ? ? if (right) {
? ? ? ? ? ? right->inOrder(ss);
? ? ? ? }
? ? }
};
class BST {
public:
? ? BST ();
? ? virtual ~BST ();
? ? void insert(int value);
? ? string inOrder();
private:
? ? unique_ptr root;
};
BST::BST(){}
BST::~BST(){}
void BST::insert(int value){
? ? if(root){
? ? ? ? root->insert(value);
? ? } else {
? ? ? ? root.reset(new TreeNode(value));
? ? }
}
string BST::inOrder(){
? ? if (root) {
? ? ? ? stringstream ss;
? ? ? ? root->inOrder(ss);
? ? ? ? return ss.str();
? ? } else {
? ? ? ? return "";
? ? }
?
}
int main(int argc, const char *argv[])
{
? ? BST bst;
? ? bst.insert(4);
? ? bst.insert(5);
? ? bst.insert(2);
? ? bst.insert(1);
? ? cout << bst.inOrder() << endl;
? ? return 0;
}