使用placement new来巧妙实现一个单例

一直对placement new的这种方式有点好奇,不知道存在这种方式的NEW有什么用,今天刚好在公司项目中见到用placement new方式来配合单例的实现的一个库,然后自己迅速写了一个小demo来模拟了一下这个实现,确实比较新颖!  直接看代码:


头文件声明:

/*
 *	思想:本类在使用过程中FOO通过单例的方式得到,但FOO类的构造和析构由它自己去负责,不需要使用者来处理!
 *        FOO类的new操作使用placement new操作来进行,所以不需要delete操作。FOO类的析构函数注册给std::atexit
 *        ,因此FOO类的整个构造和析构由它自己去完成,客户无需做任务操作。
 *
 *  知识点:
 *         1,placement new 加 单例设计 的这种模式,好处是可以省略自己的new和delete操作
 *         2,CFoo类也可以做到自己placement new和atexit来析构自己,为什么还有CFooHelper类来操作,因为CFoo类
 *            需要多声明一个静态的release函数,会让客户疑惑。
 *         3,CFooHelper类的声明和实现方式,对客户来说,CFooHelper类是不可见的!
 */


#ifndef FOO_HPP_
#define FOO_HPP_

class CFoo
{
    public:
		~CFoo();

		bool init();
		bool fnit();

    public:
        static CFoo* getInstance();
 
    private:
        CFoo();
};

#endif


实现文件:

#include <iostream>
#include "Foo.hpp"

unsigned char s_mySelfBuf[ sizeof(CFoo) ] = {0};  // 申请一个sizeof(CFoo)大小的数组地址,用来存放CFoo类
CFoo* sm_mySelf;

struct CFooHelper
{
    static void* createFoo()
    {
        CFoo::getInstance();
        return 0;
    }

    static void distroyFoo()
    {
        if ( sm_mySelf )
        {
            sm_mySelf->~CFoo();
            sm_mySelf = 0;
        }
    }
};

void* pTemp = CFooHelper::createFoo();

CFoo::CFoo()
{
    std::cout << "contrust myself, addr: " << this << std::endl;
}

CFoo::~CFoo()
{
    std::cout << "distroy myself, addr: " << this << std::endl;
}

bool CFoo::init()
{
    return true;
}

bool CFoo::fnit()
{
    return true;
}

CFoo* CFoo::getInstance()
{
    if ( !sm_mySelf )
    {
        sm_mySelf = new ( s_mySelfBuf ) CFoo;
        std::atexit(  CFooHelper::distroyFoo  );
    }

    return sm_mySelf;
}


调用的方式很简单:

#include "stdafx.h"
#include "Foo.hpp"

int _tmain(int argc, _TCHAR* argv[])
{
    CFoo* p = CFoo::getInstance(); //使用过程中,CFOO类的实例其实已经创建,这里只是拿到这个实例的指针

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值