c++ new的用法

c++ new 用法

 

c++ 中new 的用户有  newoperator , operator new  和 placemenet new

1 new operator

如下代码:

string *ps=new string("memory management");

这里所使用的new就是所谓new operator,是由C++语言内建的,就像sizeof那样,不能改变意义,总是做相同的事情。

这个动作的含义分为两方面:

第一,它分配足够的内存,用来放置某类型的对象。对于上例而言,它分配足够放置一个string 对象内存。

第二,它调用一个构造函数,为刚才分配的内存中的那个对象设定初始值。

new operator总是做这两件事,无论如何你是不能改变其行为。



2operator new

能够改变的是用来容纳对象的那块内存的分配行为,new operator调用某个函数,执行必要的内存分配动作,你可以重写或者重载那个函数,改变其行为。这个函数名称就叫operator new 。

函数 operator new 通常声明如下:

void * operator new (size_t size);

其返回类型void*。即返回一个指针,指向一块原始的、未设置初始值的内存

函数中的size_t参数表示需要分配多少内存,你可以将operator new 重载,加上额外的参数,但第一个参数类型必须总是size_t。

或者你从来没有直接用过operator new ,但是你可以像调用任何其他函数一样地调用它

void* rawMemory=operatornew(sizeof(string));

这里的operator new 将返回指针,它指向一块足够容纳string对象的内存。

和malloc一样,operator new 的唯一任务就是分配内存,它不知道什么是构造函数,它只负责分配内存。

取得operator new 返回的内存并将之转为一个对象,是newoperator的责任。

 

微软msdn的例子

//new_op_new.cpp
//compile with: /EHsc
#include<new>
#include<iostream>
 
usingnamespace std;
 
classMyClass
{
public:
   MyClass( )
   {
      cout << "ConstructionMyClass." << this << endl;
   };
 
   ~MyClass( )
   {
      imember = 0; cout << "DestructingMyClass." << this << endl;
   };
   int imember;
};
 
int main()
{
   // The first form of new delete
   MyClass* fPtr = new MyClass;
   delete fPtr;
 
   // The second form of new delete
   MyClass* fPtr2 = new( nothrow ) MyClass;
   delete fPtr2;
 
   // The third form of new delete
   char x[sizeof( MyClass )];
   MyClass* fPtr3 = new( &x[0] ) MyClass;
   fPtr3 -> ~MyClass();
   cout << "The address of x[0] is :" << ( void* )&x[0] << endl;
}


输出结果

Construction MyClass.000B3F30
Destructing MyClass.000B3F30
Construction MyClass.000B3F30
Destructing MyClass.000B3F30
Construction MyClass.0023FC60
Destructing MyClass.0023FC60
The address of x[0] is : 0023FC60


 

 

3. placement new

3.1 有时候你真的会想直接调用一个构造函数,针对一个已经存在的对象调用其构造函数,并无意义,因为构造函数用来对象初始化,而对象只能初始化一次。但是你偶尔会有一些分配好的原始内存,你需要在上面构建对象,有一个特殊的地方 operator new 称为placement new,允许这么做。

例如:

class Widget {   public:  Widget(int widgetSize);    ...... };

Widget* constructWidgetInBuffer(void*buffer,int size) {   return new (buffer) Widget(size); }

此函数返回指针,指向一个Widget object,它被构造于传递给此函数的一块内存缓存区上。当程序运行到共享内存或者内存I/O映射。这类函数可能是有用的,因为在那样运用中,对象必须置于特定的地址,或者置于特殊函数分配出来的内存上。

3.2 函数内部

Widget* constructWidgetInBuffer 只有一个表达式new (buffer) Widget(size),

有点奇怪,其实不足为奇,这是new operator的用法之一,指定一个额外的自变量(buffer)作为new operator "隐式调用operator new "。于是,被调用的operator new 除了接受"一定要有size_t自变量"之外,还接受了一个void* 参数,指向一块内存,准备用来接受构造好的对象这样的operator new 就是所谓的placement new :

void * operator new(size_t size,void*location)

{

 return location;

}

operator new 的目的是要为对象找到一块内存,然后返回一个指针指向它,在placement new 的情况下,调用者已经知道指向内存的指针了,因为调用者知道对象应该放在哪里。因此placement new 唯一需要做的就是将它获得的指针再返回。

至于没有用到(但一定得有)的size_t参数,之所以不赋予名称,为的是避免"编译器某物未被使用"的警告。

4  总结

另外注意:placement new 是C++标准程序库的一部分,要使用placement new 得用#include<new>,旧式编译器用#include<new.h>

回头想想placement new ,我们便能了解new operator和operator new之间的关系。

两个术语表面上令人迷惑,但其实很好理解:

1)如果你希望将对象产生于heap,就是得new operator,它不但分配内存而为该对象调用一个构造函数。

2)如果你只是打算分配内存,请用operator new,就没有构造函数被调用。

3)如果你打算在heap object产生自己决定的内存分配方式,请写一个自己的operator new。并使用new operator,它将会自动调用你所写的operator new。

4)如果你打算在已经分配(并拥有指针)的内存构造对象,请使用placement new 。

 


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值