创作不易,本篇文章如果帮助到了你,还请点赞 关注支持一下♡>𖥦<)!!
主页专栏有更多知识,如有疑问欢迎大家指正讨论,共同进步!
🔥c++系列专栏:C/C++零基础到精通 🔥给大家跳段街舞感谢支持!ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ
c语言内容💖:
专栏:c语言之路重点知识整合
C++11 中引入了智能指针,便于进行内存管理
使用智能指针 需要包含头文件:
#include <memory>
以及
std
命名空间
智能指针会自动回收空间,不需要担心内存泄漏问题
四种智能指针:
- auto_ptr(C++11 被弃用)
- unique_ptr
- shared_ptr
- weak_ptr
一、 auto_ptr
创建auto_ptr对象的三种方式:
#include <iostream>
#include <memory>
using namespace std;
class A
{
public:
void fun()
{
cout << this << "A::fun()" << endl;
}
};
int main()
{
auto_ptr<A> p1(new A() );
auto_ptr<A> p2;
p2.reset(new A());
auto_ptr<A> p3;
p3 = p1; //把p1空间的归属权交给p3,后面不能再用p1
return 0;
}
使用对象:
p3.get()->fun();
p3->fun();
auto_ptr 存在的问题:将 p1 赋值给 p3 ,会将 p1 的资源转交给 p3,而不是复制,此时再调用 p1
会出现空指针问题:
auto_ptr<A> p3;
p3 = p1;
p1->fun(); //error
因此在 C++11 中被弃用。
二、unique_ptr
唯一所属权的智能指针,只能有一个指针管理内存
三种创建对象与使用方式:
#include <iostream>
#include <memory>
using namespace std;
class A
{
public:
void fun()
{
cout << this << "A::fun()" << endl;
}
};
int main()
{
//1.
unique_ptr<A> p1(new A());
p1->fun();
//2.reset
unique_ptr<A> p2;
p2.reset(new A());
p2.get()->fun();
//3.move
unique_ptr<A> p3;
p3 = std::move(p2); //使用权传递,不可以直接使用 = 赋值
(*p3).fun();
cout << p2.get() << endl;
// 4.make_unqiue
unique_ptr<A> p4 = make_unique<A>(); //c++14引入
return 0;
}
C++11中unique_ptr 用于替代废弃的auto_ptr
空间使用权传递的方式要求更严格:不可以直接使用 =
赋值,可以使用 std::move
将左值转为右值进行赋值
同时,当一个unique_ptr
的使用权被交出后或者超出智能指针的作用域后,这个指针会自动失效
但是 unique_ptr 一个只能指向一块空间,如果 reset 转移到另一块空间,原先的内存就无法指向使用了,因此引入了 shared_ptr:
三、shared_ptr
共享所属权的智能指针
多个指针可以指向同一个空间,可以同时生效
使用引用计数管理回收 ,使用 use_count
函数可以查看指向这块空间的指针数量
#include <iostream>
#include <memory>
using namespace std;
class A
{
public:
void fun()
{
cout << "A::fun()" << endl;
}
~A()
{
cout << "A::~A()" << endl;
}
};
int main()
{
shared_ptr<A> p1(new A());
p1->fun();
shared_ptr<A> p2;
p2.reset(new A());
(*p2).fun();
shared_ptr<A> p3;
p3 = make_shared<A>();
p3.get()->fun();
{
shared_ptr<A> p4;
p4 = p3; // 指向同一块空间 两个指针共享内存
cout << p4.use_count() << endl;
cout << "p3: " << p3.get() << " p4: " << p4.get() << endl;
} // p4在此回收
return 0;
}
shared_ptr 存在循环引用的问题:
如果两个 shared_ptr 相互引用,引用计数永远不会变为0,因此它们所指向的对象也不会被删除,这会导致内存泄漏
例如:
#include <iostream>
#include <memory>
using namespace std;
class B;
class A
{
public:
shared_ptr<B> pb;
void fun()
{
cout << "A::fun()" << endl;
}
~A()
{
cout << "A::~A()" << endl;
}
};
class B
{
public:
shared_ptr<A> pa;
void fun()
{
cout << "B::fun()" << endl;
}
~B()
{
cout << "B::~B()" << endl;
}
};
int main()
{
shared_ptr<A> pa = make_shared<A>();
shared_ptr<B> pb = make_shared<B>();
pa->pb = pb;
pb->pa = pa;
pb->fun();
pa->fun();
// pa和 pb 的引用计数都是 1,但由于它们相互引用,它们都不会被删除
return 0;
}
为了解决循环引用的问题,引入了 weak_ptr
:
四、weak_ptr
用于解决shared_ptr存在循环引用的问题
弱引用计数的共享使用权的智能指针,不能独立存在,配合shared_ptr使用
如果使用 weak_ptr
与 shared_ptr
指向同一空间,引用计数不会加1
#include <iostream>
#include <memory>
using namespace std;
class B;
class A;
class A
{
public:
shared_ptr<B> pb;
void fun()
{
cout << "A::fun()" << endl;
}
~A()
{
cout << "A::~A()" << endl;
}
};
class B
{
public:
weak_ptr<A> pa; //使用weak_ptr
void fun()
{
cout << "B::fun()" << endl;
}
~B()
{
cout << "B::~B()" << endl;
}
};
int main()
{
shared_ptr<A> pa = make_shared<A>();
shared_ptr<B> pb = make_shared<B>();
pa->pb = pb;
pb->pa = pa;
pb->fun();
pa->fun();
return 0;
}
weak_ptr 注意事项
- 避免悬空指针 使用 weak_ptr 之前,必须确保其所指向的对象仍然存在
- std::weak_ptr 应该通过 shared_ptr 构造而来,不可直接从裸露指针构造
- 注意失效 当最后一个 shared_ptr 所引用的对象被释放时,weak_ptr 会自动失效
大家的点赞、收藏、关注将是我更新的最大动力! 欢迎留言或私信建议或问题。 |
大家的支持和反馈对我来说意义重大,我会继续不断努力提供有价值的内容!如果本文哪里有错误的地方还请大家多多指出(●'◡'●) |