Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I have some background in Java (and recently in C#) and would like to get to know C++ better as well. I think I'm aware of some of the basics of the differences in memory (and other resource) management between these languages. This is perhaps a small question relating to using the dispose pattern and the different features available in these languages to assist with it. I like what I've gathered of the RAII and SBRM principles and I'm trying to understand them further.
Suppose I have the following class and method in Java
class Resource implements Closeable {
public void close() throws IOException {
//deal with any unmanaged resources
}
}
...
void useSomeResources() {
try(Resource resource = new Resource()) {
//use the resource
}
//do other things. Resource should have been cleaned up.
}
or a fairly close C# analogue
class Resource : IDisposable
{
public void Dispose()
{
//deal with any unmanaged resources
}
}
...
void UseSomeResources()
{
using(var resource = new Resource())
{
//use the resource
}
//do other things. Resource should have been cleaned up.
}
Am I right to think that the idiom best representing this same behaviour in C++ would be the following?
class Resource {
~Resource() {
cleanup();
}
public:
void cleanup() {
//deal with any non-memory resources
}
};
...
void useSomeResources()
{
{
Resource resource;
//use the resource
}
//do other things. Stack allocated resource
//should have been cleaned up by stack unwinding
//on leaving the inner scope.
}
I don't want, especially, to elicit debate over whose language is better and things like that, but I'm wondering to what extent these implementations can be compared, and how robust they all are to cases where the block using the resource encounters exceptional circumstances. I may have completely missed the point on something, and I'm never quite sure about best practices for disposal - for the sake of argument, perhaps it's worth assuming all disposal/destruction functions here are idempotent - and really good tips for those matters might also be relevant to this question.
Thanks for any pointers.
It's almost the pattern. In fact you don't need to add a cleanup() function: the destructor is there to do the cleanup.
By the way, having a public cleanup() exposed, allows for accidental call of cleanup(), bringing the ressource in an undesired state.
class Resource {
~Resource() {
//deal with any non-memory resources
}
}; // allways ; at the end of a class ;-)
This (1)proposed class,
class Resource {
~Resource() {
cleanup();
}
public:
void cleanup() {
//deal with any non-memory resources
}
};
is non-idiomatic and dangerous because (1) it exposes the cleanup operation, and (2) it prevents deriving classes from this, and prevents automatic variables of this class.
The exposed cleanup can be called at any time by any code, and after cleanup you have non-usable zombie object. And you do not know when or if that happens, and so the implementation code has to check for that state everywere. Very ungood. It's on a par with init functions taking the roles of constructors, with just a dummy constructor.
Classes can not in practice be derived because in a derived class whose objects are destroyed, a call to this class' destructor is generated, and that destructor is inaccessible – so the code won't compile.
The proper pattern looks like this:
class Resource
{
public:
// Whatever, then:
~Resource()
{
// Clean up.
}
};
The destructor can still be called explicitly, but there's a strong incentive not to do so.
Note that with class derivation and polymorphic use, the destructor should better be made virtual. But in other cases that would needlessly make the class polymorphic and thus have a size cost. So it's an engineering decision.
(1) I added a missing semicolon. It's a good idea to post real code, even for small general examples.
You already mentioned the answer, it's RAII, just like in your link.
A typical class in C++ will have a (virtual! you forgot that) destructor:
class C {
virtual ~C { /*cleanup*/ }
};
And you control its lifetime with normal block rules:
void f() {
C c;
// stuff
// before this exits, c will be destructed
}
This is in fact what languages like C# and Java try to emulate with their dispose patterns. Since they don't have deterministic finalizers you have to manually release unmanaged resources (using using and try respectively). However, C++ is completely deterministic, so it's a lot simpler to do this.
Thanks for any pointers. Ha!
One thing you're referring to the Java try with resources method, which is a shortcut to actually calling resource.close(). The other alternative would call resource.Dispose()
The important thing to remember is that the object that you're using in Java and C# to close things using these interfaces require object and member-field closure. A file must be closed, once opened. There's no way around it, and trying to weasel your way out of that, will leave you high and dry for memory, and will leave other applications at risk for failing for not having access to the files you`ve laid claim to but have never closed. It's important that you provide code to make files be closed.
But there are other things that have to be gotten rid of when objects leave memory. When those objects leave scope, those things happen. And that's when the Destructor in C++, what you have referenced above gets called.
Closeable and IDisposable belong to what I call “Responsible” classes however. They go above and beyond what any normal “destructor” for a class would when it removes objects from scope and frees top level memory of pointers that you have available. They also take care of the rigamarole of things you may not think about or could potentially put the system at risk for later. It's like being a father versus being a good father. A father has to give his kids shelter, but a good father knows what's best for the kid even when the kids or other caretakers don`t know what's best for them.
Note that it's important to reference AutoCloseable interfaces not necessarily Closeable interfaces when you want to use Java`s “try with Resources” alternative.
The answer: The IDisposable, the Closeable interface, and even the AutoCloseable interface, all support the removal of managed resources. So does the “Destructor” in C++, the grandaddy of shorthand for such a removal process. The problem is that you still have to ensure that you handle properly the members of your class undergoing destruction. I think you have the right function in mind to call in C++ to do what you want to do.
References:
http://www.completecsharptutorial.com/basic/using.php
http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
To summarise some good points raised in other answers to this question and some other things I've read:
The answer to the main question is yes, the automatic local variable resource has its destructor called regardless of how control leaves the block in which is it defined. In this respect the inner scope and local allocation (usually implies stack rather than heap, but depends on compiler) of the variable (rather than using new) act very like a try-with-resources block in Java, or a using block in C#.
In contrast to Java and C#, the ability to allocate objects purely locally (normally meaning: to the stack) in C++ means that, for objects dealing with resources which need disposing of safely, additional interface implementations and somewhat overexposed public disposal methods are not needed (and usually not desirable).
Using a private destructor, ~Resource(), removes some of the danger of accidentally having objects in unexpected states (e.g file writer without file handle), but 'unmanaged resources' are still always safely disposed when the object is deleted (or goes out of scope if it is an automatic local variable as in the question example.)
Using public cleanup function members is still absolutely possible if this is desired, but it is often an unnecessary danger. If a cleaning up member must be made public, it's best to be the destructor itself, since this is an obvious 'self-documenting' indication to any user that it should only be called in very rare circumstances: better to just use delete or let a locally allocated object fall out of scope and let the compiler do the work of calling the destructor. It also removes any confusion a non-destructor public method might cause ('should I call cleanup() before I delete this object or not?').
If your resource object is to be inherited from, it is important to ensure its destructor is both virtual (overridable) and (at least as visible as) protected, to ensure that subclasses can be disposed of properly.
Further, with cleanup implemented directly in destructors, and the garbage-collector-less semantics of destruction immediately upon leaving scope for automatic variables (and upon delete for dynamically-allocated variables), it becomes a property and responsibility of the type itself that it is necessarily properly disposed of, rather than that it is simply capable of being disposed of safely.
An example of more idiomatic C++ usage:
class Resource {
//whatever members are necessary
public:
//resource acquisition for which this object is responsible should be constrained to constructor(s)
~Resource() { //or virtual ~Resource() if inheritance desired
//deal with resource cleanup
}
};
When used as suggested in the question, this approach should ensure resources are dealt with safely without leaks occurring.
Related
I've been thinking about the possible use of delete this in c++, and I've seen one use.
Because you can say delete this only when an object is on heap, I can make the destructor private and stop objects from being created on stack altogether. In the end I can just delete the object on heap by saying delete this in a random public member function that acts as a destructor. My questions:
1) Why would I want to force the object to be made on the heap instead of on the stack?
2) Is there another use of delete this apart from this? (supposing that this is a legitimate use of it :) )
Any scheme that uses delete this is somewhat dangerous, since whoever called the function that does that is left with a dangling pointer. (Of course, that's also the case when you delete an object normally, but in that case, it's clear that the object has been deleted). Nevertheless, there are somewhat legitimate cases for wanting an object to manage its own lifetime.
It could be used to implement a nasty, intrusive reference-counting scheme. You would have functions to "acquire" a reference to the object, preventing it from being deleted, and then "release" it once you've finished, deleting it if noone else has acquired it, along the lines of:
class Nasty {
public:
Nasty() : references(1) {}
void acquire() {
++references;
}
void release() {
if (--references == 0) {
delete this;
}
}
private:
~Nasty() {}
size_t references;
};
// Usage
Nasty * nasty = new Nasty; // 1 reference
nasty->acquire(); // get a second reference
nasty->release(); // back to one
nasty->release(); // deleted
nasty->acquire(); // BOOM!
I would prefer to use std::shared_ptr for this purpose, since it's thread-safe, exception-safe, works for any type without needing any explicit support, and prevents access after deleting.
More usefully, it could be used in an event-driven system, where objects are created, and then manage themselves until they receive an event that tells them that they're no longer needed:
class Worker : EventReceiver {
public:
Worker() {
start_receiving_events(this);
}
virtual void on(WorkEvent) {
do_work();
}
virtual void on(DeleteEvent) {
stop_receiving_events(this);
delete this;
}
private:
~Worker() {}
void do_work();
};
1) Why would I want to force the object to be made on the heap instead of on the stack?
1) Because the object's lifetime is not logically tied to a scope (e.g., function body, etc.). Either because it must manage its own lifespan, or because it is inherently a shared object (and thus, its lifespan must be attached to those of its co-dependent objects). Some people here have pointed out some examples like event handlers, task objects (in a scheduler), and just general objects in a complex object hierarchy.
2) Because you want to control the exact location where code is executed for the allocation / deallocation and construction / destruction. The typical use-case here is that of cross-module code (spread across executables and DLLs (or .so files)). Because of issues of binary compatibility and separate heaps between modules, it is often a requirement that you strictly control in what module these allocation-construction operations happen. And that implies the use of heap-based objects only.
2) Is there another use of delete this apart from this? (supposing that this is a legitimate use of it :) )
Well, your use-case is really just a "how-to" not a "why". Of course, if you are going to use a delete this; statement within a member function, then you must have controls in place to force all creations to occur with new (and in the same translation unit as the delete this; statement occurs). Not doing this would just be very very poor style and dangerous. But that doesn't address the "why" you would use this.
1) As others have pointed out, one legitimate use-case is where you have an object that can determine when its job is over and consequently destroy itself. For example, an event handler deleting itself when the event has been handled, a network communication object that deletes itself once the transaction it was appointed to do is over, or a task object in a scheduler deleting itself when the task is done. However, this leaves a big problem: signaling to the outside world that it no longer exists. That's why many have mentioned the "intrusive reference counting" scheme, which is one way to ensure that the object is only deleted when there are no more references to it. Another solution is to use a global (singleton-like) repository of "valid" objects, in which case any accesses to the object must go through a check in the repository and the object must also add/remove itself from the repository at the same time as it makes the new and delete this; calls (either as part of an overloaded new/delete, or alongside every new/delete calls).
However, there is a much simpler and less intrusive way to achieve the same behavior, albeit less economical. One can use a self-referencing shared_ptr scheme. As so:
class AutonomousObject {
private:
std::shared_ptr<AutonomousObject> m_shared_this;
protected:
AutonomousObject(/* some params */);
public:
virtual ~AutonomousObject() { };
template <typename... Args>
static std::weak_ptr<AutonomousObject> Create(Args&&... args) {
std::shared_ptr<AutonomousObject> result(new AutonomousObject(std::forward<Args>(args)...));
result->m_shared_this = result; // link the self-reference.
return result; // return a weak-pointer.
};
// this is the function called when the life-time should be terminated:
void OnTerminate() {
m_shared_this.reset( NULL ); // do not use reset(), but use reset( NULL ).
};
};
With the above (or some variations upon this crude example, depending on your needs), the object will be alive for as long as it deems necessary and that no-one else is using it. The weak-pointer mechanism serves as the proxy to query for the existence of the object, by possible outside users of the object. This scheme makes the object a bit heavier (has a shared-pointer in it) but it is easier and safer to implement. Of course, you have to make sure that the object eventually deletes itself, but that's a given in this kind of scenario.
2) The second use-case I can think of ties in to the second motivation for restricting an object to be heap-only (see above), however, it applies also for when you don't restrict it as such. If you want to make sure that both the deallocation and the destruction are dispatched to the correct module (the module from which the object was allocated and constructed), you must use a dynamic dispatching method. And for that, the easiest is to just use a virtual function. However, a virtual destructor is not going to cut it because it only dispatches the destruction, not the deallocation. The solution is to use a virtual "destroy" function that calls delete this; on the object in question. Here is a simple scheme to achieve this:
struct CrossModuleDeleter; //forward-declare.
class CrossModuleObject {
private:
virtual void Destroy() /* final */;
public:
CrossModuleObject(/* some params */); //constructor can be public.
virtual ~CrossModuleObject() { }; //destructor can be public.
//.... whatever...
friend struct CrossModuleDeleter;
template <typename... Args>
static std::shared_ptr< CrossModuleObject > Create(Args&&... args);
};
struct CrossModuleDeleter {
void operator()(CrossModuleObject* p) const {
p->Destroy(); // do a virtual dispatch to reach the correct deallocator.
};
};
// In the cpp file:
// Note: This function should not be inlined, so stash it into a cpp file.
void CrossModuleObject::Destroy() {
delete this;
};
template <typename... Args>
std::shared_ptr< CrossModuleObject > CrossModuleObject::Create(Args&&... args) {
return std::shared_ptr< CrossModuleObject >( new CrossModuleObject(std::forward<Args>(args)...), CrossModuleDeleter() );
};
The above kind of scheme works well in practice, and it has the nice advantage that the class can act as a base-class with no additional intrusion by this virtual-destroy mechanism in the derived classes. And, you can also modify it for the purpose of allowing only heap-based objects (as usually, making constructors-destructors private or protected). Without the heap-based restriction, the advantage is that you can still use the object as a local variable or data member (by value) if you want, but, of course, there will be loop-holes left to avoid by whoever uses the class.
As far as I know, these are the only legitimate use-cases I have ever seen anywhere or heard of (and the first one is easily avoidable, as I have shown, and often should be).
The general reason is that the lifetime of the object is determined by some factor internal to the class, at least from an application viewpoint. Hence, it may very well be a private method which calls delete this;.
Obviously, when the object is the only one to know how long it's needed, you can't put it on a random thread stack. It's necessary to create such objects on the heap.
It's generally an exceptionally bad idea. There are a very few cases- for example, COM objects have enforced intrusive reference counting. You'd only ever do this with a very specific situational reason- never for a general-purpose class.
1) Why would I want to force the object to be made on the heap instead of on the stack?
Because its life span isn't determined by the scoping rule.
2) Is there another use of delete this apart from this? (supposing that this is a legitimate use of it :) )
You use delete this when the object is the best placed one to be responsible for its own life span. One of the simplest example I know of is a window in a GUI. The window reacts to events, a subset of which means that the window has to be closed and thus deleted. In the event handler the window does a delete this. (You may delegate the handling to a controller class. But the situation "window forwards event to controller class which decides to delete the window" isn't much different of delete this, the window event handler will be left with the window deleted. You may also need to decouple the close from the delete, but your rationale won't be related to the desirability of delete this).
delete this;
can be useful at times and is usually used for a control class that also controls the lifetime of another object. With intrusive reference counting, the class it is controlling is one that derives from it.
The outcome of using such a class should be to make lifetime handling easier for users or creators of your class. If it doesn't achieve this, it is bad practice.
A legitimate example may be where you need a class to clean up all references to itself before it is destructed. In such a case, you "tell" the class whenever you are storing a reference to it (in your model, presumably) and then on exit, your class goes around nulling out these references or whatever before it calls delete this on itself.
This should all happen "behind the scenes" for users of your class.
"Why would I want to force the object to be made on the heap instead of on the stack?"
Generally when you force that it's not because you want to as such, it's because the class is part of some polymorphic hierarchy, and the only legitimate way to get one is from a factory function that returns an instance of a different derived class according to the parameters you pass it, or according to some configuration that it knows about. Then it's easy to arrange that the factory function creates them with new. There's no way that users of those classes could have them on the stack even if they wanted to, because they don't know in advance the derived type of the object they're using, only the base type.
Once you have objects like that, you know that they're destroyed with delete, and you can consider managing their lifecycle in a way that ultimately ends in delete this. You'd only do this if the object is somehow capable of knowing when it's no longer needed, which usually would be (as Mike says) because it's part of some framework that doesn't manage object lifetime explicitly, but does tell its components that they've been detached/deregistered/whatever[*].
If I remember correctly, James Kanze is your man for this. I may have misremembered, but I think he occasionally mentions that in his designs delete this isn't just used but is common. Such designs avoid shared ownership and external lifecycle management, in favour of networks of entity objects managing their own lifecycles. And where necessary, deregistering themselves from anything that knows about them prior to destroying themselves. So if you have several "tools" in a "toolbelt" then you wouldn't construe that as the toolbelt "owning" references to each of the tools, you think of the tools putting themselves in and out of the belt.
[*] Otherwise you'd have your factory return a unique_ptr or auto_ptr to encourage callers to stuff the object straight into the memory management type of their choice, or you'd return a raw pointer but provide the same encouragement via documentation. All the stuff you're used to seeing.
A good rule of thumb is not to use delete this.
Simply put, the thing that uses new should be responsible enough to use the delete when done with the object. This also avoids the problems with is on the stack/heap.
Once upon a time i was writing some plugin code. I believe i mixed build (debug for plugin, release for main code or maybe the other way around) because one part should be fast. Or maybe another situation happened. Such main is already released built on gcc and plugin is being debugged/tested on VC. When the main code deleted something from the plugin or plugin deleted something a memory issue would occur. It was because they both used different memory pools or malloc implementations. So i had a private dtor and a virtual function called deleteThis().
-edit- Now i may consider overloading the delete operator or using a smart pointer or simply just state never delete a function. It will depend and usually overloading new/delete should never be done unless you really know what your doing (dont do it). I decide to use deleteThis() because i found it easier then the C like way of thing_alloc and thing_free as deleteThis() felt like the more OOP way of doing it
I'm coming from C# and trying to translate some of my practices into C++. I've used dependency injection in various places throughout my code using raw pointers. Then I decide to replace the raw pointers with std::shared_ptr's. As part of that process it was suggested that I consider using stack allocated automatic variables rather than dynamically allocating them (see this question although that question was in the context of unique_ptr so maybe that is different).
I believe the below example shows the use of automatic variables.
class MyClass
{
public:
MyClass(ApplicationService& app): appService_(app)
{
}
~MyClass()
{
appService_.Destroy(something);
}
private:
ApplicationService& appService_;
}
class ConsumerClass
{
DoSomething()
{
CustomApplicationService customAppService;
MyClass myclass(customAppService);
myclass...
}
}
In the above example, when customAppservice and myclass go out of scope how do I know which will be destroyed first? If customAppService is destroyed first than the MyClass destructor will fail. Is this a good reason to use shared_ptr instead in this scenario or is there a clean way around this?
UPDATE
ApplicationService is a class that is a wrapper around global functions needed to interact with a 3rd party library that my code uses. I have this class as I believe it's the standard way to support unit testing and stubbing/mocking of free standing functions. This class simply delegates calls to the corresponding global functions. The call appService_.Destroy(something); is actually destroying an object used by each specific instance of MyClass not destroying anything do with the Application class itself.
The answer is: you don't need to know, as your design is broken, anyway.
First, a Destroy sounds like a bad idea, furthermore if called in an object that is not responsible for the destruction of the other object. The code from the Destroy method belongs into ApplicationService's destructor (which is hopefully virtual, although in this case it doesn't actually need to), which in contrast to C# gets called at a perfectly determined point in time.
Once you've done this, you will (hopefully) realize, that it is not the responsibility of MyClass to destroy the appService_, as it does not own it. It is the responsibility of the ConsumerClass (or rather the DoSomething method), which really manages the actual service and which does actually destroy it automatically once you've moved Destroy's code into the destructor. Isn't it nice how RAII does make happen everything in a clean and automatic way?
class MyClass
{
public:
MyClass(ApplicationService& app): appService_(app)
{
}
private:
ApplicationService& appService_;
}
class ConsumerClass
{
DoSomething()
{
CustomApplicationService customAppService;
MyClass myclass(customAppService);
myclass...
}
}
class ApplicationService
{
public:
virtual ~ApplicationService()
{
//code from former Destroy method
}
}
class CustomApplicationService
{
public:
virtual ~CustomApplicationService()
{
//code from former Destroy method
}
}
This is IMHO the perfect clean C++ way around it and the problem is definitely not a reason to spam shared_ptrs. Even if you really need a dedicated Destroy method and cannot move the code into the destructor (which I would take as a motivation for overthinking the design), then you would still call Destroy from DoSomething as again, MyClass is not responsible for destroying the appService_.
EDIT: According to you update (and my stupid overlooking of the something argument), your design seems indeed quite correct (at least if you cannot mess with changing the ApplicationService), sorry.
Allthough class members should get destroyed in reverse order of construction, I'm not sure this also holds for local automatic variables. What you could do to make sure the destructors get called in a defined order is introduce nested scopes using simple blocks:
void DoSomething()
{
CustomApplicationService customAppService;
{
MyClass myclass(customAppService);
myclass...
} // myclass destroyed
} // customAppService destroyed
Of course there is still completely no need to use dynamic allocation, let aside shared_ptrs. Although the nested blocks blow the code a bit, it is nothing against the ugliness of dynamic allocation applied in a non-dynamic way and without reason and it at least "looks nice in a semantic way" with customAppService's declaration on top of the block ;)
In C++, objects, in general, are destroyed in the order that is exact opposite of the order they were created in.
Based on your example, MyClass will be destroyed before CustomApplicationService
The exception is when a destructor is called explicitly. However, I don't think you should concern yourself with this exception at this stage.
Another subtlety is called static initialization order fiasco . However, this does not apply to automatic (stack) variables.
Edit:
From C++2003 - looked for 'reverse order'
6.6.0.2
On exit from a scope (however accomplished), destructors (12.4) are called for all
constructed objects with automatic storage duration (3.7.2) (named objects or
temporaries) that are declared in that scope, in the reverse order of their
declaration. ... [Note: However, the program can be terminated (by calling exit()
or abort()(18.3), for example) without destroying class objects with automatic
storage duration. ]
I just fixed a memory leak caused by someone forgetting to call the superclass's OnUnload in their override of it. The superclass version frees some resources (as does its superclass).
Are there external static analysis tools, or at least some kind of runtime trick I can do to detect this? With the ability to make an exception obviously (though these cases are exceedingly rare).
UPDATE: Based on the answers below, I need to add constraints that are specific to our setup, which is a game for Wii/360/PS3. Very specific engine for a very specific application.
We have a deep hierarchy of game object classes (a design I never agreed with, but it's the design we are shipping). Deep and wide, actually. I am going to redo this for the next game to use a Dungeon Siege-style component-based system but in our current codebase, deep hierarchies make the DispatchVirtual() -> onVirtual() pattern difficult to apply.
Destructors do not get called for our game objects because delete doesn't get called. Game objects go into an add-only (stack) allocator-based pool during a world load. At the end of a level I just set the stack pointer back to the low water mark to free everything at once. In advance, we iterate all objects and call OnUnload on them so they can free any external resources they use. You might call it "garbage collection: the nuclear option". So no destructors.
Even if we could use a destructor-based approach it would only solve the narrow problem of an OnUnload or OnFree, but not OnUpdate, OnWorldMessage, OnLoaded, etc.
Runtime solutions are interesting but I hate relying on testing to catch this. Optimal would be either a compile-time template trick or an external static analysis tool I can use.
Don't trust the derived classes to do it; use the template method design pattern to ensure your base class behavior will always happen:
class Base
{
public:
void OnUnload()
{
// Do stuff that must always be done.
this->doOnUnload();
}
private:
// Virtual method for derived classes to override.
// Can be pure virtual if it will always be overridden.
virtual void doOnUnload()
{
// Empty default implementation
}
};
The only problem is that this only buys you one level of inheritance, and your problem says you need two. In which case, this pattern can be repeated.
But in general, it's usually more stable to have base classes call down to derived classes for specific behavior than to require derived classes to call up to base classes.
A runtime "trick" you could use is to assert in the destructor of the base class if the constraint you are looking for has failed. Assuming the instance is actually destroyed and not leaked, this will tell you at the time the object is destroyed if the contract was correctly followed.
A "runtime trick" is to wrap your resources in a class and make sure that resource class handles allocation / deallocation appropriately. A major benefit you have in C++ over 3G languages is multiple inheritance.
Could you C++ developers please give us a good description of what RAII is, why it is important, and whether or not it might have any relevance to other languages?
I do know a little bit. I believe it stands for "Resource Acquisition is Initialization". However, that name doesn't jive with my (possibly incorrect) understanding of what RAII is: I get the impression that RAII is a way of initializing objects on the stack such that, when those variables go out of scope, the destructors will automatically be called causing the resources to be cleaned up.
So why isn't that called "using the stack to trigger cleanup" (UTSTTC:)? How do you get from there to "RAII"?
And how can you make something on the stack that will cause the cleanup of something that lives on the heap? Also, are there cases where you can't use RAII? Do you ever find yourself wishing for garbage collection? At least a garbage collector you could use for some objects while letting others be managed?
Thanks.
So why isn't that called "using the stack to trigger cleanup" (UTSTTC:)?
RAII is telling you what to do: Acquire your resource in a constructor! I would add: one resource, one constructor. UTSTTC is just one application of that, RAII is much more.
Resource Management sucks. Here, resource is anything that needs cleanup after use. Studies of projects across many platforms show the majority of bugs are related to resource management - and it's particularly bad on Windows (due to the many types of objects and allocators).
In C++, resource management is particularly complicated due to the combination of exceptions and (C++ style) templates. For a peek under the hood, see GOTW8).
C++ guarantees that the destructor is called if and only if the constructor succeeded. Relying on that, RAII can solve many nasty problems the average programmer might not even be aware of. Here are a few examples beyond the "my local variables will be destroyed whenever I return".
Let us start with an overly simplistic FileHandle class employing RAII:
class FileHandle
{
FILE* file;
public:
explicit FileHandle(const char* name)
{
file = fopen(name);
if (!file)
{
throw "MAYDAY! MAYDAY";
}
}
~FileHandle()
{
// The only reason we are checking the file pointer for validity
// is because it might have been moved (see below).
// It is NOT needed to check against a failed constructor,
// because the destructor is NEVER executed when the constructor fails!
if (file)
{
fclose(file);
}
}
// The following technicalities can be skipped on the first read.
// They are not crucial to understanding the basic idea of RAII.
// However, if you plan to implement your own RAII classes,
// it is absolutely essential that you read on :)
// It does not make sense to copy a file handle,
// hence we disallow the otherwise implicitly generated copy operations.
FileHandle(const FileHandle&) = delete;
FileHandle& operator=(const FileHandle&) = delete;
// The following operations enable transfer of ownership
// and require compiler support for rvalue references, a C++0x feature.
// Essentially, a resource is "moved" from one object to another.
FileHandle(FileHandle&& that)
{
file = that.file;
that.file = 0;
}
FileHandle& operator=(FileHandle&& that)
{
file = that.file;
that.file = 0;
return *this;
}
}
If construction fails (with an exception), no other member function - not even the destructor - gets called.
RAII avoids using objects in an invalid state. it already makes life easier before we even use the object.
Now, let us have a look at temporary objects:
void CopyFileData(FileHandle source, FileHandle dest);
void Foo()
{
CopyFileData(FileHandle("C:\\source"), FileHandle("C:\\dest"));
}
There are three error cases to handled: no file can be opened, only one file can be opened, both files can be opened but copying the files failed. In a non-RAII implementation, Foo would have to handle all three cases explicitly.
RAII releases resources that were acquired, even when multiple resources are acquired within one statement.
Now, let us aggregate some objects:
class Logger
{
FileHandle original, duplex; // this logger can write to two files at once!
public:
Logger(const char* filename1, const char* filename2)
: original(filename1), duplex(filename2)
{
if (!filewrite_duplex(original, duplex, "New Session"))
throw "Ugh damn!";
}
}
The constructor of Logger will fail if original's constructor fails (because filename1 could not be opened), duplex's constructor fails (because filename2 could not be opened), or writing to the files inside Logger's constructor body fails. In any of these cases, Logger's destructor will not be called - so we cannot rely on Logger's destructor to release the files. But if original was constructed, its destructor will be called during cleanup of the Logger constructor.
RAII simplifies cleanup after partial construction.
Negative points:
Negative points? All problems can be solved with RAII and smart pointers ;-)
RAII is sometimes unwieldy when you need delayed acquisition, pushing aggregated objects onto the heap.
Imagine the Logger needs a SetTargetFile(const char* target). In that case, the handle, that still needs to be a member of Logger, needs to reside on the heap (e.g. in a smart pointer, to trigger the handle's destruction appropriately.)
I have never wished for garbage collection really. When I do C# I sometimes feel a moment of bliss that I just do not need to care, but much more I miss all the cool toys that can be created through deterministic destruction. (using IDisposable just does not cut it.)
I have had one particularly complex structure that might have benefited from GC, where "simple" smart pointers would cause circular references over multiple classes. We muddled through by carefully balancing strong and weak pointers, but anytime we want to change something, we have to study a big relationship chart. GC might have been better, but some of the components held resources that should be release ASAP.
A note on the FileHandle sample: It was not intended to be complete, just a sample - but turned out incorrect. Thanks Johannes Schaub for pointing out and FredOverflow for turning it into a correct C++0x solution. Over time, I've settled with the approach documented here.
There are excellent answers out there, so I just add some things forgotten.
##0. RAII is about scopes
RAII is about both:
acquiring a resource (no matter what resource) in the constructor, and un-acquiring it in the destructor.
having the constructor executed when the variable is declared, and the destructor automatically executed when the variable goes out of scope.
Others already answered about that, so I won't elaborate.
##1. When coding in Java or C#, you already use RAII...
MONSIEUR JOURDAIN: What! When I say, "Nicole, bring me my slippers,
and give me my nightcap," that's prose?
PHILOSOPHY MASTER: Yes, Sir.
MONSIEUR JOURDAIN: For more than forty years I have been speaking prose without knowing anything about it, and I am much obliged to you for having taught me that.
— Molière: The Middle Class Gentleman, Act 2, Scene 4
As Monsieur Jourdain did with prose, C# and even Java people already use RAII, but in hidden ways. For example, the following Java code (which is written the same way in C# by replacing synchronized with lock):
void foo()
{
// etc.
synchronized(someObject)
{
// if something throws here, the lock on someObject will
// be unlocked
}
// etc.
}
... is already using RAII: The mutex acquisition is done in the keyword (synchronized or lock), and the un-acquisition will be done when exiting the scope.
It's so natural in its notation it requires almost no explanation even for people who never heard about RAII.
The advantage C++ has over Java and C# here is that anything can be made using RAII. For example, there are no direct build-in equivalent of synchronized nor lock in C++, but we can still have them.
In C++, it would be written:
void foo()
{
// etc.
{
Lock lock(someObject) ; // lock is an object of type Lock whose
// constructor acquires a mutex on
// someObject and whose destructor will
// un-acquire it
// if something throws here, the lock on someObject will
// be unlocked
}
// etc.
}
which can be easily written as it would be in Java/C# (using C++ macros):
#define LOCK(mm_mutex) \
if(Lock lock{mm_mutex}) {} \
else
void foo()
{
// etc.
LOCK(someObject)
{
// if something throws here, the lock on someObject will
// be unlocked
}
// etc.
}
##2. RAII have alternate uses
WHITE RABBIT: [singing] I'm late / I'm late / For a very important date. / No time to say "Hello." / Goodbye. / I'm late, I'm late, I'm late.
— Alice in Wonderland (Disney version, 1951)
You know when the constructor will be called (at the object declaration), and you know when its corresponding destructor will be called (at the exit of the scope), so you can write almost magical code with but a line. Welcome to the C++ wonderland (at least, from a C++ developer's viewpoint).
For example, you can write a counter object (I let that as an exercise) and use it just by declaring its variable, like the lock object above was used:
void foo()
{
double timeElapsed = 0 ;
{
Counter counter(timeElapsed) ;
// do something lengthy
}
// now, the timeElapsed variable contain the time elapsed
// from the Counter's declaration till the scope exit
}
which of course, can be written, again, the Java/C# way using a macro:
void foo()
{
double timeElapsed = 0 ;
COUNTER(timeElapsed)
{
// do something lengthy
}
// now, the timeElapsed variable contain the time elapsed
// from the Counter's declaration till the scope exit
}
##3. Why does C++ lack finally?
[SHOUTING] It's the final countdown!
— Europe: The Final Countdown (sorry, I was out of quotes, here... :-)
The finally clause is used in C#/Java to handle resource disposal in case of scope exit (either through a return or a thrown exception).
Astute specification readers will have noticed C++ has no finally clause. And this is not an error, because C++ does not need it, as RAII already handle resource disposal. (And believe me, writing a C++ destructor is magnitudes easier than writing the right Java finally clause, or even a C#'s correct Dispose method).
Still, sometimes, a finally clause would be cool. Can we do it in C++? Yes, we can! And again with an alternate use of RAII.
##Conclusion: RAII is a more than philosophy in C++: It's C++
RAII? THIS IS C++!!!
— C++ developer's outraged comment, shamelessly copied by an obscure Sparta king and his 300 friends
When you reach some level of experience in C++, you start thinking in terms of RAII, in terms of construtors and destructors automated execution.
You start thinking in terms of scopes, and the { and } characters become ones of the most important in your code.
And almost everything fits right in terms of RAII: exception safety, mutexes, database connections, database requests, server connection, clocks, OS handles, etc., and last, but not least, memory.
The database part is not negligible, as, if you accept to pay the price, you can even write in a "transactional programming" style, executing lines and lines of code until deciding, in the end, if you want to commit all the changes, or, if not possible, having all the changes reverted back (as long as each line satisfy at least the Strong Exception Guarantee). (see the second part of this Herb's Sutter article for the transactional programming).
And like a puzzle, everything fits.
RAII is so much part of C++, C++ could not be C++ without it.
This explains why experienced C++ developers are so enamored with RAII, and why RAII is the first thing they search when trying another language.
And it explains why the Garbage Collector, while a magnificient piece of technology in itself, is not so impressive from a C++ developer's viewpoint:
RAII already handles most of the cases handled by a GC
A GC deals better than RAII with circular references on pure managed objects (mitigated by smart uses of weak pointers)
Still A GC is limited to memory, while RAII can handle any kind of resource.
As described above, RAII can do much, much more...
RAII is using C++ destructors semantics to manage resources. For example, consider a smart pointer. You have a parameterized constructor of the pointer that initializes this pointer with the adress of object. You allocate a pointer on stack:
SmartPointer pointer( new ObjectClass() );
When the smart pointer goes out of scope the destructor of the pointer class deletes the connected object. The pointer is stack-allocated and the object - heap-allocated.
There are certain cases when RAII doesn't help. For example, if you use reference-counting smart pointers (like boost::shared_ptr) and create a graph-like structure with a cycle you risk facing a memory leak because the objects in a cycle will prevent each other from being released. Garbage collection would help against this.
I'd like to put it a bit more strongly then previous responses.
RAII, Resource Acquisition Is Initialization means that all acquired resources should be acquired in the context of the initialization of an object. This forbids "naked" resource acquisition. The rationale is that cleanup in C++ works on object basis, not function-call basis. Hence, all cleanup should be done by objects, not function calls. In this sense C++ is more-object oriented then e.g. Java. Java cleanup is based on function calls in finally clauses.
I concur with cpitis. But would like to add that the resources can be anything not just memory. The resource could be a file, a critical section, a thread or a database connection.
It is called Resource Acquisition Is Initialization because the resource is acquired when the object controlling the resource is constructed, If the constructor failed (ie due to an exception) the resource is not acquired. Then once the object goes out of scope the resource is released. c++ guarantees that all objects on the stack that have been successfully constructed will be destructed (this includes constructors of base classes and members even if the super class constructor fails).
The rational behind RAII is to make resource acquisition exception safe. That all resources acquired are properly released no matter where an exception occurs. However this does rely on the quality of the class that acquires the resource (this must be exception safe and this is hard).
The problem with garbage collection is that you lose the deterministic destruction that's crucial to RAII. Once a variable goes out of scope, it's up to the garbage collector when the object will be reclaimed. The resource that's held by the object will continue to be held until the destructor gets called.
RAII comes from Resource Allocation Is Initialization. Basically, it means that when a constructor finishes the execution, the constructed object is fully initialized and ready to use. It also implies that the destructor will release any resources (e.g. memory, OS resources) owned by the object.
Compared with garbage collected languages/technologies (e.g. Java, .NET), C++ allows full control of the life of an object. For a stack allocated object, you'll know when the destructor of the object will be called (when the execution goes out of the scope), thing that is not really controlled in case of garbage collection. Even using smart pointers in C++ (e.g. boost::shared_ptr), you'll know that when there is no reference to the pointed object, the destructor of that object will be called.
And how can you make something on the stack that will cause the cleanup of something that lives on the heap?
class int_buffer
{
size_t m_size;
int * m_buf;
public:
int_buffer( size_t size )
: m_size( size ), m_buf( 0 )
{
if( m_size > 0 )
m_buf = new int[m_size]; // will throw on failure by default
}
~int_buffer()
{
delete[] m_buf;
}
/* ...rest of class implementation...*/
};
void foo()
{
int_buffer ib(20); // creates a buffer of 20 bytes
std::cout << ib.size() << std::endl;
} // here the destructor is called automatically even if an exception is thrown and the memory ib held is freed.
When an instance of int_buffer comes into existence it must have a size, and it will allocate the necessary memory. When it goes out of scope, it's destructor is called. This is very useful for things like synchronization objects. Consider
class mutex
{
// ...
take();
release();
class mutex::sentry
{
mutex & mm;
public:
sentry( mutex & m ) : mm(m)
{
mm.take();
}
~sentry()
{
mm.release();
}
}; // mutex::sentry;
};
mutex m;
int getSomeValue()
{
mutex::sentry ms( m ); // blocks here until the mutex is taken
return 0;
} // the mutex is released in the destructor call here.
Also, are there cases where you can't use RAII?
No, not really.
Do you ever find yourself wishing for garbage collection? At least a garbage collector you could use for some objects while letting others be managed?
Never. Garbage collection only solves a very small subset of dynamic resource management.
There are already a lot of good answers here, but I'd just like to add:
A simple explanation of RAII is that, in C++, an object allocated on the stack is destroyed whenever it goes out of scope. That means, an objects destructor will be called and can do all necessary cleanup.
That means, if an object is created without "new", no "delete" is required. And this is also the idea behind "smart pointers" - they reside on the stack, and essentially wraps a heap based object.
RAII is an acronym for Resource Acquisition Is Initialization.
This technique is very much unique to C++ because of their support for both Constructors & Destructors & almost automatically the constructors that are matching that arguments being passed in or the worst case the default constructor is called & destructors if explicity provided is called otherwise the default one that is added by the C++ compiler is called if you didn't write an destructor explicitly for a C++ class. This happens only for C++ objects that are auto-managed - meaning that are not using the free store (memory allocated/deallocated using new,new[]/delete,delete[] C++ operators).
RAII technique makes use of this auto-managed object feature to handle the objects that are created on the heap/free-store by explcitly asking for more memory using new/new[], which should be explicitly destroyed by calling delete/delete[]. The auto-managed object's class will wrap this another object that is created on the heap/free-store memory. Hence when auto-managed object's constructor is run, the wrapped object is created on the heap/free-store memory & when the auto-managed object's handle goes out of scope, destructor of that auto-managed object is called automatically in which the wrapped object is destroyed using delete. With OOP concepts, if you wrap such objects inside another class in private scope, you wouldn't have access to the wrapped classes members & methods & this is the reason why smart pointers (aka handle classes) are designed for. These smart pointers expose the wrapped object as typed object to external world & there by allowing to invoke any members/methods that the exposed memory object is made up of. Note that smart pointers have various flavors based on different needs. You should refer to Modern C++ programming by Andrei Alexandrescu or boost library's (www.boostorg) shared_ptr.hpp implementation/documentation to learn more about it. Hope this helps you to understand RAII.
Been doing Java for number of years so haven't been tracking C++. Has finally clause been added to C++ exception handling in the language definition?
Is there a favored idiom that mimics Java's try/finally?
Am also bothered that C++ doesn't have an ultimate super type for all possible exceptions that could be thrown - like Java's Throwable class.
I can write:
try {
// do something
} catch(...) {
// alas, can't examine the exception
// can only do cleanup code and perhaps rethrow, ala:
throw;
}
ADDENDUM EDIT:
I ended up accepting the answer that
had the most up votes, i.e., use
destructors to do cleanup. Of course,
from my own comments, it is clear I
don't entirely agree with that.
However, C++ is what it is and so in
the application endeavor I have in
mind, I'm going to more or less strive
to adhere to common community
practice. I'll use template classes to
wrap resources that don't already have
a class destructor (i.e., C library
resources), thus bestowing on them
destructor semantics.
NEW ADDENDUM EDIT:
Hmm, instead of finally then a closure
feature perhaps? A closure combined with
ScopeGuard approach (see one of the
answers below) would be a way to
accomplish cleanup with arbitrary
actions and access to the cleanup
code's outer scope context. Cleanup could be done in the idiom fashion that is seen in Ruby programming where they supply cleanup blocks when a resource is being opened. Isn't a
closure feature being considered for
C++?
By making effective use of destructors. When an exception is thrown in a try block, any object created within it will be destroyed immediately (and hence its destructor called).
This is different from Java where you have no idea when an object's finalizer will be called.
UPDATE: Straight from the horse's mouth: Why doesn't C++ provide a "finally" construct?
My $.02. I've been programming in managed languages like C# and Java for years, but was forced to make the switch to C++ for the purposes of speed. At first I couldn't believe how I had to write out the method signature twice in the header file and then the cpp file, and I didn't like how there was no finally block, and no garbage collection meant tracking memory leaks everywhere - gosh I didn't like it at all!
However, as I said I was forced to use C++. So I was forced to seriously learn it, and now I've finally understood all the programming idioms like RAII and I get all the subtleties of the language and such. It took me a while but now I see just how different of a language it is compared to C# or Java.
These days I think C++ is the best language there is! Yes, I can understand that there is a little more what I call 'chaff' sometimes (seemingly unnecessary stuff to write), but after actually using the language seriously, I've changed my mind about it completely.
I used to have memory leaks all the time. I used to write all my code into the .h file because I hated the separation of code, I couldn't understand why they would do that! And I used to always end up with stupid cyclic include dependencies, and heaps more. I was really hung up on C# or Java, to me C++ was a huge step down. These days I get it. I almost never have memory leaks, I enjoy the separation of interface and implementation, and I don't have problems with cycle dependencies anymore.
And I don't miss the finally block either. To be honest, my opinion is that these C++ programmers that you talk about writing repeated cleanup actions in catch blocks just sound to me like they're just bad C++ programmers. I mean, it doesn't look like any of the other C++ programmers in this thread are having any of the problems you mention. RAII really does make finally redundant, and if anything, it's less work. You write one destructor and then you never have to write another finally ever! Well at least for that type.
With respect, what I think is going on is you're just used to Java now, just like I had been.
C++'s answer is RAII: The object's destructor will be executed when they go out of scope. Whether by a return, by an exception or whatever. If you handle the exception somewhere else, you can be sure all objects from the called function down to your handler will be properly destructed by having their destructor called. They will clean up for you.
Read http://en.wikipedia.org/wiki/Resource_acquisition_is_initialization
No finally has not been added to C++, nor is it likely to ever be added.
The way C++ uses constructor/destructor makes the need for finally unnecessary.
If you are using catch(...) to cleanup then you are not using C++ properly. The cleanup code should all be in the destructor.
Though it is not a requirement to use it C++ does have a std::exception.
Forcing developers to derive from a specific class to use exception goes against the keep it simple philosophy of C++. Its also why we don't require all classes to derive from Object.
Read: Does C++ support 'finally' blocks? (And what's this 'RAII' I keep hearing about?)
The use of finally is more error prone than destructors to do clean up.
This is because you are forcing the user of the object to do clean up rather than the designer/implementer of the class.
Ok, I have to add in an answer to the points you made in a separate answer post:
(It would be a lot more convenient if you'd edited this into the original question, so it doesn't end up at the bottom below the answers to it.
If all cleanup always gets done in
destructors then there wouldn't need
to be any cleanup code in a catch
block - yet C++ has catch blocks where
cleanup actions get done. Indeed it
has a block for catch(...) where it is
only possible to do cleanup actions
(well, certainly can't get at any
exception information to do any
logging).
catch has a completely separate purpose, and as a Java programmer you should be aware of that. The finally clause is for "unconditional" cleanup actions. No matter how the block is exited, this must be done. Catch is for conditional cleanup. If this type of exception is thrown, we need to perform a few extra actions.
The cleanup in a finally block will
get done whether there was an
exception thrown or not - which is
what one always wants to happen when
cleanup code does exist.
Really? If we want it to always happen for this type (say, we always want to close a database connection when we're done with it), then why don't we define it once? In the type itself? Make the database connection close itself, rather than having to put a try/finally around every single use of it?
That's the point in destructors. They guarantee that each type is able to take care of its own cleanup, every time it's used, without the caller having to think of it.
C++ developers from day one have been
plagued with having to repeat cleanup
actions that appear in catch blocks in
the code flow that occurs upon
successful exit from the try block.
Java and C# programmers just do it
once in the finally block.
No. C++ programmers have never been plagued by that. C programmers have. And C programmers who realized that c++ had classes, and then called themselves C++ programmers have.
I program in C++ and C# daily, and I feel I'm plagued by C#'s ridiculous insistence that I must supply a finally clause (or a using block) EVERY SINGLE TIME I use a database connection or something else that must be cleaned up.
C++ lets me specify once and for all that "whenever we're done with this type, it should perform these actions". I don't risk forgetting to release memory. I don't risk forgetting to close file handles, sockets or database connections. Because my memory, my handles, sockets and db connections do it themselves.
How can it ever be preferable to have to write duplicate cleanup code every time you use a type? If you need to wrap the type because it doesn't have a destructor itself, you have two easy options:
Look for a proper C++ library which provides this destructor (hint: Boost)
Use boost::shared_ptr to wrap it, and supply it with a custom functor at runtime, specifying the cleanup to be done.
When you write application server
software like Java EE app servers
Glassfish, JBoss, etc., you want to be
able to catch and log exception
information - as opposed to let it
fall on the floor. Or worse fall into
the runtime and cause a ungraceful
abrupt exit of the application server.
That's why it's very desirable to have
an overarching base class for any
possible exception.
And C++ has just such a class. std::exception.
Have done C++ since the CFront days
and Java/C# most of this decade. Is
clear to see there's just an enormous
culture gap in how fundamentally
similar things are approached.
No, you've never done C++. You've done CFront, or C with classes. Not C++. There's a huge difference. Quit calling the answers lame, and you might learn something about the language you thought you knew. ;)
Cleanup functions, themselves, are thoroughly lame. They have low cohesion, in that they are expected to perform a series of activities only related in when they happen. They have high coupling, in that they need to have their internals modified when the functions that actually do something are changed. Because of this, they're error-prone.
The try...finally construct is a framework for cleanup functions. It is a language-encouraged way to write lousy code. Moreover, since it encourages writing the same cleanup code over and over, it undermines the DRY principle.
The C++ way is far preferable for these purposes. The cleanup code for a resource is written precisely once, in the destructor. It's in the same place as the rest of the code for that resource, and therefore has good cohesiveness. The cleanup code doesn't have to be put into unrelated modules, and therefore this cuts down on coupling. It is written precisely once, when well designed.
Moreover, the C++ way is much more uniform. C++, with the smart pointer additions, handles all sorts of resources in the same way, while Java handles memory well and provides inadequate constructs to release other resources.
There are plenty of problems with C++, but this isn't one of them. There are ways in which Java is better than C++, but this isn't one of them.
Java would be much better off with a way to implement RAII instead of try...finally.
To avoid having to define a wrapper class for every releasable resource, you may be interested in ScopeGuard (http://www.ddj.com/cpp/184403758) which allows one to create "cleaners" on the fly.
For example:
FILE* fp = SomeExternalFunction();
// Will automatically call fclose(fp) when going out of scope
ScopeGuard file_guard = MakeGuard(fclose, fp);
An Example of how difficult it is to use finally correctly.
Open and closing two files.
Where you want to guarantee that the file is closed correctly.
Waiting for the GC is not an option as the files may be re-used.
In C++
void foo()
{
std::ifstream data("plop");
std::ofstream output("plep");
// DO STUFF
// Files closed auto-magically
}
In a language with no destructors but has a finally clause.
void foo()
{
File data("plop");
File output("plep");
try
{
// DO STUFF
}
finally
{
// Must guarantee that both files are closed.
try {data.close();} catch(Throwable e){/*Ignore*/}
try {output.close();}catch(Throwable e){/*Ignore*/}
}
}
This is a simple example and already the code is getting convoluted. Here we are only trying to marshal 2 simple resources. But as the number of resources that need to be managed increases and/or their complexity increases the use of a finally block becomes harder and harder to use correctly in the presence of exceptions.
The use of finally moves responsibility for correct usage onto the user of an object. By using constructor/destructor mechanism provided by C++ you move the responsibility of correct usage to the designer/implementer of the class. This is inheritanly safer as the designer only needs to do it correctly once at the class level (rather than have different users try and do it correctly in different ways).
Using C++11 with its lambda expressions, I've recently started using the following code to mimic finally:
class FinallyGuard {
private:
std::function<void()> f_;
public:
FinallyGuard(std::function<void()> f) : f_(f) { }
~FinallyGuard() { f_(); }
};
void foo() {
// Code before the try/finally goes here
{ // Open a new scope for the try/finally
FinallyGuard signalEndGuard([&]{
// Code for the finally block goes here
});
// Code for the try block goes here
} // End scope, will call destructor of FinallyGuard
// Code after the try/finally goes here
}
The FinallyGuard is an object which is constructed with a callable function-like argument, preferrably a lambda expression. It will simply remember that function until its destructor is called, which is the case when the object goes out of scope, either due to normal control flow or due to stack unwinding during exception handling. In both cases, the destructor will call the function, thus executing the code in question.
It is a bit strange that you have to write the code for the finally before the code for the try block, but apart from that it actually feels a lot like a genuine try/finally from Java. I guess one should not abuse this for situations where an object with its own proper destructor would be more appropriate, but there are cases where I consider this approach above more suitable. I discussed one such scenario in this question.
As far as I understand things, std::function<void()> will use some pointer indirection and at least one virtual function call to perform its type erasure, so there will be a performance overhead. Don't use this technique in a tight loop where performance is critical. In those cases, a specialized object whose destructor does one thing only would be more appropriate.
C++ destructors make finally redundant. You can get the same effect by moving the cleanup code from finally to corresponding destructors.
I think that you are missing the point of what catch (...) can do.
You say in your example "alas, can't examine the exception". Well, you have no information about the type of the exception. You don't even know if it's a polymorphic type so even if you had some sort of an untyped reference to it, you couldn't even safely attempt a dynamic_cast.
If you know about certain exceptions or exception hierarchies that you can do something with then this is the place for catch blocks with explicity named types.
catch (...) is not often useful in C++. It can be used in places which have to guarantee that they don't throw, or only throw certain contracted exceptions. If you are using catch (...) for cleanup then there is a very good chance that your code is not robustly exception safe in any case.
As mentioned in other answers, if you are using local objects to manage resources (RAII) then it can be surprising and enlightening how few catch blocks you need, often - if you don't need to do anything locally with an exception - even the try block can be redundant as you let the exceptions flow out to the client code that can respond to them while still guaranteeing no resource issues.
To answer your original question, if you need some piece of code to run at the end of a block, exception or no exception, then a recipe would be.
class LocalFinallyReplacement {
~LocalFinallyReplacement() { /* Finally code goes here */ }
};
// ...
{ // some function...
LocalFinallyReplacement lfr; // must be a named object
// do something
}
Note how we can completely do away with try, catch and throw.
If you had data in the function that was originally declared outside the try block that you needed access to in the "finally" block, then you may need to add that to the constructor of the helper class and store it until the destructor. However, at this point I would seriously reconsider whether the problem could be resolved by altering the design of the local resource handling objects as it would imply something awry in the design.
Not completetely offtopic.
Boiler Plating DB Resource Cleanup in Java
sarcasm mode: Isn't the Java idiom wonderful?
I've done plenty of class design and template wrapper design in C++ over those 15 years and done it all the C++ way in terms of destructors cleaning up. Every project, though, also invariably involved the use of C libraries that provided resources with the open it, use it, close it usage model. A try/finally would mean such a resource can just be consumed where it needs to be - in a completely robust manner - and be done with it. The least tedium approach to programming that situation. Could deal with all the other state going on during the logic of that cleanup without having to be scoped away in some wrapper destructor.
I did most of my C++ coding on Windows so could always resort to using Microsoft's __try/__finally for such situations. (Their structured exception handling has some powerful abilities for interacting with exceptions.) Alas, doesn't look like C language has ever ratified any portable exception handling constructs.
That wasn't ideal solution, though, because it was not straightforward to blend C and C++ code in a try block where either style of exception might get thrown. A finally block added to C++ would have been helpful for those situations and would enable portability.
Regarding your addendum-edit, yes closures are being considered for C++0x. They can be used with RAII scoped guards to provide an easy to use solution, check Pizer's weblog. They can also be used to mimic try-finally, see this answer ; but is this really a good idea ? .
Thought I'd add my own solution to this - a kind of smart pointer wrapper for when you have to deal with non-RAII types.
Used like this:
Finaliser< IMAPITable, Releaser > contentsTable;
// now contentsTable can be used as if it were of type IMAPITable*,
// but will be automatically released when it goes out of scope.
So here's the implementation of Finaliser:
/* Finaliser
Wrap an object and run some action on it when it runs out of scope.
(A kind of 'finally.')
* T: type of wrapped object.
* R: type of a 'releaser' (class providing static void release( T* object )). */
template< class T, class R >
class Finaliser
{
private:
T* object_;
public:
explicit Finaliser( T* object = NULL )
{
object_ = object;
}
~Finaliser() throw()
{
release();
}
Finaliser< T, R >& operator=( T* object )
{
if (object_ != object && object_ != NULL)
{
release();
}
object_ = object;
return *this;
}
T* operator->() const
{
return object_;
}
T** operator&()
{
return &object_;
}
operator T*()
{
return object_;
}
private:
void release() throw()
{
R::release< T >( object_ );
}
};
... and here's Releaser:
/* Releaser
Calls Release() on the object (for use with Finaliser). */
class Releaser
{
public:
template< class T > static void release( T* object )
{
if (object != NULL)
{
object->Release();
}
}
};
I have a few different kinds of releaser like this, including one for free() and one for CloseHandle().