placement new
来源:互联网 发布:c json转实体类 编辑:程序博客网 时间:2024/06/07 01:05
上一篇,我分析了 new , delete 现在来分析一下 placement new
placement new 的语法: new(address) constructed_function(..)
placement new 是以已分配的内存为this,来调用函数。在需要重复分配内存的情况下,
使用placement new 的效率是比较高的。
ok ! 下面我们来看一看,placement new的例子吧。
class test0{};
class test1
{
public:
test1(int i){};
}
void main
{
test0* ptest0 = new test0[10]; //能够使用,分配内存,调用test0无参构造函数。
//test1* ptest1 = new test1[10]; //不能够使用,因为test1没有无参的构造函数。
test1* ptest1= (test1*)new byte[sizeof(test1)*10]; //先分配内存.
for(int i = 0; i < 10; i++)
{ new(ptest1+i) test1(1); } //调用构造函数
}
ok ! placement new 的例子还很多。写这篇文章,主要是记录一下自己对placement new 的使用。
#include <stdlib.h>#include <stdio.h>class class111{public:class111(){m_name = "class111";printf("class111()\n");}~class111(){printf("~class111()\n");}void name(){printf("%s\n", m_name);}private:char* m_name;};class class222{public:class222(){m_name = "class222";printf("class222()\n");}~class222(){printf("~class222()\n");}void name(){printf("%s\n", m_name);}private:char* m_name;};class class333{public:class333(){m_name = "class333";printf("class333()\n");}~class333(){printf("~class333()\n");}void name(){printf("%s\n", m_name);}private:char* m_name;};class test{public:test(){m_pC1 = new class111();m_pC2 = new class222();m_pC3 = new class333();}~test(){delete m_pC1;delete m_pC2;delete m_pC3;}void memberNames(){m_pC1->name();m_pC2->name();m_pC3->name();}private:class111* m_pC1;class222* m_pC2;class333* m_pC3;};void main(){test t;t.memberNames();}
从上例中,我们可以看到 ,test的构造函数去,new成员变量,析构函数去delete成员变量。而这三个成员变量是随着test对象的存在,而存在,随着test对象的消亡
而消亡。所以,我们完全没有必要,三次new,和三次delete,我们只需一次new,和一次delete.这样就比较高效了。
#define LOGOUT(a)class test{public:test(){m_pBlock = (char*)malloc(sizeof(class111)+ sizeof(class222)+ sizeof(class333));if (nullptr == m_pBlock){LOGOUT("内存分配失败");return;}m_pC1 = new(m_pBlock) class111();m_pC2 = new(m_pBlock+sizeof(class111)) class222();m_pC3 = new(m_pBlock + sizeof(class111) + sizeof(class222)) class333(); //好恶心}~test(){if (nullptr == m_pBlock)return;m_pC1->~class111();m_pC2->~class222();m_pC3->~class333();free(m_pBlock);}void memberNames(){if (nullptr == m_pBlock)return;m_pC1->name();m_pC2->name();m_pC3->name();}private:char* m_pBlock;class111* m_pC1;class222* m_pC2;class333* m_pC3;};void main(){test t;t.memberNames();}
#define LOGOUT(a)class test{DECLARE_SMART_MEM(test);public:test(){USE_SMART_MEM(test, m_pC1, m_pC2, m_pC3);if (IS_TRUE(SMART_MEM_FAIL(test))){LOGOUT("内存分配失败");return;}m_pC1->class111::class111(); //m_pC1 = new(m_pC1) class111(); 我喜欢这样写,因为不需要手动delete,所以m_pC2->class222::class222(); // 我不喜欢出现newm_pC3->class333::class333();}~test(){if (IS_TRUE(SMART_MEM_FAIL(test)))return;m_pC1->~class111();m_pC2->~class222();m_pC3->~class333();}void memberNames(){if (IS_TRUE(SMART_MEM_FAIL(test)))return;m_pC1->name();m_pC2->name();m_pC3->name();}private:class111* m_pC1;class222* m_pC2;class333* m_pC3;};void main(){test t;t.memberNames();}
/**author: zyb* \brief smart_mem*/#pragma once#include <stdlib.h>#include <new.h>#include "commonMacro.h"#define _MYLIBSTART namespace mylib{#define _MYLIBEND}_MYLIBSTARTtemplate<class _Ty>struct is_pointer{static constexpr bool value = false;};template<class _Ty>struct is_pointer<_Ty*>{static constexpr bool value = true;};template<class _Ty>class auto_free{public:typedef auto_free<_Ty> _Myt;auto_free(_Ty* _ptr = 0) noexcept{_Myptr = _ptr;}~auto_free() noexcept{if (NOT_NULLPTR(_Myptr))free(_Myptr);}_Myt& operator= (_Ty* _ptr) noexcept{if (NOT_NULLPTR(_Myptr))free(_Myptr);_Myptr = _ptr;return *this;}bool isnullptr() const noexcept{return IS_NULLPTR(_Myptr);}private:_Ty* _Myptr;};template<class _Ty>constexpr int pointer2class_size(_Ty* pParam) noexcept{(pParam);return sizeof(_Ty);}template<class _Ty, class... _Types>constexpr int params_size(_Ty& first, _Types&... params) noexcept{static_assert(is_pointer<_Ty>::value, "params must be pointer");return pointer2class_size(first) + params_size(params...);}constexpr int params_size() noexcept{return 0;}template<class _Ty, class... _Types>inline void init_params(char* pBlock, _Ty& first, _Types&... params) noexcept{first = (_Ty)pBlock;init_params(pBlock + pointer2class_size(first), params...);}inline void init_params(char* pBlock) noexcept{(pBlock);}template<class _Ty, class... _Types>void* smart_mem_alloc(_Ty& first, _Types&... params) noexcept{char* pBlock =(char*)malloc(params_size(first, params...));if (IS_NULLPTR(pBlock))return nullptr;init_params(pBlock, first, params...);return (void*)pBlock;}_MYLIBEND#undef _MYLIBSTART#undef _MYLIBEND#define DECLARE_SMART_MEM(classname)\private:\mylib::auto_free<void> m_##classname##_blockptr#define USE_SMART_MEM(classname,...)\m_##classname##_blockptr =\mylib::smart_mem_alloc(__VA_ARGS__)#define SMART_MEM_FAIL(classname)\m_##classname##_blockptr.isnullptr()
00D41080 push ecx
00D41081 push esi
00D41082 mov esi,ecx
00D41084 push edi
USE_SMART_MEM(test, m_pC1, m_pC2, m_pC3);
00D41085 push 0Ch //param_size直接计算出三个变量的总大小。sizeof(class111) = 4 sizeof(class222) = 4 sizeof(class333) = 4 4+4+4 = 0ch
{
00D41087 mov dword ptr [esi],0
00D4108D call dword ptr [__imp__malloc (0D42054h)] //malloc(0ch) 分配内存
00D41093 mov edi,eax
00D41095 add esp,4
00D41098 test edi,edi
00D4109A je test::test+2Bh (0D410ABh)
00D4109C lea eax,[edi+4]
00D4109F mov dword ptr [esi+4],edi
00D410A2 mov dword ptr [esi+8],eax
00D410A5 add eax,4
00D410A8 mov dword ptr [esi+0Ch],eax
00D410AB mov eax,dword ptr [esi]
00D410AD test eax,eax
00D410AF je test::test+3Bh (0D410BBh)
00D410B1 push eax
00D410B2 call dword ptr [__imp__free (0D4204Ch)]
00D410B8 add esp,4
00D410BB mov dword ptr [esi],edi //保存分配的内存
if (IS_TRUE(SMART_MEM_FAIL(test)))
00D410BD test edi,edi
00D410BF je test::test+83h (0D41103h) //跳转为分配失败
{
LOGOUT("内存分配失败");
return;
}
- placement new
- placement new
- placement new
- placement new
- placement new
- placement new
- placement new
- placement new
- placement new
- placement new
- placement new
- placement new
- placement new
- new placement
- placement new
- placement new
- Placement New
- Placement new
- 浅谈BroadcastReceiver
- SpringBoot整合Sentry监控项目日志
- SpringBoot整合Rabbitmq设置消息请求头
- HttpSession工作原理简介
- vs2015学习qt562_64位的opencv人脸检测项目工程配置
- placement new
- 浅谈 css 之 position用法
- content-type
- 【Git】4.Eclipse中Git的使用
- java代理
- D002_Java简单数据类型转换和包装类
- Unity3D-移动障碍物之吊桥
- poj-3604(数论+推导)
- 深入理解JavaScript编程中的同步与异步机制