当前位置:天才代写 > tutorial > C语言/C++ 教程 > 对auto_ptr的进修

对auto_ptr的进修

2017-11-04 08:00 星期六 所属: C语言/C++ 教程 浏览:853

副标题#e#

auto_ptr是C++尺度库提供的类模板,它可以辅佐措施员自动打点用new表达式动态分派的单个工具,不外对用new表达式分派的数组打点没有雷同的支持,不能用auto_ptr存储数组,假如这样做了,功效将是未界说的.

auto_ptr工具被初始化为指向由new表达式建设的动态分派工具.当auto_ptr工具的生命期竣事时,动态分派的工具被自动释放.

在利用auto_ptr类模板之前,必需包括下面的头文件:

#include <memory>

auto_ptr工具的界说有下面三种形式:

  auto_ptr<type_pointed_to> identifier(ptr_allocated_by_new);
  auto_ptr<type_pointed_to> identifier(auto_ptr_of_same_type);
  auto_ptr<type_pointed_to> identifier;

type_pointed_to代表由new表达式建设的工具的范例.在最常见的环境下,我们但愿把auto_ptr直接初始化为new表达式返回的工具地点.可以这样来做:

auto_ptr<int> pi(new int(1024);

pi被初始化为由new表达式建设的工具的地点,且该工具的初始化值为1024.可以查抄auto_ptr所指的工具的值,方法与普通指针沟通:

if (*pi != 1024);

new表达式建设的工具由pi指向,当pi的生命期竣事时,它将被自动释放.假如pi是全局工具,则pi所指向的工具在措施竣事时释放.

假如我们用一个class范例的工具初始化auto_ptr工具,好比尺度的string范例,则:

auto_ptr<string> pstr_auto(new string("Hello world"));

假设此刻但愿会见一个字符串操纵,对付普通的string指针,会凭据下面这样来做:

string* pstr_type = new string("Hello World");

pstr_type->size();

那么,用auto_ptr也是一样的方法:

auto_ptr<string> pstr_auto(new string("Hello world"));

pstr_auto->size();

auto_ptr类模板背后的主要念头是支持与普通指针范例沟通的语法,可是为auto_ptr工具所指工具的释放提供自动打点.同时,利用auto_ptr工具并不比直接利用指针价钱更高.

在下面的环境中,用pstr_auto的值初始化pstr_auto2,而且pstr_auto的底层工具是string,会奈何呢?

auto_ptr<string> pstr_auto2(pstr_auto);

假定直接用一个string指针初始化别的一个,好比:

string* pstr_type2(pstr_type);

那么,这两个指针都持有措施空闲存储区内的字符串地点,我们必需小心地将delete表达式只应用在一个指针上,而auto_ptr类模仿支持所有权观念.

当界说auto_ptr时,它知道本身对初始化字符串拥有所有权,而且有责任删除该字符串,这是所有权授予auto_ptr工具的责任.

问题是,当pstr_auto2被初始化为指向与pstr_auto沟通的工具时,所有权会产生什么样的变革?我们不但愿让两个auto_ptr工具都拥有同一个底层工具–这会引起反复删除工具的问题,这也是我们利用auto_ptr范例首先要防备的.


#p#副标题#e#

当一个auto_ptr工具被用另一个auto_ptr工具初始化或赋值时,左边被赋值或初始化的工具就拥有了空闲存储区内底层工具的所有权,而右边的auto_ptr工具则除掉所有责任.于是,在我们的例子中,将是用pstr_auto2删除字符串工具,而不是pstr_auto,pstr_auto不再被用来指向字符串工具.

雷同的行为也产生在赋值操纵符上,已知下列两个auto_ptr工具.

auto_ptr<int> p1(new int(1024));

auto_ptr<int> p2(new int(2048));

赋值操纵符可以将一个auto_ptr工具拷贝到另一其中,如下所示:

p1 = p2;

在赋值之前,由p1指向的工具被删除.赋值之后,p1拥有int型工具的所有权,该工具值为2048,p2不再被用来指向该工具.

在auto_ptr界说的第三种形式中,我们建设一个auto_ptr工具,可是没有用指针将其初始化.譬喻:

auto_ptr<int> p_auto_int;

因为p_auto_int没有被初始化指向一个工具,所以它的内部指针值被配置为0,这意味着对它解引用会使措施呈现未界说的行为,就仿佛我们直接解引用一个值为0的指针时所产生的一样.

对付普通指针,我们只需测试是否为0,譬喻:

if (pi != 0);

可是奈何测试一个auto_ptr工具是否指向一个底层工具呢?操纵get()返回auto_ptr工具内部的底层指针,所觉得了判定auto_ptr指针是否指向一个工具,可以如下编程:

  int *pi = 0;
  if (p_auto_int.get() != 0 && *p_auto_int != 1024)
  *p_auto_int = 1024;

假如它没有指向一个工具,那么奈何使其指向一个呢?即奈何配置一个auto_ptr工具的底层指针?我们可以用reset()操纵,譬喻:

p_auto_int.reset(new int(1024));

我们不可以或许在auto_ptr工具被界说之后,再用new表达式建设工具的地点来直接向其赋值,因此,我们不能这样写:

  void example()
  {
  auto_ptr<int> pi;
  {
  pi = new int(4);
  }
  }

#p#分页标题#e#

假如为了重置一个auto_ptr工具,我们必需利用reset()函数,我们可以向reset()通报一个指针,假如不但愿配置该auto_ptr工具的话,可以通报一个0值.假如auto_ptr当前指向一个工具而且该auto_ptr工具拥有该工具的所有权,则该工具在底层指针被重置之前,首先被删除,譬喻:

auto_ptr<string> pstr_auto(new string("Hello World"));

pstr_auto.reset(new string("YES")); //在重置之前删除工具Hello World

在这种环境下,用字符串操纵assign()对原有的字符串工具从头赋值,比删除原有的字符串工具并从头分派第二个字符串工具更为有效:

//这种环境下,重置的更有效

pstr_auto->assign("YES");

#p#副标题#e#

措施设计的一个难事是:有时候仅仅获得正确的功效是不足的,有时候,我们不只需要正确的功效,并且还需要一个可接管的机能,像挪用assign()有效释放和重分派一个字符串这样的小细节就是一个很好的例子,它说明在某些环境下,这些小细节会积累成可骇的机能瓶颈.

auto_ptr类模板为动态分派内存提供了大量的安详性和便利性,可是我们仍需小心,不然就会陷入贫苦.

1.我们必需小心,不能用一个指向"内存不是通过应用new表达式分派的"指针来初始化或赋值auto_ptr.假如这样做了,delete表达式会被应用在不是动态分派的指针上,这将导致未界说的措施行为.

2.我们必需小心,不能让两个auto_ptr工具拥有空间存储区内同一工具的所有权.一种很显然犯这种错误的要领是,用同一个指针初始化或赋值两个auto_ptr工具,另一个途径是通过get()操纵,譬喻:

auto_ptr<string> pstr_auto(new string("HELLO"));

auto_ptr<string> pstr_auto2(pstr_auto.get());

release()操纵答允将一个auto_ptr工具的底层工具初始化或赋值给第二个工具,而不会使两个auto_ptr工具同时拥有同一个工具的所有权.release(0不权像get()一样返回底层工具的地点,并且还释放该工具的所有权,前面代码可被改写如下:

auto_ptr<string> pstr_auto2(pstr_auto.release());

此时两个工具仍然指向同一个工具,可是pstr_auto不再拥有拥有权.

 

    关键字:

天才代写-代写联系方式