代码之家  ›  专栏  ›  技术社区  ›  nabulke

资源分配和自动释放

c++
  •  2
  • nabulke  · 技术社区  · 16 年前

    在我的申请中,我得到了很多 CDbaOciNotifier类 OCIEnv类 .

    我想实现的是资源的分配和释放 CDbaOciNotifier类

    理想的行为首先是 将创建环境,然后所有以下通知程序使用相同的环境。随着最后一个通知程序的销毁,环境也将被销毁(调用customdeleter)。

    到目前为止,我得到了什么(使用静态工厂方法创建通知程序):

    #pragma once
    
    #include <string>
    #include <memory>
    #include "boost\noncopyable.hpp"
    
    class CDbaOciNotifier : private boost::noncopyable
    {
    public:
    
        virtual ~CDbaOciNotifier(void);
    
        static std::auto_ptr<CDbaOciNotifier> createNotifier(const std::string &tnsName, const std::string &user, const std::string &password);
    
    private:
        CDbaOciNotifier(OCIEnv* envhp);
    
        // All notifiers share one environment
        static OCIEnv* m_ENVHP;
    
        // Custom deleter
        static void freeEnvironment(OCIEnv *env);
    
        OCIEnv* m_envhp;
    };
    

    CPP公司:

    #include "DbaOciNotifier.h"
    
    using namespace std;
    
    OCIEnv* CDbaOciNotifier::m_ENVHP = 0;
    
    CDbaOciNotifier::~CDbaOciNotifier(void)
    {
    }
    
    CDbaOciNotifier::CDbaOciNotifier(OCIEnv* envhp)
                    :m_envhp(envhp)
    {
    
    }
    
    void CDbaOciNotifier::freeEnvironment(OCIEnv *env)
    {
        OCIHandleFree((dvoid *) env, (ub4) OCI_HTYPE_ENV);
        *env = null;
    }
    
    auto_ptr<CDbaOciNotifier> CDbaOciNotifier::createNotifier(const string &tnsName, const string &user, const string &password)
    {
        if(!m_ENVHP)
        {
            OCIEnvCreate( (OCIEnv **) &m_ENVHP, OCI_EVENTS|OCI_OBJECT, (dvoid *)0,
                (dvoid * (*)(dvoid *, size_t)) 0,
                (dvoid * (*)(dvoid *, dvoid *, size_t))0,
                (void (*)(dvoid *, dvoid *)) 0,
                (size_t) 0, (dvoid **) 0 );
        }
    
        //shared_ptr<OCIEnv> spEnvhp(m_ENVHP, freeEnvironment); ...got so far...
    
        return auto_ptr<CDbaOciNotifier>(new CDbaOciNotifier(m_ENVHP));
    }
    

    我想避免自己计算引用(通知者),而使用类似shared\u ptr的东西。

    2 回复  |  直到 16 年前
        1
  •  2
  •   deft_code    16 年前

    你的代码里有很多东西。这里是解决方案,但简化为简单的要点。

    class CDbaOciNotifier
    {
    public:
       CDbaOciNotifier() :
          m_resource(get_env())
       { }
    
    private:
       shared_ptr<OCIEnv> m_env;
    
       struct Delete_env
       {
          void operator()(OCIEnv* env)
          {
             OCIHandleFree( ... );
          }
       };
    
       static shared_ptr<OCIEnv> get_env()
       {
            // make sure a mutex is involved if CDbaOciNotifier
            // can be constructed concurrently.
    
            static weak_ptr<OCIEnv> s_env;
    
            shared_ptr<OCIEnv> env = s_env.lock();
            if( ! env )
            {
                OCIEnv* env_ptr = OCIEnvCreate( ... );
                env.reset( env_ptr, Delete_env() );
                s_env = env;
            }
            return env;
       }
    };
    

    CDbaOciNotifier 同时。你需要一个静态互斥来保护 s_env

    weak_ptr 必须是一个函数本地静态否则你的应用程序可能爆炸,如果一个全局或静态 CDC控制器

        2
  •  1
  •   Michael Kristofik    16 年前

    这对你有用吗?

    // In .h file
    class CDbaOciNotifier
    {
        // ...
        private:
            static shared_ptr<OCIEnv> envPtr;
    };
    
    // In .cpp file
    // Write freeEnvironment as a free function.
    shared_ptr<OCIEnv> CDbaOciNotifier::envPtr(new OCIEnv, freeEnvironment);