Is it possible to implement in C++ a design that is both - RAII, to ensure the resource is safely released, and - lazy initialzation, that the resource is acquired only when it's really used.
My idea is that just implement as a lazy initialization, while in the real resource acquisition, use RAII.
How's the industry practice?
Yes, it's possible. Just use std::optional
(C++17 or from Boost) or unique_ptr
/shared_ptr
.
(opinion) optional
has a great advantage in the readability - you can't be any clearer that this value may not be initialized.
To show that resources are released correctly: first let's start with eager initialization (live):
ofstream file("test.txt");
file << "no flush\n";
ifstream inFile("test.txt");
string line;
getline(inFile, line);
cout << line << endl;
This, doesn't print anything for me¹. Let's move writing to a separate scope (live):
{
ofstream file("test.txt");
file << "no flush\n";
}
ifstream inFile("test.txt");
string line;
getline(inFile, line);
cout << line << endl;
This should print no flush
, because ofstream
is guaranteed to close()
the file upon destruction. (unless something else accessed test.txt
at the same time)
And now with Boost.Optional and lazy init (live):
{
boost::optional<std::ofstream> file;
file = ofstream("test.txt");
file.get() << "no flush\n";
}
ifstream inFile("test.txt");
string line;
getline(inFile, line);
cout << line << endl;
Resources are released at the same time as they were with regular ofstream
.
¹ file access isn't guaranteed to be buffered, but it makes for a good example, also available on online compilers.