《C++ primer(第四版)》读书笔记6

第18章. 特殊工具与技术


注意:new表达式,placement new表达式,delete表达式,operator new 和 operator delete标准库函数之间的区别

a:operator new 和 operator delete标准库函数只是new和delete表达式操作的第一步(见下)。而placement new负责构造对象。可以通过改写类成员operator new 和 operator delete函数,来改变operator new和delete的默认行为(改写仍可以调用全局的库函数: Type *p=::new Type;   ::delete p,注意如果调用全局,则new和delete都调用全局)

new表达式步骤 string *sp=new string("initialized"):
1)调用operator new标准库函数(如果是类对象可改写),分配足够大的原始的未类型化的内存,以保存指定类型的一个对象
2)运行该类型的一个构造函数,用指定初始化式构造对象
3)返回指向新分配并构造的对象的指针

delete表达式步骤 delete sp;
1)对sp指向的对象运行适当的析构函数
2)通过调用operator delete的标准库函数释放该对象所用内存
  • 预分配空间而不构造对象,与释放空间而不析构对象

1)alloc.allocate(newcapacity),alloc.deallocate(elements,end-elements)
2)使用operator new和delete标准库函数,一般是供new和delete表达式使用,但也可以直接调用

1.
T* newelements=alloc.allocate(newcapacity);
T* newelements=static_cast<T*>(operator new[](newcapacity*sizeof(T)));

2.
alloc.deallocate(elements,end-elements);
operator delete[](elements);

使用allocator类的方法比直接使用operator new和operator delete函数更为类型安全
operator函数它们是在void*指针而不是类型化的指针上进行操作。
allocate成员分配类型化的内存,所以使用它的程序可以不必计算以字节为单位的所需内存量,它们也可以避免对operator new的返回值进行强制类型转换。类似地,deallocate释放特定类型的内存,也不必转换参数为void*



new表达式与operator new函数,以及delete表达式与operator delete函数是不同的
我们可以重定义operator标准库函数,但不能重新定义new和delete表达式的行为



  • 不分配空间而构造对象
1)alloc.construct(first_free,t);   //first_free为一指针
2)使用placement new:new (first_free) T(t);    //初始化列表可以为空
placement new表达式比allocator类的construct成员更灵活placement new表达式初始化对象时,可以使用任何构造函数,并直接建立对象。construct函数总是使用复制构造函数。
对某些类而言,使用复制构造函数是不可能的(因为复制构造函数是私有的),或者应该避免的,在这种情况下,也许有必要使用placement new表达式。


  • 不释放空间而析构对象

1)alloc.destroy(p)  //p为一指针
2)显式调用析构:p->~T()   //析构,但不释放空间。而operator delete函数不会允许析构函数,它只释放特定的内存


类接管自己的内部数据结构的内存管理,用allocator类。
另一种优化内存分配的方法设计优化new表达式的行为,通过定义成员new和delete函数,即operator new和operator delete成员。
如果类定义(或继承)了自己的成员new和delete函数,则使用那些函数为对象分配和释放内存;否则,调用这些函数的标准库版本

注意:如果类定义了这两个成员中的一个,它也应该定义另一个

类成员operator new函数必须具有返回类型void*并接受size_t类型的形参。由new表达式用以字节计算的分配内存量初始化函数的size_t形参
类成员operator delete函数必须具有返回类型void。它可以定义接受单个void*类型形参,也可以定义为接受两个形参,即void*和size_t类型。由delete表达式用被delete的指针初始化void*形参,该指针可以是空指针。如果提供了size_t形参,就由编译器用第一个形参所指对象的字节大小自动初始化size_t形参。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值