Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

I need to write a class in C++ that acquires a hardware resource and releases it

ID: 658941 • Letter: I

Question

I need to write a class in C++ that acquires a hardware resource and releases it again when it is destroyed. Basically that can be done in the constructor and destructor of the class. The difficulty I'm having is that I want this class to be usable as a local object only.

So basically:

struct Magic
{
Magic(const Settings& settings)
{
    acquireHardware(settings);
}
~Magic()
{
    releaseHardware();
}
// Magic does not need to store the settings or a reference to them
};
This should be allowed:

void useAllTheHardware(const Settings& settings)
{
Magic useHardwareWith(settings);
...
// destructor releases the hardware
}
This should fail:

struct badIdea
{
badIdea(const Settings& settings)
    : settings_(settings),
    useHardwareWith_(settings)
{
}
Settings settings_;
Magic useHardwareWith_;
};
badIdea mustFail(settings); // <-- not allowed
My environment is exception-free (embedded, and compiled with gcc -fno-exceptions), and if things go terribly wrong there's usually no way of handling that except fixing the bug that caused the crash.

How can I do that?

Explanation / Answer

You can't quite do it, but you can come close:

#include <cstddef>

#include <new>

struct Magic
{
enum promise
{
i_promise_not_to_put_this_in_another_class
};

void *operator new(size_t) = delete;
void *operator new[](size_t) = delete;
void operator delete(void *) = delete;
void operator delete[](void *) = delete;

Magic(promise) {}
Magic(Magic&&) = delete;
Magic(const Magic&) = delete;
Magic& operator = (Magic&&) = delete;
Magic& operator = (const Magic&) = delete;
~Magic() {}
};

struct WhyIsThisABadIdea
{
Magic m;

WhyIsThisABadIdea() : m(Magic::i_promise_not_to_put_this_in_another_class) {} // obvious lies
};

int main()
{
Magic m(Magic::i_promise_not_to_put_this_in_another_class); // okay
//new Magic(Magic::i_promise_not_to_put_this_in_another_class); // error
WhyIsThisABadIdea bad; // okay
}