Resource allocation and automatic deallocation

Posted by nabulke on Stack Overflow See other posts from Stack Overflow or by nabulke
Published on 2010-05-25T12:40:31Z Indexed on 2010/05/25 12:51 UTC
Read the original article Hit count: 169

Filed under:

In my application I got many instances of class CDbaOciNotifier. They all share a pointer to only one instance of class OCIEnv.

What I like to achieve is that allocation and deallocation of the resource class OCIEnv will be handled automatically inside class CDbaOciNotifier.

The desired behaviour is, with the first instance of class CDbaOciNotifier the environment will be created, after that all following notifiers use that same environment. With the destruction of the last notifier, the environment will be destroyed too (call to custom deleter).

What I've got so far (using a static factory method to create notifiers):

#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));
}

I'd like to avoid counting references (notifiers) myself, and use something like shared_ptr.

Do you see an easy solution to my problem?

© Stack Overflow or respective owner

Related posts about c++