网站建设中 敬请期待.,网站如何做h5动态页面,线上做网站赚钱,专业的外贸行业网站设计1、概念 堆内存的对象需要手动使用delete销毁#xff0c;如果忘记使用delete销毁就会造成内存泄漏。 所以C在ISO 98标注中引入了智能指针的概念#xff0c;并在C11 中趋于完善。 使用智能指针可以让堆内存对象具有栈内存对象的特性。原理时给需要自动回收的堆内存对象套上一层…1、概念 堆内存的对象需要手动使用delete销毁如果忘记使用delete销毁就会造成内存泄漏。 所以C在ISO 98标注中引入了智能指针的概念并在C11 中趋于完善。 使用智能指针可以让堆内存对象具有栈内存对象的特性。原理时给需要自动回收的堆内存对象套上一层栈内存的模板类对象即可。 C有四种智能指针 auto_ptr 自动指针已经废弃CISO 98unique_ptr 唯一指针(CISO 11)shared_ptr 共享指针(CISO 11)weak_ptr 协助指针(CISO 11) 使用智能指针需要引入头文件#includememory 2、auto_ptr #include iostream
#include memory
using namespace std;
class Test
{
private:string s;
public:Test(string s):s(s){cout s 构造函数 endl;}~Test(){cout s 析构函数 endl;}void show(){cout s 执行程序 endl;}
};
int main()
{{Test *t1 new Test(A);// 创建一个智能指针管理t1auto_ptrTest ap1(t1); // ap1 管理t1// 取出被管理的堆内存对象并调用show成员函数ap1.get()-show(); // 释放控制权
// ap1.release();// 创建B堆对象B将A顶掉A对象销毁ap1.reset(new Test(B));ap1.get()-show(); // 释放控制权并且销毁资源对象ap1.reset();cout 局部代码块执行结束 endl;}return 0;
} 释放对象不会调用析构函数只有销毁对象才会有 由于成员变量存在指针类型因此拷贝构造函数与赋值运算符的使用会出现问题。与浅拷贝的问题不同的是auto_ptr的复制语义会引起资源对象控制权转移的问题。 #include iostream
#include memory
using namespace std;
class Test
{
private:string s;
public:Test(string s):s(s){cout s 构造函数 endl;}~Test(){cout s 析构函数 endl;}void show(){cout s 执行程序 endl;}
};int main()
{{Test *t1 new Test(A);// 创建一个智能指针管理t1auto_ptrTest ap1(t1); // ap1 管理t1auto_ptrTest ap2(ap1); // 显式调用拷贝构造函数cout ap1.get() ap2.get() endl; // 0 0x1052780auto_ptrTest ap3 ap2; // 隐式调用构造函数// 0 0 0xe82780cout ap1.get() ap2.get() ap3.get() endl;auto_ptrTest ap4;ap4 ap3; // 赋值运算符// 0 0 0 0x922780cout ap1.get() ap2.get() ap3.get() ap4.get() endl; }return 0;
} 3、unique_ptr 作为对auto_ptr的改进unique_ptr对其他持有的资源对象具有唯一控制权即不可以通过常规的复制语义转移或拷贝资源对象的控制权。 通过特殊的语法实现控制权的转移效果。 #include iostream
#include memoryusing namespace std;class Test
{
private:string s;
public:Test(string s):s(s){cout s 构造函数 endl;}~Test(){cout s 析构函数 endl;}void show(){cout s 执行程序 endl;}
};int main()
{{Test *t1 new Test(A);// 创建一个智能指针管理t1unique_ptrTest up1(t1); // up1 管理t1unique_ptrTest up2(move(up1)); // 显式调用拷贝构造函数cout up1.get() up2.get() endl; // 0 0x1052780unique_ptrTest up3 move(up2); // 隐式调用构造函数// 0 0 0xe82780cout up1.get() up2.get() up3.get() endl;unique_ptrTest up4;up4 move(up3); // 赋值运算符// 0 0 0 0x922780cout up1.get() up2.get() up3.get() up4.get() endl;}return 0;
} 4、shared_ptr unique_ptr对资源具有独占性多个shared_ptr对象可以共享资源。 shared_ptr有两种创建方式 两种创建方式的区别在于后者是一步到位创建资源对象关系绑定前者分为两步完成先创建资源对象再进行关系绑定。 新方式的优点 安全性更好性能更好 新方式的缺点 资源释放效率低 每多一个shared_ptr对资源进行管理引用计数将1每个指向该对象的shared_ptr对象销毁时引用计数-1最后一个shared_ptr对象销毁时计数清零资源对象销毁。 #include iostream
#include memory
using namespace std;
class Test
{
private:string s;
public:Test(string s):s(s){cout s 构造函数 endl;}~Test(){cout s 析构函数 endl;}void show(){cout s 执行程序 endl;}
};
int main()
{shared_ptrTest sp3;{shared_ptrTest sp1 make_sharedTest(A);cout 引用计数 sp1.use_count() endl;shared_ptrTest sp2(sp1); // 拷贝构造函数cout 引用计数 sp2.use_count() endl; sp3 sp2;cout 引用计数 sp3.use_count() endl;}cout 引用计数 sp3.use_count() endl;return 0;
} 5、weak_ptr weak_ptr是一个不控制资源对象的智能指针也不会影响资源的引用计数其主要目的是协助shared_ptr工作。 通过weak_ptr的构造函数参数传入一个持有资源对象的shared_ptr对象或者weak_ptr对象即可创建。 weak_ptr与资源对象呈现弱相关性所以不支持get等函数直接操作资源对象。 建议weak_ptr调用lock函数之前先检测引用计数是否大于0或使用expried()函数检测是否可以转换为shared_ptr。 lock()函数通过传入持有资源对象的对象创建新对象 #include iostream
#include memory
using namespace std;
class Test
{
private:string s;
public:Test(string s):s(s){cout s 构造函数 endl;}~Test(){cout s 析构函数 endl;}void show(){cout s 执行程序 endl;}
};
int main()
{weak_ptrTest wp3;{shared_ptrTest sp1 make_sharedTest(A);weak_ptrTest wp1 sp1;cout sp1.use_count() endl; // 1cout wp1.use_count() endl; // 1weak_ptrTest wp2(wp1); // 拷贝构造cout wp2.use_count() endl;shared_ptrTest sp2 wp1.lock();cout sp2.use_count() endl; // 2 wp3 wp2;cout wp3.use_count() endl;}cout wp3.use_count() endl; // 0if(wp3.expired()){cout 无法使用lock函数因为没有可以管理的对象 endl;}return 0;
}