我们知道除了静态内存和栈内存外,每个程序还有一个内存池,这部分内存被称为自由空间或者堆。程序用堆来存储动态分配的对象即那些在程序运行时分配的对象,当动态对象不再使用时,我们的代码必须显式的销毁它们。
在C++中,动态内存的管理是用一对运算符完成的:new和delete,new:在动态内存中为对象分配一块空间并返回一个指向该对象的指针,delete:指向一个动态独享的指针,销毁对象,并释放与之关联的内存。
动态内存管理经常会出现两种问题:一种是忘记释放内存,会造成内存泄漏;一种是尚有指针引用内存的情况下就释放了它,就会产生引用非法内存的指针。
为了更加容易(更加安全)的使用动态内存,引入了智能指针的概念。智能指针的行为类似常规指针,重要的区别是它负责自动释放所指向的对象。标准库提供的两种智能指针的区别在于管理底层指针的方法不同,shared_ptr允许多个指针指向同一个对象,unique_ptr则“独占”所指向的对象。标准库还定义了一种名为weak_ptr的伴随类,它是一种弱引用,指向shared_ptr所管理的对象,这三种智能指针都定义在memory头文件中。
#include<iostream>
using namespace std;
int main() {
//--------------------shared_ptr---------------------------------------
shared_ptr<int> p1=make_shared<int>(100);//make_shared返回指向此对象的shared_ptr指针,因此前面的对象类型直接用auto
shared_ptr<int> p2(new int(42));//使用new来与shared_ptr结合
shared_ptr<int> p3(p1);//100这个对象有两个引用者
if (p3.unique())//false
cout << "ptr is unique" << endl;
else
cout << p3.use_count() << endl;
if(p1)
{
cout <<*p1 << endl;
}
//--------------------unique_ptr-------------------------------------------
unique_ptr<int> p4(new int(42));//只有这种创建方式了,不能make_shared;另外不能用=,因为接受只能指针构造函数是explicit的,不接受隐式类型转换
//不接受赋值,不接受拷贝
//但是接受转移
unique_ptr<int> p5(p4.release());//p4放弃对指针的控制权,p4置为空,并将指针的控制权交给p5;
unique_ptr<int> p6(new int(66));
p6.reset(p5.release());//p5失去指针的控制权,然后p6释放原来的内存,并获得p5当时指针的控制权
//-------------------weak_ptr-----------------------------------
auto p7 = make_shared<int>(77);
weak_ptr<int> p8(p7);//只是为了获取该对象,不增加引用次数
cout << p7.use_count() << endl;//1
cout << *p8.lock()<< endl;//返回值为一个shared_ptr对象
//弱引用可以实现相互引用的时候的互锁问题,解决方案就是:将相互引用的两个类中其中一个改为weak_ptr;
system("pause");
return 0;
}