用new在指定内存构造对象

C++中使用new进行系统调用分配内存,与C语言中的malloc分配内存的本质区别在于malloc只是在堆上开辟一块内存,而new不但开辟内存而且还调用了对象构造函数进行初始化,最后返回相应指针。
如:A* p = new A;
    A* p = new(std::nothrow)A;//如果分配内存失败不抛出异常,返回NULL指针
另外new作为函数可以在指定内存上分配构造对象的。
形式如下:
new (ptr)A();
利用placement new可以在栈上分配对象:
char buff[1024];
memset(buffer, 0, sizeof(buffer));
A* p = new(buff)A();
在网络IO发送一条协议,数据是变长的可能要用到placement new。
比如协议内容如下:

#pragma pack(1)//1字节对其

enum eEventType
{
    eEventType_PlayInfo = 1,
    eEventType_Max
};

struct stEvent
{
    unsigned short eventTyp;    //eEventType
    stEvent(eEventType _etype) :eventTyp(_etype){}
    virtual ~stEvent(){}
};

struct stPlayerInfo
{
    stPlayerInfo():stEvent(eEventType_PlayInfo){}
    int passward;
    char name[32];
    int size;
    char data[0];
};
可以用
    char buffer[1024];
    memset(buffer, 0, sizeof(buffer));
    stPlayerInfo* pSend = new (buffer)stPlayerInfo();
    pSend->passward = 123456;
    char someData[] = "hhhh sllll ss";
    pSend->size = strlen(someData);
    memcpy(pSend->data, someData, pSend->size);
    ......
    //最后将数据发送出去
    write(sock, pSend, sizeof(stPlayerInfo)+pSend->size);

其实可以封装一个函数做只是在指定内存调用构造函数
template<class T>
void placement(T* p)
{
    new (static_cast<void*>(p))T();
}

这样就可以
    char buffer[1024];
    memset(buffer, 0, sizeof(buffer));
    stPlayerInfo* pSend = (stPlayerInfo*)buffer;
    placement(pSend);

猜你喜欢

转载自blog.csdn.net/qq_19825249/article/details/106815102