关于placement new

何为placement new呢?placement new 是重载operator new的一个标准、全局的版本,它不能被自定义的版本代替(不像普通的operator new和operator delete能够被替换成用户自定义的版本)。

首先我们区分下几个容易混淆的关键词:new operator、operator new、placement new 。

对于new operator,其实它是语言内建的,我们是没有办法改变它的。当我们创建了一个new表达式时,会发生两件事。首先,使用operator new()分配内存,然后调用构造函数。现在明白了吧,new operator会去调用operator new()跟创建对象的构造函数,我们能控制的,只有内存的分配函数operator new()(对于operator delete()也是一样)。所谓控制,其实就是重载这个函数,编译器将用重载的operator new代替默认的版本去分配内存。

接下来就是要说的placement new了。其实它也是operator new重载的一个版本,只是很少人用到它。它有一个特点,就是允许你在已经分配好的内存上创建一个对象,也就是说,可以通过某种手段在指定的内存创建对象。

好了,说到这里,我们就可以利用它来做一些高效率的事情了。

当我们用new分配对象数组空间时,会自动调用对象的默认构造函数。可是如果数组只有一部分元素会被使用,或者元素立即被赋值,那刚刚自动调用对象的默认构造函数不就等于白做了吗?这时候placement new就发挥作用了,因为它可以在分配好的缓冲区上创建对象。采用这种方式,缓冲区占用的存储区的分配,可以避免被默认的构造函数初始化:

const size_t n = sizeof(string) * 30;

string *sbuf = static_cast<string *>(::operator new(n));/*这时候是直接调用operator new函数来分配内存的,也就是说,只会分配空间,类似于malloc。*/

下面是一个在分配好的内存空间上创建对象的函数:

void append(string buf[], int &size, const string &val)

{new (&buf[size++] string(val);}//palcement new

这样的话,我们就可以在需要的情况下使用pacement new通过复制构造函数来初始化数组里的元素,在一些情况下能够提高程序的效率。

但这样的话我们就得自己来负责清理工作了,凡事有利必有弊吧。

这里得通过显式调用string的析构函数,如:

buf[size].~string();

并用operator delete来释放存储区:

::operator delete(buf);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值