#include <memory>
#include <iostream>
/************************************************************************************
使用智能指针的注意点:
1. 绝对不要自己手动管理堆空间(delete、delete[])
2. 初始化智能指针时尽可能使用 std::make_shared 空间更小
(下面为了学习不用这种方式创建shared_ptr)
3. 不要用一个裸指针去构造两个独立的智能指针对象(裸指针构造的对象引用计数不关联),
只有用智能指针去初始化另一个智能指针时,引用计数才加 1
4. 用weak_ptr打破shared_ptr的循环引用(如:下边的Father和Son会造成内存泄漏)
5. 在类内部接口中需要通过this来使用智能指针时,需要继承enable_shared_from_this
6. 在构造和析构时不能使用shared_from_this()函数
7. 智能指针实际是模板类,比裸指针效率更低,且更占内存
8. 优先使用类的实例,实在需要用到指针再考虑智能指针
(singleton/object > unique_ptr > shared_ptr)
************************************************************************************/
using namespace std;
//类的前置声明
class Son;
//C++11 using定义类型别名
using Son_sPtr = shared_ptr<Son>;
class Duaghter;
using Duaghter_wPtr = weak_ptr<Duaghter>;
using Duaghter_sPtr = shared_ptr<Duaghter>;
class Father;
using Father_sPtr = shared_ptr<Father>;
using Father_uPtr = unique_ptr<Father>;
//继承自enable_shared_from_this<Father>时,Father成员内部才允许用this构造share_ptr
class Father : public enable_shared_from_this<Father> {
public:
Father(int id):m_id(id) { cout << "creat Father" << m_id << endl; }
~Father() { cout << "destory Father" << m_id << endl; }
void setSon(Son_sPtr& son) { m_son = son; }
void setDuaghter(Duaghter_sPtr& duaghter) { m_duaghter = duaghter; }
int ID() { return m_id; }
private:
Son_sPtr m_son{ nullptr };
Duaghter_wPtr m_duaghter;//不能给nullptr 因为weak_ptr只能由对应的shared_ptr进行初始化
int m_id{ 0 };
};
class Son {
public:
Son(int id):m_id(id) { cout << "creat Son" << m_id << endl; }
~Son() { cout << "destory Son" << m_id << endl; }
void setFather(Father_sPtr& father) { m_father = father; }
int ID() { return m_id; }
private:
Father_sPtr m_father{ nullptr };
int m_id{ 0 };
};
class Duaghter {
public:
Duaghter(int id) :m_id(id) { cout << "creat Duaghter" << m_id << endl; }
~Duaghter() { cout << "destory Duaghter" << m_id << endl; }
void setFather(Father_sPtr& father) { m_father = father; }
int ID() { return m_id; }
private:
Father_sPtr m_father{ nullptr };
int m_id{ 0 };
};
void useSharedPtr()
{
//错误!不能使用两个不相关的智能指针对象管理同一份内存
//Son *s_son = new Son(1);//裸指针
//Son_sPtr s2_son(s_son);
//Son_sPtr s3_son(s_son);
//cout << "s2_son use_count : " << s2_son.use_count() << endl;
//cout << "s3_son use_count : " << s3_son.use_count() << endl;
//shared_ptr的构造函数
Son_sPtr son(new Son(1));
//智能指针son这个对象管理的内容被引用的次数 use_count()
cout << "son use_count : " << son.use_count() << ",id : " << son->ID() << endl;
//shared_ptr的拷贝构造函数
Son_sPtr son2(son);
cout << "son2 use_count : " << son2.use_count() << ",id : " << son2->ID() << endl;
Son_sPtr son3 = son;
cout << "son3 use_count : " << son3.use_count() << ",id : " << son3->ID() << endl;
///重置智能指针;
//无参数:引用计数-1,当前智能指针被置nullptr
son3.reset();
cout << "son use_count : " << son.use_count() << endl;
///重载了bool
if(son3)
cout << "son3 != nullptr" << endl;
else
cout << "son3 == nullptr" << endl;
//有参数:引用计数-1,当前智能指针管理其他的对象
son2.reset(new Son(2));
cout << "son use_count : " << son.use_count() << ",id : " << son->ID() << endl;
cout << "son2 use_count : " << son2.use_count() << ",id : " << son2->ID() << endl;
son2 = son;
cout << "son use_count : " << son.use_count() << ",id : " << son->ID() << endl;
cout << "son2 use_count : " << son2.use_count() << ",id : " << son2->ID() << endl;
///判断智能指针管理的对象当前是否只有这1个地方再管理unique()
if (son2.unique())
cout << "son2 use_count : 1, id : " << son2->ID() << endl;
else
cout << "son2 use_count : " << son2.use_count() << ",id : " << son2->ID() << endl;
///拿智能指针内部管理的对象,不交出管理权
auto *contain = son.get();
cout << "son use_count : " << son.use_count() << ",id : " << son->ID() << endl;
//delete contain;//error ! 不可以自己去删除shared_ptr智能指针管理的对象
// cout << "son == nullptr : " << (son == nullptr) << endl;
}
//此时shared_ptr会出现内存泄漏
void testSharedPtr()
{
Son_sPtr son(new Son(1));
Father_sPtr father(new Father(1));
son->setFather(father);//引用基数+1
father->setSon(son);//引用基数+1
}
void useWeakPtr()
{
Duaghter_sPtr sDuaghter(new Duaghter(1));
Duaghter_wPtr wDuaghter;
///判断weak_ptr是否过期
if (wDuaghter.expired())
cout << "wDuaghter is expired !" << endl;
Duaghter_wPtr wDuaghter2(sDuaghter);
if (wDuaghter2.expired())
cout << "wDuaghter2 is expired !" << endl;
else
cout << "wDuaghter2 is not expired !" << endl;
//赋值运算符
wDuaghter = wDuaghter2;//weak_ptr引用基数+1
Duaghter_sPtr sDuaghter2 = wDuaghter.lock();//shared_ptr的引用计数+1
cout << "wDuaghter use_count: " << wDuaghter.use_count() << endl;
cout << "sDuaghter use_count: " << sDuaghter.use_count() << endl;
cout << "**************************************" << endl;
//智能指针sDuaghter不再管理对象
sDuaghter.reset();
if (wDuaghter2.expired())
cout << "wDuaghter2 is expired !" << endl;
else
cout << "wDuaghter2 is not expired !" << endl;
sDuaghter2.reset();
Duaghter_sPtr sDuaghter3 = wDuaghter2.lock();//此时weak_ptr已过期,取回的是nullptr
if (!sDuaghter3)
{
cout << "wDuaghter3 is null !" << endl;
}
}
//此时不会出现泄漏问题
void testSharedAndWeakPtr()
{
Duaghter_sPtr duaghter(new Duaghter(1));
Father_sPtr father(new Father(1));
duaghter->setFather(father);
father->setDuaghter(duaghter);
}
//使用unique_ptr指针作为函数形参
void useUniquePtrParam(Father_uPtr father)
{
cout << "ID :" << father->ID() << endl;
}
//默认使用unique_ptr管理指针,除非需要共享
void testUniquePtr()
{
//构造函数
Father_uPtr father(new Father(1));
cout << "ID :" << father->ID() << endl;
cout << "ID :" << (*father).ID() << endl;
//由于unique_ptr独占特性,所以不存在拷贝构造和赋值运算符
//可以通过release函数交出管理权和内容
Father* father2 = father.release();
cout << "ID :" << father2->ID() << endl;
if (!father)
{
cout << "father is null " << endl;
}
delete father2;//销毁原来的内存
father2 = nullptr;
Father_uPtr father3(new Father(3));
//不允许值传递
//useUniquePtrParam(father3);//编译不过
//但允许使用右值move传参
useUniquePtrParam(move(father3));
if (!father3)//move结束后,智能指针对象变成为初始状态
{
cout << "father3 is null " << endl;
}
//可以用release或move使unique_ptr交出独占权,从而转换为shared_ptr
Father_uPtr father4(new Father(4));
Father_sPtr contain(father4.release());
cout << "father4 ID: " << contain->ID() << endl;
Father_uPtr father5(new Father(5));
Father_sPtr contain2(move(father5));
cout << "father5 ID: " << contain2->ID() << endl;
}
C++11学习笔记 -- 智能指针
最新推荐文章于 2024-01-19 00:45:00 发布