unique_ptr , shared_ptr,weak_ptr 。
std::shared_ptr是C++ 提供的最常用的智能指针,采用引用计数,多个shared_ptr中的 T *ptr指向同一个内存区域(同一个对象),并且他们(多个shared_ptr)共同维护一个引用计数器,记录着同一个实例被引用的次数,当引用次数大于0时内存可用,等于0时释放内存。实现了任何地方都不是使用时自动删除指针,帮助解决消除内存泄漏和悬空指针的问题。
每个std::shared_ptr指针在内部维护着两个内存位置:
下面是 shared_ptr 内部原理实例。
- // shared_ptr 伪代码
-
- template<typename T>
- class Shared_ptr {
- pubolic:
- ........
- private:
- T *_ptr; // 指针指向的内存区域
-
- int *_refCount; // 引用次数
- }
案例:shared_ptr 带来的循环引用问题
- #include
- #include
- using namespace std;
-
- class ClassB;
-
- class ClassA
- {
- public:
- ClassA()
- {
- cout << "ClassA Constructor...." << endl;
- }
- ~ClassA()
- {
- cout << "ClassA Destructor....." << endl;
- }
- // 在 A中引用 B
- shared_ptr
pb; - };
-
- class ClassB
- {
- public:
- ClassB() {
- cout << "ClassB Constructor....." << endl;
- }
- ~ClassB()
- {
- cout << "ClassB Destructor....." << endl;
- }
- // 在B中引用A
- shared_ptr
pa; - };
-
- int main() {
- shared_ptr
spa = make_shared(); - shared_ptr
spb = make_shared(); - spa->pb = spb;
- spb->pa = spa;
- }
在上面代码中,ClassA和ClassB之间存在着循环引用,从运行结果可以看到:当main函数运行结束后,spa和spb管理的动态资源并没有得到释放,产生了内存泄漏。
所以为了解决类似这样的问题,C++11引入了 weak_ptr ,来打破这种循环引用。