Okay, I have studied the RAII ideome, as a realworld test I made a small
application where
I have wrapped a c api handle for a directory inside a raii class. Could you
provide some
weedback on the code below, have I understood RAII correctly?
If something else look weired in my code please tell me that aswell, I'm
very good at taking critisism :)
(the application is enumerating files recurivly from a strarting dir)
//John
----------------------------------------------
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/dir.h>
#include <vector>
#include <string>
using namespace std;
// RAII class for opendir
class DirectoryHandle
{
public:
DirectoryHandle(string directory)
{
dirhandle = opendir(directory.c_str());
}
~DirectoryHandle()
{
closedir(dirhandle);
}
direct *readNext()
{
return readdir(dirhandle);
}
bool canAccess()
{
return (NULL != dirhandle);
}
private:
DIR *dirhandle;
};
void enumerateFileSystem(vector<string> *fileList, string directory)
{
struct direct *dirEntry;
struct stat fileInfo;
string path;
// open directory for scanning (using RAII object)
DirectoryHandle dirHandle(directory);
while (dirHandle.canAccess() && ((dirEntry = dirHandle.readNext()) !=
NULL))
{
// exclude . and .. directories
if (strcmp(dirEntry->d_name,".") != 0 &&
strcmp(dirEntry->d_name,"..") != 0)
{
path = directory + dirEntry->d_name;
if (stat(path.c_str(), &fileInfo) != -1)
{
// check if this is a directory
if (S_ISDIR(fileInfo.st_mode)) {
string subDir = path + "/";
// start enumerating that directory recursivly
enumerateFileSystem(fileList, subDir);
}
else {
// nope, this is a file
// add to list
fileList->push_back(path);
}
}
}
}
return;
};
int main(int argc, char *args[])
{
vector<string> files;
enumerateFileSystem(&files, "/etc/");
for (size_t i = 0; i < files.size(); i++)
{
cout << files[i] << endl;
}
return 0;
}
On 2/11/07, Milan Babuskov <[EMAIL PROTECTED]> wrote:
>
> --- John Gunnarsson wrote:
> > As you can see the cleanup code is duplicated 3 times (not very DRY)
> > If I would have implemented the same scenario in c# the cleanupcode
> > would have been placed in a "finally" clause only once, and would be
> > executed wither an exception occured or not.
> >
> > Since I'm quite new to c++ I'm sure I just missed something very
> > vital here, and would like to know how you solve scenarios
> > like this in C++.
>
> Generally it is not a good practice to have stuff like:
>
> try
> {
> ...* x= new Something;
> ...
> delete x;
> }
> catch()
> {
> }
>
> The solution is to create objects on the stack, or use some kind of
> wrapper object (a proxy, smart pointer, whatever) and have it's
> constructor allocate the memory and have it's destructor free that memory.
>
> --
>
> Milan Babuskov
> http://www.guacosoft.com
>
>
>
[Non-text portions of this message have been removed]