Your answer is clear and my question is answered. Just one more comment
Wrong. The destructor is guaranteed to be called for each existing and
successfully created object. No exception from this rule that I know of (no pun
intended).
For the object pointed by smart pointer, yes. But for the objects allocated
on heap and pointed by raw pointer, no. Right? :-)
George schrieb:
One C++ object for each resource instance that needs to be freed.
Free that resource in the destructor.
Compose these objects to make more complicated objects that require multiple
resources, but now needn't worry about freeing them (because C++
automatically calls base and member destructors).
I agree in theory it is good approach.
Not only in theory. It works perfectly fine in practice.
Currently, I am only aware that using
auto_ptr to deal with memory.
That is correct. auto_ptr can be used to implement RAII for objects allocated
with new.
Could you show some pseudo code about your
design pattern above about how to build complicate component to wrap file
handlers so that it is ensured it will be freed in destructor?
For resources other than the heap memory, you would use other classes to
implement RAII. For files you could use the iostream library. For intertask
syncronizatino, you could use boost threads or the MFC CSingleLock and
CMultiLock classes, and so on.
What makes me confused is that, the destructor is not ensured to be called
-- there may be exceptions. :-)
Wrong. The destructor is guaranteed to be called for each existing and
successfully created object. No exception from this rule that I know of (no pun
intended).
One approach I could think of is to make a class, and put FILE* as its
member variable, then using auto_ptr to point to the class instance. I am not
sure whether it is the same or similar to your design pattern.
FILE* has nothing to do with new, so there is no point in using auto_ptr.
To wrap FILE* in an RAII class, you could do something like:
class FileException;
class File
{
private:
FILE* f_;
public:
File(FILE* f) : f_(f)
{
if (!f_)
throw FileException;
}
~File()
{
fclose(f);
}
operator FILE*()
{
return f_;
}
};
And in a function:
void file_handling()
{
File myfile(fopen("filename", "r");
int ch = fgetc(myfile);
...
}