//
// main.cpp
// C++Test28
//
#include <iostream>
#include <memory>
#include <string>
using namespace std;
// 智能指针
class base {
public:
base(int _a) : a(_a) { cout << "构造函数" << endl; }
~base() { cout << "析构函数" << endl; }
int a;
};
class B;
class A {
public:
shared_ptr<B> m_b;
};
class B {
public:
shared_ptr<A> m_a;
};
int main(int argc, const char *argv[]) {
unique_ptr<base> up1(new base(2));
// unique_ptr<base> up2 = up1; //编译器提示未定义
unique_ptr<base> up2 = move(up1); //转移对象的所有权
// cout<<up1->a<<endl; //运行时错误
cout << up2->a << endl; //通过解引用运算符获取封装的原始指针
up2.reset(); // 显式释放内存
shared_ptr<base> sp1(new base(3));
shared_ptr<base> sp2 = sp1; //增加引用计数
cout << "共享智能指针的数量:" << sp2.use_count() << endl; // 2
sp1.reset(); //
cout << "共享智能指针的数量:" << sp2.use_count() << endl; // 1
cout << sp2->a << endl;
auto sp3 = make_shared<base>(4); //利用make_shared函数动态分配内存
{
shared_ptr<A> a(new A); // new出来的A的引用计数此时为1
shared_ptr<B> b(new B); // new出来的B的引用计数此时为1
a->m_b = b; // B的引用计数增加为2
b->m_a = a; // A的引用计数增加为2
}
//b先出作用域,B的引用计数减少为1,不为0;
//所以堆上的B空间没有被释放,且B持有的A也没有机会被析构,A的引用计数也完全没减少
//a后出作用域,同理A的引用计数减少为1,不为0,所以堆上A的空间也没有被释放
return 0;
}
//构造函数
//2
//析构函数
//构造函数
//共享智能指针的数量:2
//共享智能指针的数量:1
//3
//构造函数
//析构函数
//析构函数
// 智能指针的陷阱(循环引用的问题)
//循环引用”简单来说就是:两个对象互相使用一个shared_ptr成员变量指向对方会造成循环引用。
//
//即A内部有指向B,B内部有指向A,这样对于A,B必定是在A析构后B才析构,对于B,A必定是在B析构后才析构A,这就是循环引用问题,违反常规,导致内存泄露。
//
//解决循环引用方法:
//
//1. 当只剩下最后一个引用的时候需要手动打破循环引用释放对象。
//2. 当A的生存期超过B的生存期的时候,B改为使用一个普通指针指向A。
//3. 使用weak_ptr打破这种循环引用,因为weak_ptr不会修改计数器的大小,所以就不会产生两个对象互相使用一个shared_ptr成员变量指向对方的问题,从而不会引起引用循环。