Effective C++ 读书笔记 2

本文探讨了使用C++智能指针管理资源的有效方法,包括auto_ptr和shared_ptr的应用,以及它们如何帮助避免内存泄漏。介绍了通过引用计数机制实现的shared_ptr,允许多个智能指针共享同一资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

13 以对象管理资源
   指针是一个很让人头疼的东西,因为你不知道申请的指针是否已经正确释放,即使你写上了delete
   举一个例子
   void f()
  {
     char *p = new char[100];
     if(p)
     {
    .....
        一些异常导致跳出
        或者对一些情况直接return
        .....
     }
     delete []p;
  }
  上面的例子会有很多让你想不到的内存泄漏的机会,怎么办呢,C++提供了用对象管理资源的方法,这

里的资源的范围很广了,比如内存啊,互斥对象啊,画刷画笔一些乱七八糟的啊,等等。
  思想很简单,在构造函数中将指针传给对象,由于跳出作用域后局部对象自身会调用析构函数,所以可

以在类的析构函数中去delete指针,unlock互斥锁,release内核对象等。
   最简单的就是auto_ptr这个类了
   tr1::auto_ptr<char> ap(new char[100]);
   这样就可以通过ap来访问分配的内存空间了,在异常跳出,return等乱七八糟的情况下,这个内存空

间都能够正确的释放掉。
   但是,一个指针只能被一个auto_ptr对象管理,实际上在进行拷贝和赋值时,会将原来对象的指针设

置为0


14 在资源管理类中小心copy行为
   文中首先举了个禁止复制的例子,禁止复制和拷贝函数主要有两种方法,前面已经讲到过了,一种是

将两个函数声明为private,并且不实现;另一种方法是创建一个基类,将基类的构造函数设为private
   shared_ptr是一个能够允许多个智能指针指向同一个内存单元的一种智能指针,因此它叫做shared
   tr1::shared_ptr<char> sp1(new char[100]);
   tr1::shared_ptr<char> sp2(sp1);
   sp1、sp2都能正常对字符串进行操作
   它是如何实现的呢?
   通过引用计数
   这个引用计数放在什么地方?
   是作为每个类对象的成员变量存在吗?
   似乎不是,举个例子
   tr1::shared_ptr<char> sp1(new char[100]);
   tr1::shared_ptr<char> sp2(sp1);
   tr1::shared_ptr<char> sp3(sp2);
   这时, sp1的引用计数为2,而sp2和sp3的引用计数为3,不能保持一致
   怎么办呢,我查了一些书,好想有下面几种方法
   a. int *use;
   把一个int型的指针作为成员变量,这样不就实现多个对象共享一个引用计数了吗,这种方法最简单
   b. 封装类
   实际的指针和引用计数都封装在这个类中,然后多个对象指向这个封装类
   c.
   ms string 指针指向的内存单元的前几个字节里,有一段放的就是引用计数。

15 资源类中提供对原始资源的访问
   没什么好说的, get()函数返回指向原始资源的指针。
   不过这一节发现了一个我根本不知道的东西,试看下面的代码
   class A
   {
   public:
        A(int n = 0):m_nVal(n){}    
   private:
        int m_nVal;
   };
   void main()
   {
    A a(5);
    int n = a;
   }
  这段代码没什么意义,就是为了测试,当然他通不过编译,对类进行怎样的修改,它能通过编译呢?
  呵呵,加一行语句 operator int() const{return m_nVal;}

16 new和delete要采用相同的形式
   嗯,如果是delete,直接调用类的析构函数,然后释放空间完事。如果是delete [],他要首先查找
要释放多少个对象(这个数字被写入了指针所指向的内存的前几个字节),然后逐个调用构造函数,最后

释放空间。


17 以独立语句将newed对象置入智能指针
   我先不说话,先看下面的代码
   int priority();
   void processwidget(shared_ptr<Widget> sp, int priority);
   processwidget(shared_ptr<Widget>(new Widget), priority());
   有什么潜在的内存泄漏风险吗?
   如果你知道,我真是pf的五体投地,如果不知,去看看书吧,不过看完以后,你也会感觉,扣的真是

太细了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值