Backstory (You can skip)
I am building an API for managing Files and Directories in a consistent manner across a project. This is for deduplication and consistency when performing a task, and in this particular case, I want to ensure that a file is closed and the mutex is unlocked. Now this is a straight-forward task to solve if I simply create a new object QByteArray
to hold the value while I clean up, but I would like to know if it is actually possible to forgo this, and return with cleanup code happening regardless.
Problem:
Take the following FUNCTIONAL code:
QByteArray Foo::getFileContents(QCD::FileSystem fileSystem, QString fileName)
{
formatDirectoryPath(fileSystem, fileName);
QString key(d_ROOT.absoluteFilePath(fileName));
m_Mutex.lock();
ct_Check(!m_Files.contains(key)); // QMap<QString,QFile*> m_Files
ct_Check(!m_Files[key]->exists());
ct_Check(!m_Files[key]->open(QIODevice::ReadOnly));
QByteArray ba(m_Files[key]->readAll()); // I dont want to create a new object
m_Files[key]->close(); // Needs to run before return
m_Mutex.unlock(); // Need to free the mutex
return ba;
}
As you can see, I had to create a QByteArray object to hold my value while I closed the file. It would be nice if I could just do this instead:
QByteArray Foo::getFileContents(QCD::FileSystem fileSystem, QString fileName)
{
formatDirectoryPath(fileSystem, fileName);
QString key(d_ROOT.absoluteFilePath(fileName));
m_Mutex.lock();
ct_Check(!m_Files.contains(key));
ct_Check(!m_Files[key]->exists());
ct_Check(!m_Files[key]->open(QIODevice::ReadOnly));
return m_Files[key]->readAll();
&& m_Files[key]->close(); // Illegal, but you get the idea
&& m_Mutex.unlock();
}
where I return the readAll()
but still manage somehow to close the file inside the function block as well as unlock the mutex.
Is this possible without having to create any more objects?
QMutexLocker
, which will unlock the mutex in its destructor. You easily implement a similar class that closes aQFile
in its destructor. – pschill Feb 5 at 15:30QMutex
destructor. You unlock it in theQMutexLocker
destructor. I recommend that you familiarize yourself with RAII, which is a mandatory concept for C++ developers. It even has its own page atcppreference
and coincidentally uses mutexes as example: en.cppreference.com/w/cpp/language/raii – pschill Feb 5 at 16:17QFile
closes itself in it's destructor.QFile::open
andQFile::close
are basically vestigial at this point, they can be replaced byQFile::QFile
andQFile::~QFile
– Caleth Feb 5 at 20:18