在栈上new出一个对象

new operator的作用:首先会在堆上开辟一段空间(调用的是operator new函数,其实底层实际调用的是malloc),

然后调用new operator后面的typename的构造函数(如果是普通类型则不需要),

最后new operator typename会返回一个指向该堆的内存地址.

如果想要在栈上调用new operator:我们需要做的就是不让new operator调用operator new函数,

而是自己在栈上开辟好一段空间,

然后通过调用placement new (是operator new的重载)将该空间的地址传入.

为方便观察,我们在一个自定义类中重写全局的placement new函数.

#include <iostream>
class NewStackObj
{
public :
        NewStackObj(){}
        ~NewStackObj(){}
        static void* operator new(std::size_t size,void *p);
        static void  operator delete(void *,void *);
};
void* NewStackObj::operator new(std::size_t size,void *p) 
{
        std::cout << "overwrite placement new" << std::endl;
        if(!p)
                return ::operator new(size);
        return p;
}
void NewStackObj::operator delete(void *,void *)
{
        std::cout << "overwrite placement delete" << std::endl;
        return;
}
int main()
{
        char mem[sizeof(NewStackObj)];
        NewStackObj *p = NewStackObj::new(mem) NewStackObj();
}
其中的mem在栈上,且其指向的内存空间也在栈上,内存空间的大小可以放下一个NewStackObj的大小,当执行NewStackObj::new(mem) NewStackObj的时候,调用的是我们自定义的placement new.

全局的placement new的声明和实现如下:

inline _LIBCPP_INLINE_VISIBILITY void* operator new  (std::size_t, void* __p) _NOEXCEPT {return __p;}  
inline _LIBCPP_INLINE_VISIBILITY void* operator new[](std::size_t, void* __p) _NOEXCEPT {return __p;}  
inline _LIBCPP_INLINE_VISIBILITY void  operator delete  (void*, void*) _NOEXCEPT {}  
inline _LIBCPP_INLINE_VISIBILITY void  operator delete[](void*, void*) _NOEXCEPT {} 

std::size_t size其实就是需要的内存空间的大小,比如我们这里传入的NewStackObj(),它会将NewStackObj对象的大小传入,(如果是基础类型比如int *p = new int,传入的大小是sizeof(int)),然后void*就是我们需要传入的已经开辟好的内存空间的地址,比如我们这里传入的mem.


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值