Screenplay: C++: Ownership/RAII

RAII: “Resource Acquisition is Initialization”

Allocate in Constructor

#include <unistd.h>


class Allocates
{
public:
    Allocates(size_t n)
    : _mem(new char[n]) {}
private:
    char* _mem;
};

int main()
{
    Allocates allocs(28);
    return 0;
}

Discussion

  • Memory leak (valgrind etc)

  • initializer list? Morph it.

Deallocate in Destructor - Ownership

#include <unistd.h>


class Owns
{
public:
    Owns(size_t n)
    : _mem(new char[n]) {}
    ~Owns() { delete[] _mem; }
private:
    char* _mem;
};

int main()
{
    Owns owns(28);
    return 0;
}

Discussion

  • deterministic: at end of scope - return

  • Array delete

Ownership: 2 x non-const

#include <unistd.h>
#include <string.h>


class MaybeOwns
{
public:
    MaybeOwns(size_t n)
    : _mem(new char[n]) {}
    ~MaybeOwns() { delete[] _mem; }

    char* mem() { return _mem; }

private:
    char* _mem;
};

int main()
{
    MaybeOwns mo(28);
    char* whose = mo.mem();
    strcpy(whose, "You are mine!");
    delete[] whose;
    return 0;
}

Discussion

  • mem() is non-const

  • as if _mem was public

  • anyone can modify/delete

Ownership: const Method

Add const to method …

#include <unistd.h>
#include <string.h>


class MaybeOwns
{
public:
    MaybeOwns(size_t n)
    : _mem(new char[n]) {}
    ~MaybeOwns() { delete[] _mem; }

    char* mem() const { return _mem; }

private:
    char* _mem;
};

int main()
{
    MaybeOwns mo(28);
    char* whose = mo.mem();
    strcpy(whose, "You are mine!");
    delete[] whose;
    return 0;
}

Discussion

  • explain const method: promise to not modify object

  • exposing a member publicly does not modify object

  • Don’t do this!

Ownership: 2 x const

Add const to mem() return type, and let compiler take you by the hand,

  • const variable

  • strcpy(): lhs parameter, see man strcpy

  • delete[] whose still possible! Don’t do it!

#include <unistd.h>
#include <string.h>

#include <string>
#include <memory>


class MaybeOwns
{
public:
    MaybeOwns(size_t n)
    : _mem(new char[n]) {}
    ~MaybeOwns() { delete[] _mem; }

    const char* mem() const { return _mem; }

private:
    char* _mem;
};

int main()
{
    MaybeOwns mo(28);
    const char* whose = mo.mem();
    delete[] whose;
    return 0;
}