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的五体投地,如果不知,去看看书吧,不过看完以后,你也会感觉,扣的真是
太细了。
指针是一个很让人头疼的东西,因为你不知道申请的指针是否已经正确释放,即使你写上了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的五体投地,如果不知,去看看书吧,不过看完以后,你也会感觉,扣的真是
太细了。