智能指针其实并不是指针,而是一个特殊对象。
在智能指针对象生命期即将结束时,它会调用析构函数释放有它管理的堆内存。
访问智能指针管理对象的方法,使用操作符“->”(重载)。
访问智能指针本来的方法,使用操作符“.”。
我们常见的智能指针有以下几种:
C98 std::auto_ptr 第一代智能指针,有些操作比如“=”坑比较多,不推荐使用。 C11 std::unique_ptr 独占对象,并保证指针所指对象生命周期与其一致。 std::shared_ptr 可共享指针对象,可以赋值给shared_ptr或weak_ptr。 通过引用计数的方式控制生命周期,当指针所指对象的所有的shared_ptr生命周期结束时(引用计数为0时)会被销毁。 std::weak_ptr 可以指向shared_ptr,但并不影响引用计数。 不影像所指对象的生命周期,在引用所指对象时,先用需要lock()才能使用。 Boost 不共享对象,类似于std::unique_ptr boost::scoped_ptr boost::scoped_array 共享对象,类似于std::shared_ptr boost::shared_ptr boost::shared_array 共享对象,但不改变对象引用计数,类似于std::weak_ptr boost::weak_ptr 侵入式引用计数,要求使用对象自己实现计数功能 boost::intrusive_ptr
下面给一个例子,说明一下std下的四种智能指针。
1、SmartPointerTest.cpp
#include <memory> #include <iostream> #include "MyTest.h" using namespace std; void test_auto_ptr() { std::auto_ptr<MyTest> auto_ptr_01(new MyTest("tom", 20)); if (auto_ptr_01.get()) { auto_ptr_01->sayHello(); auto_ptr_01.get()->_name = "jerry"; auto_ptr_01->sayHello(); (*auto_ptr_01)._age += 1; auto_ptr_01->sayHello(); } //auto_ptr_02会抢占auto_ptr_01的对象 //此后auto_ptr_01不指向MyTest对象 std::auto_ptr<MyTest> auto_ptr_02 = auto_ptr_01; if (auto_ptr_01.get()) { cout << "auto_ptr_01 is released" << endl; } auto_ptr_02->sayHello(); //只是释放所有权,并不释放内存 //MyTest* test = auto_ptr_02.release(); //释放内存 auto_ptr_02.reset(); if (!auto_ptr_01.get()) { cout <<"auto_ptr_02 is released"<< endl; } } void test_unique_ptr() { //独占对象 //保证指针所指对象生命周期与其一致 unique_ptr<MyTest> unique_ptr_01(new MyTest("tom", 20)); unique_ptr_01->sayHello(); //不允许直接做右值 //unique_ptr<int> unique_ptr_02 = unique_ptr_01; //需要通过move来处理 unique_ptr<MyTest> unique_ptr_03 = move(unique_ptr_01); if (!unique_ptr_01)cout << "unique_ptr_01 is empty" << endl; unique_ptr_03->sayHello(); //释放指针 unique_ptr_03.reset(); if (!unique_ptr_03)cout << "unique_ptr_03 is empty" << endl; } void test_shared_ptr() { shared_ptr<MyTest> shared_ptr_01(make_shared<MyTest>("tom", 20)); shared_ptr<MyTest> shared_ptr_02 = shared_ptr_01; shared_ptr_01->sayHello(); shared_ptr_02->sayHello(); shared_ptr_01.reset(); if (!shared_ptr_01)cout << "shared_ptr_01 is empty" << endl; shared_ptr_02->sayHello(); shared_ptr_02.reset(); if (!shared_ptr_02)cout << "shared_ptr_02 is empty" << endl; } void test_weak_ptr() { shared_ptr<MyTest> shared_ptr_01(make_shared<MyTest>("tom", 20)); weak_ptr<MyTest> weak_ptr_01 = shared_ptr_01; shared_ptr_01->sayHello(); weak_ptr_01.lock()->sayHello(); weak_ptr_01.reset(); if (!weak_ptr_01.lock())cout << "weak_ptr_01 is empty" << endl; shared_ptr_01->sayHello(); weak_ptr<MyTest> weak_ptr_02 = shared_ptr_01; weak_ptr<MyTest> weak_ptr_03 = weak_ptr_02; if(weak_ptr_01.lock())weak_ptr_02.lock()->sayHello(); shared_ptr_01.reset(); if (!weak_ptr_01.lock())cout << "weak_ptr_02 is empty" << endl; } int _tmain(int argc, _TCHAR* argv[]) { test_auto_ptr(); test_unique_ptr(); test_shared_ptr(); test_weak_ptr(); return 0; }
2、MyTest.h
#pragma once #include <iostream> #include <string> using namespace std; class MyTest { public: MyTest(string name, int age); ~MyTest(); void sayHello(); public: string _name; int _age; };
3、MyTest.cpp
#include "stdafx.h" #include "MyTest.h" MyTest::MyTest(string name, int age) { _name = name; _age = age; } MyTest::~MyTest() { } void MyTest::sayHello() { cout << "Hello " << _name<< "! You are "<< _age <<" years old." << endl; }
PS:
聪明的你有没有发下,CPP的智能指针,与JVM内存中的四种引用方式,强引用、软引用、弱引用,虚引用,有很多相似的地方呢?