动态分配的对象(dynamically allocated object)

           动态分配的对象被分配在程序的空闲存储区free store 的可用内存池中。C++中一般用new来申请内存,delete来撤消new申请的内存。

       new有三种形式:

       1、支持单个对象动态分配

       例如:

      

int *p;
p = new int;

支持的类型有内置类型:int, double, char ....

还有自定义的类、结构体等等。

new成功后可直接初始化,如:

double *p;
p = new double(3.1415);

且结果返回的是一个指针,最后要用delete撤消。


       此外,C++标准库提供了auto_ptr类模板,它可以帮助程序员自动管理用new 表达式动态分
配的单个对象(不幸的是,对用new 表达式分配的数组管理没有类似的支持,我们不能用auto_ptr 存储数组。如果这样做了结果将是未定义的)。
       auto_ptr 对象被初始化为指向由new 表达式创建的动态分配对象。当auto_ptr 对象的生命期结束时,动态分配的对象被自动释放。也就是说不用delete来释放new申请的内存。

       auto_ptr类模板在memoy中,使用时要加进来。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 表达式创建的对象的类型

identifier 变量名

ptr_allocated_by_new 初始值,而且要是new出来

auto_ptr_of_same_type 同种类型的另一对象


      auto_ptr相关的一些操作:

      1)、赋值,如

auto_ptr<int> ptr (new int (100) );
auto_ptr<int> ptr2(new int(200) );

ptr = ptr2;

       在赋值之前由ptr 指向的对象被删除。赋值之后ptr 拥有int 型对象的所有权,该对象值为200, ptr2 不再被用来指向该对象。


        2)、get()操作,返回auto_ptr对象内部的底层指针。

        3)、reset()操作,设置auto_ptr对象底层指针。如:

auto_ptr <int> p;
if (p.get() != 0 && *p != 100)
     *p = 100;
else
     p.reset( new int (100) );

      最后,使用auto_ptr类要注意的两点:

       <1> 我们必须小心,不能用一个指向“内存不是通过应用new 表达式分配的”指针来初始化或赋值auto_ptr 。如果这样做了,delete 表达式会被应用在不是动态分配的指针上,这将导致未定义的程序行为。
       <2> 我们必须小心,不能让两个auto_ptr 对象拥有空闲存储区内同一对象的所有权。一种很显然犯这种错误的方法是,用同一个指针初始化或赋值两个auto_ptr 对象。另一种途径是通过使用get()操作。例如

auto_ptr< string >
pstr_auto( new string( "Brontosaurus" ) );
// 喔! 现在两个指针都指向同一个对象
// 并都拥有该对象的所有权
auto_ptr< string > pstr_auto2( pstr_auto.get() );

       release()操作允许将一个auto_ptr 对象的底层对象初始化或赋位给第二个对象,而不会使两个auto_ptr 对象同时拥有同一对象的所有权。release()不仅像get()操作一样返回底层对象的地址,而且还释放这对象的所有权。前面代码段可被正确改写如下
// ok: 两个对象仍然指向同一个对象
// 但是, pstr_auto 不再拥有拥有权
auto_ptr< string >
pstr_auto2( pstr_auto.release() );


       2、支持数组动态分配

       第一维可以是表达式、变量、常量,但不能为空,第二、三……维一定要是常量。如:

int *p = new int[1024];
int (*pp)[1024] = new int [2*3+1][1024];

       3、定位new表达式(placement new expresssion)

       定位new 表达式(placement new expression),可以允许程序员要求将对象创建在已经被分配好的内存中。使用时要包含头文件<new>。形式如下:

new (place_address) type -specifier

place_address 必须是个指针。如:

#include <iostream>
#include <new>

const int chunk = 16;
class Foo 
{
public:
   int val() { return _val; }
   Foo() { _val = 0; }
private:
   int _val;
};
// 预分配内存但没有Foo 对象
char *buf = new char[ sizeof(Foo) * chunk ];

int main() 
{
   // 在buf 中创建一个Foo 对象
   Foo *pb = new (buf) Foo;
   // 检查一个对象是否被放在buf 中
   if ( pb->val() == 0 )
   cout << "new expression worked!" << endl;

   // 到这里不能再使用 pb
   delete[] buf;
   return 0;
}
编译并执行该程序产生下列输出
new expression worked

      最后,说下常量对象的动态分配。

      在空闲存储区创建的const 对象有一些特殊的属性。首先,const 对象必须被初始化;第二,用 new 表达式返回的值作为初始值的指针必须是一个指向const 类型的指针。如:

const int *p = new const int ( 100);
.
.
.
delete p;







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值