C++之智能指针

智能指针:动态内存管理是由一对运算符完成的:new和delete。默认情况下,动态分配的对象是默认未初始化的,这意味着内置类型和组合类型的值将是未定义的,而类类型对象将用默认构造函数进行初始化。

string *ps = new string;   //定义一个指向字符串的指针,初始化为空
int* pi = new int;       //pi指向一个未初始化的int

动态内存管理会出现两种问题:
1、忘记释放内存,会造成内存泄漏;
2、在有指针引用的情况下就释放了它,就会产生引用非法内存的指针。

所以,为了更加安全的使用动态内存,引入了智能指针的概念。智能指针是一个类,重载了->和*操作符。由类来实现对动态内存的管理,所有的智能指针都有一个explicit构造函数。
explicit关键字:使用该关键字修改的构造函数,将不能使用隐式转换,只能通过强制类型转换
auto_ptr:auto_ptr在进行拷贝构造时,内部会发生资源访问元的移交,所以在拷贝构造或者赋值时,原智能指针将不能再次去访问资源。

class Test
{
	public:
		Test(string s)
		{
			str = s;
			cout << "Test create" <<endl;
		}
		~Test()
		{
			cout << "test delete " << endl;
		}
    	void print()
        {
            cout << "str = " << str << endl;
        }
}
int main()
{
    auto_ptr<Test> p(new Test("abc"));   //调用构造函数
    auto_ptr<Test> p2(new Test("ghh"));   //调用构造函数
    p2 = p;    //将p的地址拷贝给p2,此时释放p,调用p的析构函数
    p2->print();
}

unique_ptr:在auto_ptr基础上禁用拷贝构造和赋值运算符重载函数;

 	unique_ptr& operator=(const unique_ptr&) = delete;
	unique_ptr(const unique_ptr&) = delete;

使用unique_ptr无法使用拷贝构造函数,无法进行复制操作,应该使用std::move函数。unique_ptr指向的堆内存无法同其他unique_ptr共享,即每个unique_ptr独自拥有最其所指堆内存的空间的所有权。

int main()
{
    unique_ptr<Test> p = new Test("asdd");  //错误使用,不能使用复制操作
    unique_ptr<Test> p(new Test("asdd"));   //调用构造函数
    unique_ptr<Test> p2(new Test("ghjjj"));  //调用构造函数
    p2 = move(p);  //调用了move后p2原本的对象会被释放,指向p的对象   
}

shared_ptr:shared_ptr是基于“引用计数”的实现,多个shared_ptr指向同一块动态堆内存,并维护一个共享的引用计数器,记录了引用同一个对象的shared_ptr实例的数量。当最后一个指向动态对象的shared_ptr销毁时,会自动销毁其所指对象。

int main()
{
    //空的shared_ptr指针,他的引用计数是0
    shared_ptr<int> p1;   //不传入任何实参
    shared_ptr<int> p2(nullptr);   //传入空指针nullptr
    
    //用具体值初始化智能指针对象指向的内存
    shared_ptr<int> p1(new int(1111));
    cout << *p1 << endl;
    
    //用另一个智能指针对象初始化当前指针对象
    shared_ptr<int> p2 = p1;
    
    //shared_ptr<int> p4 = make_shared<int>(2);
    
    //通过成员函数use_count()来查看资源的所有者个数
    cout<<p2.use_count()<<endl;
    p1.reset();  //重新绑定对象,当还有指针指向对象绑定该地址时,就不会释放该对象的内存空间
    p2.reset();  //当p2是最后一个绑定该对象的指针时,释放该内存,调用析构函数
    
}  

weak_ptr:要搭配 shared_ptr 一起使用,weak_ptr不会增加资源的引用计数,weak_ptr 不能直接用来访问资源。需要用 lock 方法转换为shared_ptr ;

int main()
{
    shared_ptr<int> sp1,sp2;
    weak_ptr<int> wp;
    
    sp1 = make_shared_ptr<int>(20);    //初始化shared_ptr
    wp = sp1;        //sp1  ,wp 指向同一对象   
    
    sp2 = wp.lock();   //sp2指向 
    sp1.reset();       //释放sp1
    
    sp1 = wp.lock();    //将sp1加入
    
    return 0;   
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值