As a follow-up to my original post, I want to thank people
for their responses. The consensus seems to be to have a
resource-specific struct for each resource, and
to stay away from abusing unique_ptr. I think an approach like
BOOST_SCOPE_EXIT has its place, but not for the type of
resource management being discussed -- the resource needs to
be allocated, anyway, so just code up the release code in the
destructor, and, then, no program-specific BOOST_SCOPE_EXIT is
needed.
Attached(below) is a no-frills header file with 5 resource managers,
which I have just used and tested in a small program. I am
certain I will be re-using this functionality in future code.
The code needs to be broken into separate header files, maybe
use namespaces, .... Any other suggestions on this? I have
used the "_mgr" suffix for the resource classes, like the "_ptr"
suffix on the smart pointers.
====================
/*
The structs in this file are resource managers. When the object
goes out of scope, the resource is freed. If the struct has the
method get(), possibly const, it should return the resource that
is being managed. The return value can be a value, a refererence or
a pointer, whichever is appropriate for the particualr resource.
*/
PS I was not able to send the header file as an attachment.
//============ Integer file descriptors ===============
#include <unistd.h> // close
// Example:
// IntFD fd = open( "filename", O_WRONLY );
struct IntFD_mgr {
int fd_;
IntFD_mgr( int fd = -1 ) : fd_( fd ) {}
int get( void ) const { return fd_; }
~IntFD_mgr(){ close( get() ); }
};
//============ X resources ===============
#include <X11/Xlib.h>
struct Display_mgr
{
Display* display_;
Display_mgr( Display* disp = nullptr ) :
display_( disp )
{}
Display* get( void ) const { return display_; };
~Display_mgr() { XCloseDisplay( get() ); }
};
struct FontWithDisplay_mgr
{
XFontStruct* fontStruct_;
Display* display_;
FontWithDisplay_mgr( XFontStruct* fs = nullptr,
Display* disp = nullptr ) :
fontStruct_( fs ),
display_( disp )
{}
XFontStruct* get( void ) const { return fontStruct_; };
~FontWithDisplay_mgr() { XFreeFont( display_, get() ); }
};
//============ syslog management ===============
#include <syslog.h>
#include <sstream> // insertion convert to string
// Only one instance allowed per process
struct SystemLogger_mgr
{
SystemLogger_mgr( const char *ident, int option, int facility)
{
openlog( ident, option, facility );
}
~SystemLogger_mgr() { closelog(); }
};
// Allows stream logging such as
// SysLog( LOG_ERR, "value= " << 5 );
#define SysLog( P, D ) \
if( LOG_MASK(P) ) { \
std::stringstream str; str << D; \
syslog(P, str.str().c_str() ); }
//============ XDG management ===============
#include <basedir.h>
// Example:
// XDGHandle xdgh;
struct XDGHandle_mgr {
xdgHandle handle_;
XDGHandle_mgr( void ) { xdgInitHandle( get() ); }
xdgHandle* get( void ) { return &handle_; }
~XDGHandle_mgr(){ xdgWipeHandle( get() ); }
};