1.auto_ptr
不提倡使用,因为在C++11中已经明确被废弃。
先定义一个类用来做测试:
#include <memory>
#include <iostream>
using namespace std;
class CMyClass
{
public:
CMyClass(int n) : i(n) {
cout<<"CMyClass contructor "<<i<<endl;
}
CMyClass(const CMyClass& other) {
cout<<"CMyClass copy contructor"<<endl;
}
~CMyClass() {
cout<<"CMyClass destructor"<<i<<endl;
}
void test() {
cout<<"test"<<endl;
}
private:
int i;
};测试代码:
//按值传递
void func1(auto_ptr<CMyClass> ap){ap->test();}
//按const引用传递
void func2(const auto_ptr<CMyClass>& ap){ap->test();}
//1.auto_ptr只能用于管理从new返回的一个对象,不支持new数组
//2.auto_ptr不能初始化为指向非动态内存
int main()
{
{
CMyClass* p = new CMyClass(1);
auto_ptr<CMyClass> ap1(p); //动态内存的所有权已转移到ap1,动态内存由ap1负责释放
//因为auto_ptr对内存的所有权独有,在析构时ap和ap1都试图删除p。
//两次删除同一个对象的行为在C++标准中是未定义的,所以应该防止两个auto_ptr拥有同一个对象(编译器不会报错)
auto_ptr<CMyClass> ap(p);
auto_ptr<CMyClass> ap2(new CMyClass(2));
auto_ptr<CMyClass> ap3(ap2);
//ap2->test(); //运行异常,因为动态内存的所有权已转移到ap3,动态内存由ap3负责释放
ap3->test();
auto_ptr<CMyClass> ap4(new CMyClass(4));
auto_ptr<CMyClass> ap5(new CMyClass(5));
//赋值前,由ap5指向的对象被删除,ap4指向的内存的所有权转移到了ap5(通过单步调试该行,可看出ap5指向对象的析构函数被调用)
ap5 = ap4;
//智能指针作为参数
//应谨慎使用智能指针作为参数传递,如果非要使用的话,请传递一个const引用
auto_ptr<CMyClass> ap6(new CMyClass(6));
auto_ptr<CMyClass> ap7(new CMyClass(7));
func1(ap6);
//ap6->test(); //error,调用func函数后,ap6已经不再拥有任何对象了
func2(ap7);
ap7->test(); //ok
//成员函数
//1.get()
//第一行与第三行相同,都是p1所在的那块内存的地址。第二行是ap8这个类对象本身所在内存的地址
CMyClass* p1 = new CMyClass(0);
auto_ptr<CMyClass> ap8(p1);
cout<<p1<<endl;
cout<<&ap8<<endl;
cout<<ap8.get()<<endl;
//2.reset()
//重新设置auto_ptr指向的对象。类似于赋值操作,但赋值操作不允许将一个普通指针直接赋给auto_ptr,而reset()允许
auto_ptr<CMyClass> ap9(new CMyClass(9));
ap9.reset(new CMyClass(10));
ap9.reset(0); //reset(0)可以销毁对象,释放内存
//3.release()
//返回auto_ptr指向的那个对象的内存地址,并释放对这个对象的所有权
//对于上面的ap和ap1同时拥有对p的所有权的问题,可以让其中一个先释放所有权
ap.release();
cout<<endl;
}
return 0;
}
2.unique_ptr
跟所指对象的内存紧紧的绑定在一起,不和其他的指针共享其指向的内存
3.shared_ptr
可以赋值,允许多个shared_ptr共享一块内存,它采用了引用计数的内存管理方式
4.weak_ptr
是为配合shared_ptr而引入的一种智能指针来协助shared_ptr工作
template <class T>
void IsPtrValid(weak_ptr<T>& wp) {
shared_ptr<T> sp = wp.lock();
if (sp != nullptr) {
cout << "shared_ptr is good" << endl;
}else{
cout << "shared_ptr is null" << endl;
}
}
int main()
{
//2.unique_ptr跟所指对象的内存紧紧的绑定在一起,不和其他的指针共享其指向的内存
//也就是说unique_ptr不能赋值给别的unique_ptr
unique_ptr<CMyClass> p(new CMyClass(1));
p->test();
//unique_ptr<CMyClass> p1 = p; //无法通过编译
CMyClass cls = *p;//调用CMyClass的复制构造函数,若想禁止调用复制构造函数,将复制构造函数生命诚private
cls.test();
p.reset(); //释放指针拥有的内存呢
//3.shared_ptr可以赋值,允许多个shared_ptr共享一块内存,它采用了引用计数的内存管理方式,
//因此当它放弃了所有权时并不会释放内存,不会影响其他引用这块内存的指针,只有当引用计数变为0时才会释放内存。
shared_ptr<CMyClass> sp(new CMyClass(2));
shared_ptr<CMyClass> spcopy = sp;
spcopy.reset();//减少引用计数,当引用计数为0时释放拥有的内存
sp.reset();
//shared_ptr作为类的成员变量的使用例子如下
//在CMyClass中声明:shared_ptr<CMyClass> m_sp;
//在CMyClass的构造函数中初始化:m_sp.reset();
//在使用时实例化:m_sp.reset(new CMyClass());
//在不再使用时释放:m_sp.reset();
//4.weak_ptr是为配合shared_ptr而引入的一种智能指针来协助shared_ptr工作
//weak_ptr可以指向shared_ptr指向的内存,但不拥有该内存,当调用lock时可以返回指向内存的shared_ptr
shared_ptr<CMyClass> sp1(new CMyClass(3));
weak_ptr<CMyClass> wp = sp1;
IsPtrValid(wp); //输出“shared_ptr is good”
sp1.reset();
IsPtrValid(wp);//输出“shared_ptr is null”
return 0;
}
转载请注明原文地址: https://ju.6miu.com/read-674094.html