effective c++ 08 以对象管理资源02

以对象管理资源02

请记住:任何技术都是一层窗户纸,一捅就破。只是起了一个牛逼的名字而已,我们花老爷grape告诉我,再怎么花哨的技术,无非就是封装、继承、多态而已。话不多说开始本节的重点智能指针(以对象管理资源)。
自C++11起,C++标准提供两大类型的智能指针:
  1. Class shared_ptr实现共享式拥有(shared ownership)概念。多个智能指针可以指向相同对象,该对象和其相关资源会在“最后一个引用(reference)被销毁”时候释放。为了在结构复杂的情境中执行上述工作,标准库提供了weak_ptr、bad_weak_ptr和enable_shared_from_this等辅助类,但我们一般用的weak_ptr比较多
  2. Class unique_ptr实现独占式拥有(exclusive ownership)或严格拥有(strict ownership)概念,保证同一时间内只有一个智能指针可以指向该对象。它对于避免资源泄露(resourece leak)——例如“以new创建对象后因为发生异常而忘记调用delete”——特别有用。

一.shared_ptr的使用
shared_ptr多个指针指向相同的对象。shared_ptr使用引用计数,每一个shared_ptr的拷贝都指向相同的内存。每使用他一次,内部的引用计数加1,每析构一次,内部的引用计数减1,减为0时,自动删除所指向的堆内存。shared_ptr内部的引用计数是线程安全的,但是对象的读取需要加锁。
1. 智能指针是个模板类,可以指定类型,传入指针通过构造函数初始化。也可以使用make_shared函数初始化。不能将指针直接赋值给一个智能指针,一个是类,一个是指针。例如std::shared_ptr pp = new int(10);的写法是错误的.
2. get函数可以获取原始指针
3. 请不要用一个原始指针初始化多个shared_ptr,否则会造成二次释放同一内存,导致出错。
看看下面的例子:

#include <iostream>
#include <memory>
int main() {
    {
        int a = 10;
        std::shared_ptr<int> ptra = std::make_shared<int>(a);
        std::shared_ptr<int> ptra2(ptra); //copy
        std::cout << ptra.use_count() << std::endl;//2

        int b = 20;
        int *pb = &a;
        //std::shared_ptr<int> ptrb = pb;  //error
        std::shared_ptr<int> ptrb = std::make_shared<int>(b);//1
        ptra2 = ptrb; //assign
        pb = ptrb.get(); //获取原始指针

        std::cout << ptra.use_count() << std::endl;//1
        std::cout << ptrb.use_count() << std::endl;//2
    }
}

结果:
在这里插入图片描述
请继续看:

class  A1
{
public:
	A1(int x,int y)
	{
		a = x;
		b = y;

	}
	void show()
	{
		cout << a << " " << b << endl;
	}
	int a, b;
	~A1()
	{
		cout << "~A1\n";
	}
};

void gogo()
{
	//类
	shared_ptr<A1>m_pp = make_shared<A1>(1, 2);
	m_pp->show();
	A1 *m_ap1 = new A1(100,200);
	shared_ptr<A1>m_spap1(m_ap1);
	m_spap1->show();
	//普通类型
	shared_ptr<int>m_pt = make_shared<int>(10);
	cout << *m_pt << endl;

	//int a = 20;
	//shared_ptr<int> m_myp(&a);//注意这样是不行的因为变量a在栈区。

	int *pa = new int(1000);
	shared_ptr<int> m_spa(pa);
	cout << *pa << endl;
	
}
int main() {
		
	
	gogo();
	
	system("pause");
}

结果:
在这里插入图片描述
二.unique_ptr的使用
 unique_ptr“唯一”拥有其所指对象,同一时刻只能有一个unique_ptr指向给定对象(通过禁止拷贝语义、只有移动语义来实现)。相比与原始指针unique_ptr用于其RAII的特性,使得在出现异常的情况下,动态资源能得到释放。unique_ptr指针本身的生命周期:从unique_ptr指针创建时开始,直到离开作用域。离开作用域时,若其指向对象,则将其所指对象销毁(默认使用delete操作符,用户可指定其他操作)。unique_ptr指针与其所指对象的关系:在智能指针生命周期内,可以改变智能指针所指对象,如创建智能指针时通过构造函数指定、通过reset方法重新指定、通过release方法释放所有权、通过移动语义转移所有权。

#include <iostream>
#include <memory>

int main() {
    {
        std::unique_ptr<int> uptr(new int(10));  
        //std::unique_ptr<int> uptr2 = uptr;  //不能赋值
        //std::unique_ptr<int> uptr2(uptr);  //不能复制
        std::unique_ptr<int> uptr2 = std::move(uptr); //装换所有权
        uptr2.release(); //释放所有权
    }
    }

继续看代码:

void gogog1()
{
	unique_ptr<A1>m_pp(new A1(1, 2));
	m_pp->show();
	m_pp.release();//转换之后m_pp为空
	m_pp->show();//会报错
}

当指针m_pp离开作用域后就会释放指针所指内存。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Effective C++》是由C++之父Bjarne Stroustrup所著的一本经典C++编程指南。这本书对于想要更深入理解和掌握C++编程的开发者来说是一本非常有用的资源。 《Effective C++》以52条编程规范的形式呈现,每一条规范都经过作者的亲身经历和经验总结。这些规范涵盖了C++中一些重要的概念、技术和最佳实践,从而帮助读者写出更高效、更健壮、更易维护的C++代码。 这本书主要分为多个部分,每个部分都聚焦于一个特定的主题。其中包括: 1. 构造/解构和赋值运算符重载:介绍了构造函数、析构函数、拷贝构造函数和赋值运算符的正确使用方式,避免内存泄漏和资源冲突。 2. 资源管理:提供了如何正确管理动态内存分配和资源使用的建议,包括智能指针、RAII等技术。 3. 类设计:讲解了类的设计原则和技巧,包括尽量使用const、规避对象切割等。 4. 继承与多态:介绍了如何正确使用继承和多态的技术,包括虚函数、多态对象的销毁等。 5. 异常安全:提供了如何处理异常以及避免资源泄漏的方法。 通过阅读《Effective C++》,读者可以学习到许多编写高质量C++代码的技巧和实践。作者结合自己在C++设计与开发中的丰富经验,以清晰的语言和易于理解的示例,帮助读者深入理解C++语言的特性和问题,并提供了解决方案。对于想要进一步掌握C++的开发者来说,这本书是一份不可或缺的参考资料。它不仅有助于提高代码质量,还能避免一些常见的陷阱和错误,从而使程序更加高效和可靠。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

发如雪-ty

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值