"Smart" Resource Management

Contents

  1. Ownership
  2. Sharing
  3. Using / Pointing

Ownership

Ownership is best expressed with std::unique_ptr.

Heap-allocated object

class Logger {
    private:
        std::unique_ptr<ILogTarget> _Target;
};

Heap-allocated array

int hash(const char* name) {
    std::ifstream input(name, std::ios::binary);
    const auto size = 4096;
    std::unique_ptr<char[]> buffer(new char[size]);
    int h = 42;
    while (input) {
        input.read(buffer.get(), size);
        h = h + buffer[42] % 42;
    }
    return h;
}

C-style resource

How to own a FILE*

It is the same as every other resource:

  • obtain - fopen
  • return - fclose
struct FCloserDeleter
{
    void operator()(FILE* file) const
    {
        if (file)
        {
            fclose(file);
        }
    }
};

typedef std::unique_ptr<FILE, FCloserDeleter> FilePtr;

Custom deleter

Directly using a deleter

template <typename T>
using UniqueReleasePtr<T> = std::unique_ptr<T, ReleaseDeleter>;

template <typename T>
using UniqueDestroyPtr<T> = std::unique_ptr<T, DestroyDeleter>;
namespace std
{
template <>
struct default_delete<ID3DDevice>
{
    void operator()(ID3DDevice* ptr) const
    {
        ptr->Release();
    }
}
}

owner

Presented in A brief introduction to C++’s model for type and resource safety

Implemented in:

template <class T>
using owner = T;

(https://github.com/Microsoft/GSL/blob/master/include/gsl/gsl#L55)

Static checkers:

Sharing

  • Use intrusive_ptr or shared_ptr

Using / Pointing

  • Use a plain pointer
  • Use a reference