If the resource one requires to acquire in the construction of an object can fail is it possible to do RAII, if exceptions are prohibited by a local coding standard?
If so, what is the canonical manner to handle the failure of resource acquisition in this case?
RAII is an important C++ idiom for resource management. Notably, RAII provides a structural idiom for proper resource management with exceptions. The power of the idiom is in the guarantees it provides. Properly used, the destructor for your RAII-object is guaranteed to be called to allow you to free resources.
The principle that objects own resources is also known as "resource acquisition is initialization," or RAII. When a resource-owning stack object goes out of scope, its destructor is automatically invoked. In this way, garbage collection in C++ is closely related to object lifetime, and is deterministic.
Resource acquisition is initialization (RAII) is a programming idiom used in several object-oriented, statically-typed programming languages to describe a particular language behavior. In RAII, holding a resource is a class invariant, and is tied to object lifetime.
Resource Acquisition Is Initialization or RAII, is a C++ programming technique which binds the life cycle of a resource that must be acquired before use (allocated heap memory, thread of execution, open socket, open file, locked mutex, disk space, database connection—anything that exists in limited supply) to the ...
I would not go with the invalid object approach in general because I would consider this as bad design. After construction, the object must be in a state where the invariants are established (that is the only purpose a constructor should serve). Consider a class strange_vector
implementing something like std::vector
, but after calling strange_vector<int>(10, 0)
, the object would be in an unusable state because the allocation failed.
Instead I would declare the constructors private and use a factory method which returns an optional:
class file
{
public:
~file() {fclose(m_file);}
static std::optional<file> open(std::string const& filename)
{
auto f = fopen(filename.c_str(), "r");
if (f)
{
return std::make_optional<file>(f);
}
else
{
return std::nullopt;
}
}
private:
file(FILE* file);
FILE* m_file;
};
One of the biggest benefits of exception handling is (besides decoupling error handling and normal code path) that you cannot ignore them accidentally. If you want that, you could create your own class similar to optional
that, when not initialized with a valid object, logs an error message and terminates your program (or any other reasonable error handling). I think there is a talk from A. Alexandrescu about systematic error handling where he implements a class Expected<T>
that contains either a value of type T
or an exception. You could use this a basis and instead of the exception add your error handling there.
std::optional
is not part of the standard yet, but you can easily get implementations either as part of recent compilers, in boost, or in other libraries.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With