Click here to Skip to main content
Click here to Skip to main content

RAII, Dynamic Objects, and Factories in C++

By , 3 May 2005
 

Introduction

Preface

This article consists of two parts. The first part describes the concept of RAII in general. The second part continues with a special application of RAII for managing dynamic objects.

What is RAII?

  • The worst name invented in the history of C++: RAII means 'resource acquisition is initialization'. Stroustrup: "The basic idea is to represent a resource by a local object, so that the local object's destructor will release the resource. That way, the programmer cannot forget to release the resource". A resource is "any entity that a program acquires and releases. Typical examples are free store, file handles, threads, sockets".
  • A misnomer: The important characteristic of RAII is that resources are released in the destructor. Resources may have been acquired in the constructor or in a member function. Weaker varieties of RAII like std::auto_ptr don't even acquire a resource.
  • Nevertheless RAII is a very important and valuable idiom for managing resources in C++. Moreover, RAII is a genuine C++ technique not found in other programming languages. Binding resources to a scope significantly reduces the complexity of the whole program.

Advantages of RAII

What can you achieve with RAII?[1]

  • Automatic resource handling. Release (cleanup, deallocation, undo, rollback, ...) of various resources without manual interference by the user (user also needs no try, catch, finally, or using blocks).
  • Exception safety. Automatic resource management works for normal and exceptional program flow.
  • Encapsulation and information hiding. Resource acquisition and release are encapsulated in an object.
  • Locality of resources.
  • Deterministic Resource Management. You (can) know in advance when (where) the RAII objects go out of scope and therefore when the resources are released. Resources can be bound to a scope, function scope or block scope (if, do, while, for), in rare cases (Singleton) the global scope.
  • Transactional Programming ("ACID Programming"). Transactional concepts (Atomicity, Consistency, Isolation, Durability) from the database world applied to non-SQL programming.

[1] This list describes prototypical RAII and does not apply to all varieties of RAII.

Challenge

  • You have to plan the lifetime of resources.

Examples of RAII

  • Acquisition and release of resources, e.g., dynamic objects, database connections, locks, ...

    Example:

    void myFun()
    {
      XyzLib::Mutex mutex;
      mutex.lock()
      // do things in series ...
    }
    // mutex.unlock() is automatically called in the destructor of mutex
  • Set and reset the state of objects (devices), e.g., SetCurrentDirectory in constructor and reset it in destructor, start and stop a timer, set and reset a cursor (wait - arrow), ...

    Example:

    void myFun()
    {
      CWaitCursor waitCursor;
      performLongOperation();
      // ...
    }
    // MSDN: "The object's constructor automatically causes the wait cursor to be
    // displayed. When the object goes out of scope (at the end of the block in
    // which the CWaitCursor object is declared), its destructor sets the cursor
    // to the previous cursor. In other words, the object performs the necessary
    // clean-up automatically."
  • Perform undo or rollback.

    Example:

    void myFun (Database& db)
    {
      Transaction transaction (db);
      transaction.beginWork();
      //...
      
      if (something.isWrong())
      {
        throw runtime_error ("something wrong in myFun()");
      }
      //...
    
      transaction.commitWork();
    }
    // transaction.rollbackWork() is called in the destructor of
    // transaction if transaction.commitWork() fails or is not
    // reached, e.g. due to an exception

    Similar tasks can be quite daunting in languages that lack destructors and thus RAII.

Managing Dynamic Objects with RAII

RAII Containers for Dynamic Objects

Stroustrup explains RAII to a former C++ programmer who pretends to never have heard about RAII during 6 years of programming in C++:

"For example, a container is a systematic way of dealing with objects. Some of the things you can have in a container are pointers to other objects, but the container's constructors and destructor can take care of contained objects. The name of the game here is to get allocation out of the way so you don't see it. If you don't directly allocate something, you don't directly deallocate it, because whoever owns it deals with it. The notion of ownership is central. A container may own its objects because they are stored directly. A container of pointers either owns the pointed-to objects or it doesn't. If it contains 1000 pointers, there's only one decision to make. Does it own them, or doesn't it? That's a 1000 to 1 reduction in complexity. As you apply this technique recursively and in as many places as you can, allocation and deallocation disappear from the surface level of your code."

Implementing a RAII Factory for Dynamic Objects

Based on the above quotation from Stroustrup, the following code implements a RAII factory for dynamic objects. I use the term 'factory' here and not 'container' to avoid confusion with traditional containers, e.g., STL containers, and to emphasize the 'creational aspect'. Clarification: Neither the name 'RAII Factory' nor the following code stem from Bjarne Stroustrup.

Example: Consider the following simple class:

class MyClass
{
public:
  MyClass ()
  MyClass (int i)

  void set (int i);
  int  get ();
private:
// ...
};

Let's implement a RAII factory that creates objects of type MyClass:

class MyClassFactory
{
public:
  MyClass* create ()        { return imp.keep (new MyClass; }
  MyClass* create (int arg) { return imp.keep (new MyClass (arg)); }
private:
  RaiiFactoryImp<MyClass> imp;
};

Nothing fancy. MyClassFactory consists of a few lines of boilerplate code that forwards arguments to the MyClass constructor, calls the imp.keep() function, and returns the created object to the caller.

Common RAII factory code is factored out into an implementation class template called RaiiFactoryImp. Concrete RAII factories like MyClassFactory delegate repetitive functions to it.

RaiiFactoryImp basically has/implements two tasks. It:

  • stores dynamically created objects (keep()) and
  • destroys all stored objects in the destructor (~RaiiFactoryImp())
template <typename T>
class RaiiFactoryImp
{
public:
  ~RaiiFactoryImp()
  {
    while (!container.empty())
    {
      const T* p = container.back();
      container.pop_back();
      delete p;
    }
  }

  T* keep (T* p)
  {
    container.push_back (p);
    return p;
  }

private:
  std::vector<const T*> container;

  // non-copyable
  RaiiFactoryImp (const RaiiFactoryImp&);
  RaiiFactoryImp& operator= (const RaiiFactoryImp&);
};

A more polished version of RaiiFactoryImp can be found in the source code download.

Using the code: Place the RAII factory in the right scope and create as much dynamic objects as you need. All created objects are destroyed at the end of the scope, i.e., when the RAII factory goes out of scope.

void myFun (int n)
{
  MyClassFactory factory;
  
  for (int i = 0; i < n; ++i)
  {
    MyClass* p = factory.create (i);
    // ...
  }
}
// all objects created by factory are deleted here!

Features of RAII Factory

  • A RAII factory creates and stores objects. The create() function forwards arguments to the object's constructor.
  • Objects are either fully created and returned to the caller or an exception is thrown. There is no need to check the returned pointer for NULLness.
  • When the factory goes out of scope, it deletes all created objects in the destructor. The factory is non-copyable. The lifetime of objects is bound to a scope ('scope based resource management'). Programming with scope instead of programming with new and delete.
  • new and delete are encapsulated.
  • A factory owns created objects for their entire lifetime. There is no transfer of ownership, no release or detach function. The factory only lends objects to the user. This is also known as 'Producer-Product pattern' or 'Creator as Sole Owner pattern'.
  • Ease of use: The RAII factory implementation above contains no template parameters in the user interface.
  • Non-intrusive: RAII factories for third party classes can be written without changing the third party classes.

What is the Right Scope for a RAII Factory?

The RAII Factory deletes all objects when it goes out of scope. You have to put the factory in the right scope. But what is the right scope?

  • In general, the right scope is the scope in which the created objects are used. The lifetime of created objects cannot exceed the lifetime of the owning RAII factory. Returning a created object from the scope of the factory would crash the program. Of course, created objects and the factory can be passed 'down' to other functions by reference or by address.
  • The "Minimal Scoping Rule": Objects should not loiter around. They should only exist for the time, better, the scope they are needed: the minimal, lowest possible scope.
  • The lifetime of the RAII factory should exceed the lifetime of all pointers to created objects in order to avoid dangling pointers. The RAII factory should not go out of scope when pointers to created objects still exit.

When to use a RAII factory?

If you know in advance that you want to create only one object, you don't need to dynamically allocate anything and you also don't need a RAII factory. Just put the object on the stack. Likewise, for a fixed number of objects, you will probably use a stack-based array.

For an unknown number of objects - unknown at compile time - we have to distinguish between value objects and entity objects. See this article for a brief description of the distinction between value objects (Point, Date, ...) and entity objects (Account, DataBaseConnection, ...).

  • To create an unknown number of value objects, you typically copy each created object by value into a container and work with the container further on (iterate, search, sort, ...). Copying value objects is semantically correct and usually computationally cheap. There is no need for a RAII-Factory in this case, e.g.:
    // create n value objects
    void myFun (int n)
    {
      vector<Point> container;
      for (int i = 0; i < n; ++i)
      {
        //...
        Point pt (x, y);
        container.push_back (pt); // copy by value
        //...
      }
    }
  • A RAII factory is the right tool to create an unknown number of entity objects. Usually entity objects are non-copyable. In a sense, a RAII factory is a mechanism to 'extend' the stack for an indeterminate number of entity objects.

Extending RAII-Factory

The RAII factory described so far contains the basic implementation that can be extended in various ways. Examples:

An OO Variant

The following example outlines an OO variant of a RAII factory that produces base and derived class objects alike (if the constructor parameters match).

// base.h

class MyBase {
public:
  MyBase (int i);
  virtual ~MyBase(); //<A href="http://www.parashift.com/c++-faq-lite/virtual-functions.html" target=_blank>virtual destructor!</A>
// ...
};

A class derived from MyBase:

// derived.h

class MyDerived : public MyBase {
public:
  MyDerived (int i);
  virtual ~MyDerived();
// ...
};

MyPolymorphicFactory produces MyBase objects as well as objects of types derived from MyBase.

class MyPolymorphicFactory
{
public:
  template <typename T>
  MyBase* create (int arg) { return imp.keep (new T (arg)); }
private:
  RaiiFactoryImp<MyClass> imp;
};

Using the code:

void myFun (int n)
{
  MyPolymorphicFactory factory;

  for (int i = 0; i < n; ++i)
  {
    MyBase* m = factory.create<MyBase> (n);
    // ...
    m = factory.create<MyDerived> (n);
    // ...
  }
}

Note how the create function is defined and invoked as factory.create<MyBase>() or factory.create<MyDerived>(). The type of the object actually created is specified in angle brackets after the function name. This is called 'explicit function template argument specification'. You need a C++ compiler with advanced template support for this to work (not with VC++ 6.0).

A Generic RAII Factory

GFactory<T> is a class template that can be used to create objects of (almost) any type T. One limitation of this approach stems from the fact that many overloaded create() function templates are needed in GFactory because create() should support all combinations of const and non-const template parameters. Currently, GFactory<T>.create() can take up to 8 arguments (up to 16 if all arguments are const). The VC++ 6.0 compiler sometimes reports ambiguous calls (workaround: cast arguments to their type, see source code download for details). Current compilers like the VC++ 7.1 and the GCC 3.4 compiler work as expected.

#include "gfactory.h"

void myFun()
{
  GFactory<MyClass> myClassFactory;
  
  for (int i = 0; i < 10; ++i)
  {
    MyClass* m = myClassFactory.create (i);
    // ...
  }
}

Disposing Objects

Sometimes (rarely) you need to immediately destroy an object instead of waiting until the RAII factory goes out of scope. For this purpose, a dispose() function can be implemented. Be sure though that no dangling pointer is left in your code in this case.

MyClass* p = factory.create (i);
// ...
factory.dispose (p); // will delete p

Factory, Container, or Both?

Questions that may arise now:

  • Is a RAII factory just another container with additional create() functions to accomplish continuous ownership of created objects?
  • Which container functions should be added to a RAII factory then?
  • Should there even be a raii_factory_vector, raii_factory_list, raii_factory_map, etc.?

There are some good reasons to separate creation (factory) from iteration and other container functionality. This way you create objects by using a RAII factory and put them in a different, specialized container - preferably in a container appropriate for pointers like ptr_vector or in a hash table for fast access by key. Separation of concerns provides for flexibility in this case.

On the other hand, an all-in-one solution also has its merits. It's convenient to create and use objects in one place. In an example in the source code download, operator[] is implemented which can be used as iterator through the RAII factory, e.g.:

MyClassFactory factory;
// ...
for (int i = 0; i < factory.size(); ++i)
{
 cout << *factory[i] << endl;
}

So, what's the main difference between usual containers and RAII factories? Whereas containers are generic data structures, RAII factories are much more specialized in their objective. Resource management is only their most basic purpose. You easily come up with many useful features that you want to add to a RAII factory.

A powerful application of RAII factories are tree-like structures where each parent element produces n child elements which in turn become parent elements and so on. Many real world domains can naturally and efficiently be modeled as hierarchies of objects that produce and own their descendants.

Alternatives to RAII Factories

Manual Management of Dynamic Objects

Maybe you have seen C++ programs with new and delete statements scattered around the code, sometimes decorated with many try/catch blocks. This is a maintenance nightmare ("Shall I delete this object here or is it used further on?") and a resource management 'anti-pattern'. Most horror stories about 'memory problems' in C++ programs stem from people who have tried this approach. Manual management of dynamic objects, resources in general, is impractical for any but very small applications.

'Smart Pointers'

'Smart pointers' are not pointers but objects that mimic one aspect of pointers, that is, dereferencing. Additionally, they perform some extra, 'smart' task. E.g., std::auto_ptr and reference-counted 'smart pointers' manage the lifetime of objects for which a pointer is passed to them. In many cases, this combination of (partial) pointer functionality and resource management produces more troubles than benefits. Furthermore, resource-managing 'smart pointers' thwart deterministic resource management (you can always return, e.g., an auto_ptr). If you ask me, I would avoid 'smart pointers'. However, 'smart pointer' certainly is the best name invented in the history of C++.

Garbage Collection

Garbage Collection (GC) is a runtime mechanism that recycles unreferenced memory ('garbage') but offers no guarantee for the controlled destruction of objects. GC defeats the purpose of RAII and the unique advantage of C++: deterministic encapsulated resource management. You neither know when the collector kicks in nor when and if a 'finalizer' is called (and are even advised to avoid using a Finalize method). Exception handling gets complicated in GC languages because the responsibility of releasing resources other than pure memory is shifted on to the user. Strangely enough, GC does not necessarily prevent memory leaks [link1, link2, link3]. For C++, there is hardly a good reason to trade RAII for GC.

Conclusion

After a recap of the basic idea of RAII, this article has presented RAII factories, a special variety of RAII to handle dynamic objects. Compared to C++ code that is unaware of it, RAII saves you most new and delete statements. Compared to GC languages, RAII saves you most try, catch, finally, and using blocks. RAII fosters a C++ programming style that greatly simplifies resource handling. In Stroustrup's words again: "As you apply this technique recursively and in as many places as you can, allocation and deallocation disappear from the surface level of your code".

Online Resources

Bartosz Milewski: Resource Management in C++ [link1, link2, link3]

History

  • April 16, 2005 - Submission to CodeProject.
  • April 27, 2005 - Article update submitted: clarification on the origin of 'RAII Factory'.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Roland Pibinger
Web Developer
Austria Austria
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5memberSnacho17 Oct '12 - 9:56 
I have finally understood RAII concept in examples. Thank you.
NewsYin/Yang - finally a better name for RAII!memberRoland Pibinger10 Jan '07 - 6:55 
"Le Chaud Lapin" coined a new and IMO much better name for RAII: Yin/Yang[^]. "Yin/Yang symbolizes duality and symmetry. For every action, there is an opposite reaction."
I’d add that dynamically created objects may be created in any member function (not just the constructor) and may be deleted in any member function, preferably and at least in the destructor. This is also illustrated in the above article.
Smile | :) Frown | :(
GeneralPattern: Creator as Sole OwnermemberRoland Pibinger27 Aug '06 - 1:31 
Tom Cargill's seminal article 'Managing Dynamic Objects in C++'[^] (DDJ Jul 22 2001) is available online. It describes, among others, the 'Creator as Sole Owner' pattern on which RAIIFactory is based.
News&quot;GC is no silver bullet&quot;memberRoland Pibinger12 Nov '05 - 9:01 
Another interesting article by Danny Kalev: "A Garbage Collector for C++"[^]

"If garbage collection is almost 50 years old, one wonders why many programming languages have deliberately chosen not to support it. The answer, as usual, is that a GC is no silver bullet."


GeneralStroustrup: Smart pointers should be approached with carememberRoland Pibinger18 Jul '05 - 9:29 
"The main “Smart pointer” is a reference counted pointer, shared_ptr, intended for code where shared ownership is needed. When the last shared_ptr to an object is destroyed, the object pointed to is deleted. Smart pointers are popular, but should be approached with care. They are not the panacea that they are sometimes presented to be. In particular, they are far more expensive to use than ordinary pointers, destructors for objects “owned” by a set of shared_ptrs will run at unpredictable times, and if a lot of objects are deleted at once because the last shared_ptr to them is deleted you can incur “garbage collection delays” exactly as if you were running a general collector. The costs primarily relate to free store allocation of use count objects and especially to locking during access to the use counts in threaded systems. Do not simply replace all your ordinary pointers with smart_ptrs if you are concerned with performance or predictability. These concerns kept smart_ptrs “ancestor”, counted_ptr, out of the 1998 standard. If it is garbage collection you want, you might be better off simply using one of the available garbage collectors (http://www.research.att.com/~bs/C++.html)."

Stroustrup: C++ in 2005[^]
GeneralEnjoyed your article...memberMatt Gullett19 Jun '05 - 16:13 
First of all, I think your concept of an RAII factory is useful for certain situations, but is really nothing more than a very simplistic pooling mechanism with creation symantics. At least to me, it seems like the concept complicates the vast majority of situations I can think of. Straight-up RAII, by which I mean, MyClass allocates and de-allocates it's own resourcesand is constructuted within a stack-frame is usually suffecient for most situations.
 
Your method is only really useful when a particular function (stack frame) is going to allocate multiple (many) instances of a class and then pass that down through function class/etc. The problem here is that the initial function should be responsible for allocating MyClass instances unless naming those instances as variables is unnecessary (it just needs an array/list/stack/etc. of them as nameless objects). For this case, a typical collection (std:list, etc) will probably satisfy the need and will also provide RAII for the objects it contains (MyClass) which provide RAII for themselves.
 
For those situations where objects must be completely handled as pointers, auto_ptr is often enough, but if a programmer wants more, he/she can easily write a wrapper class to completely hide the underlying object construction. From my perspective, what your concept lacks to be more useful is a reference counting mechanism; which makes it something entirely different from what you are trying to accomplish.
 
Ultimately, C++ is meant to be a highly flexible language that allows programmers to create useful/powerful/creative solutions. It's power lies in the fact that I can choose to use GC, RAII, RAII Factories, pools, smart pointers, auto_ptr, wrapper classes, or just plain new/delete when I need it and how I see fit. None of these are panaceas and none fit all or even most situations. They are tools in an ever increasing toolbox that allow programmers to choose when/where to deal with complexity.
 
C++'s real problem is that it is a victim of it's own success. It is too powerful and too flexible. It is easy to do things a bad way, especially if you do not know what the right way is. Software development is partly shifting from an art to a practice. C++ is a wonderful pallete for an artist, but .NET/Java are better for practicioner programmers. Which is exactly why C++ is going to continue to be an important language for some time to come.
 
Sorry for the rant. I did enjoy your article and I think it is a good tool for situations where appropriate.
GeneralRe: Enjoyed your article...memberRoland Pibinger20 Jun '05 - 11:43 
Matt Gullett wrote:
Your method is only really useful when a particular function (stack frame) is going to allocate multiple (many) instances of a class and then pass that down through function class/etc. The problem here is that the initial function should be responsible for allocating MyClass instances unless naming those instances as variables is unnecessary (it just needs an array/list/stack/etc. of them as nameless objects). For this case, a typical collection (std:list, etc) will probably satisfy the need and will also provide RAII for the objects it contains (MyClass) which provide RAII for themselves.
 
std::list is designed only for value type objects. For (Non-copyable) 'entity objects' (called 'reference objects' in C#) RAII Factory is a mechanism that consistently and reliably takes care of resource management. And it makes you consider the scope of a resource.
 
Matt Gullett wrote:
C++'s real problem is that it is a victim of it's own success. It is too powerful and too flexible. It is easy to do things a bad way, especially if you do not know what the right way is. Software development is partly shifting from an art to a practice. C++ is a wonderful pallete for an artist, but .NET/Java are better for practicioner programmers. Which is exactly why C++ is going to continue to be an important language for some time to come.
 
I agree with your point of view. Unfortunately there seems to be no attempt to simplify the use of C++. Quite the contrary (see e.g. C++/CLI, Boost, ...)!
 


NewsMore links to RAII articlesmemberRoland Pibinger18 Jun '05 - 23:20 
1. Jonathan Dodds: "RAII in C++"[^]
 
2. Stephen Dewhurst: "Gotcha #67: Failure to Employ Resource Acquisition Is Initialization"[^]
 
Please note that in latter article class DBLock should disallow copying. Just make the copy constructor and operator= private and leave them unimplemented:
class DBLock {
public:
  DBLock() { lockDB(); }
  ~DBLock() { unlockDB(); }
private:<font color="red">
  DBLock (const DBLock&);
  DBLock& operator= (const DBLock&); </font>
};
 
3. The RAII Model[^]

GeneralRAII factory vs. 'smart pointer'memberRoland Pibinger25 May '05 - 9:12 
emilio_grv[^] has just published an article[^] about 'reference counting smart pointers and handles of various flavours'. You can directly compare the RAII factory to the smart pointer approach with respect to capability and usability.

GeneralYou could combine this with memory poolsmemberDon Clugston8 May '05 - 14:01 
One of the bonuses you get from this approach is more flexibility in exactly _how_ you do your memory management. For example, you're perfectly set up to use memory pools (eg boost::pool) to eliminate most of the memory management overhead. I think this is a significant benefit which is worth mentioning in the article.
 
Something that has never been clear to me, though, is how you can use RAII when you have a container with a highly variable (sometimes decreasing) number of elements. Sure, you know the scope of the container, but you can't always wait around until the container is destroyed before releasing all the objects. Moreover, the objects themselves may have internal RAII objects inside them which need to have their destructors called.
Any thoughts on this?

GeneralRe: You could combine this with memory poolsmemberRoland Pibinger9 May '05 - 0:59 
Don Clugston wrote:
One of the bonuses you get from this approach is more flexibility in exactly _how_ you do your memory management. For example, you're perfectly set up to use memory pools (eg boost::pool) to eliminate most of the memory management overhead. I think this is a significant benefit which is worth mentioning in the article.
 
Good point! Actually one of the boost::pool templates is similar to the generic RAIIFActory (GFactory) presented above. The scope bound approach also bears some resemblance with obstacks in C on Unix.
 
Something that has never been clear to me, though, is how you can use RAII when you have a container with a highly variable (sometimes decreasing) number of elements. Sure, you know the scope of the container, but you can't always wait around until the container is destroyed before releasing all the objects. Moreover, the objects themselves may have internal RAII objects inside them which need to have their destructors called. Any thoughts on this?
 
The RAIIFactory defines the maximum lifetime of created objects. I mention in the article that objects may be destroyed earlier (see 'Disposing Objects'). Albeit the user must ensure that the pointer to the disposed object will not be used any more. The factory implementation should probably be changed from vector to hash table when objects are disposed frequently. Also, for heavy create/dispose scenarios memory pools (as you mention above) are ideal, even 'local' pools where each factory object manages the raw memory of its created objects. In gerneral, RAIIFactories can also handle shorter actual lifetimes of objects.
 
There are settings where a RAIIFActory is not appropriate. One can be described as Publisher-Subscriber-Pattern (a.k.a. Observer). Subscribers get a reference to a resource from the publisher (the 'factory') but never give it back. They just discontinue to use it sometime without giving notice to the publisher. In this cases one should look for other solutions.

GeneralDid Stroustroup mention RAII factories?...memberworndown27 Apr '05 - 3:21 
RAII is an excellent and extremely useful programming idiom and I'm using it ALL the time. However, I don't see any need for such a RAII factory, at all.
 
worndown
GeneralRe: Did Stroustroup mention RAII factories?...memberRoland Pibinger27 Apr '05 - 7:23 
worndown wrote:
Re: Did Stroustroup mention RAII factories?...
 
No, Stroustrup did not mention RAII factories. I'll update the article to prevent any misunderstanding.
 
RAII is an excellent and extremely useful programming idiom and I'm using it ALL the time. However, I don't see any need for such a RAII factory, at all.
 
Stroustrup said: "For example, a container is a systematic way of dealing with objects. .... The name of the game here is to get allocation out of the way so you don't see it. If you don't directly allocate something, you don't directly deallocate it, because whoever owns it deals with it. The notion of ownership is central."
 
RAII factory is a container that creates and owns objects so that the user needs not directly allocate and deallocate anything. That's the gist.
GeneralRe: Did Stroustroup mention RAII factories?...memberworndown27 Apr '05 - 10:47 
You article begins with the right stuff:
 
void myFun()
{
XyzLib::Mutex mutex;
mutex.lock()
// do things in series ...
}
// mutex.unlock() is automatically called in the destructor of mutex
 
This is perfect example of RAII and you should not go beyond this point. If you want to allocate resources inside Mutex dynamically, do it, nothing prevents you from that and you don't have to invent RAII factory, which only adds unnecessary inderection, complexity and confusion, when objects are allocated and destroyed at different scopes as in you example:
 
void myFun (int n)
{
MyClassFactory factory;

for (int i = 0; i < n; ++i)
{
MyClass* p = factory.create (i);
// ...
}
}
// all objects created by factory are deleted here!
 
RAII stands for 'Resource Acquisition Is Initialization'. I think that the code above contadicts this idiom.
 
Look into source/sink approach.
 
worndown
GeneralRe: Did Stroustroup mention RAII factories?...memberWREY6 May '05 - 11:31 
Yes, all objects created by 'factory' will be destroyed upon exiting 'myFun', but you're going to have a bunch of dangling pointers if care weren't taken to nullify them prior to exiting the function, because 'MyClass::p' will be pointing to object(s) that no longer exist.
 
OTOH, RAII seeks to remove that concern altogether, because what you don't allocate, you don't have to deallocate.
 
Smile | :)
 
William
 
Fortes in fide et opere!
GeneralRe: Did Stroustroup mention RAII factories?...members_t_r_e_a_m_e_r26 Feb '09 - 22:46 
Actually Stroustroup invented RAII.
 
From wikipedia:
 
Resource Acquisition Is Initialization, often referred to by the acronym RAII, is a popular design pattern in several object oriented programming languages like C++, D and Ada. The technique, invented by Bjarne Stroustrup[1], ensures that when resources are acquired they are properly released by tying them to the lifespan of suitable objects: resources are acquired during the initialization of objects, when there is no chance of using them before the resource is available, and released with the destruction of the same objects, which is guaranteed to take place even in case of errors.
GeneralSmart ptr vs RAIImemberrm82224 Apr '05 - 1:46 
I voted this article 2 becase i think it obfuscated developers.
 
What the difference between RAII factory and smartptr?
RAII factory caontains many pointers smart ptr contains one(common cases)
RAII factory have fixed method of creation & destruction of all contained objects, smartptr incapsulates only destruction (which can be template policy)
 
RAII factory have fixed objects lifetime, smartptr can be destroyed anytime and lifetime can be increased.
 
I think RAII factory like a container of smart-pointer with constrains. Resolving any of this constrains will be step back to smart-pointers.
 
RAII factory have much unmotivated restrictions for object manipulation.
 
example - sometimes i create chain of 2-3 smart-pointers
lowest level is creates\destroys real object
top level prevents MT-access.
i don't think this possible for RAII-factory
GeneralRe: Smart ptr vs RAIImemberRoland Pibinger25 Apr '05 - 9:58 
rm822 wrote:
I voted this article 2 becase i think it obfuscated developers.
 
Unsure | :~
 
What the difference between RAII factory and smartptr?
RAII factory caontains many pointers smart ptr contains one(common cases)
RAII factory have fixed method of creation & destruction of all contained objects, smartptr incapsulates only destruction (which can be template policy)

 
That's an important difference. If you want that "allocation and deallocation disappear from the surface level of your code" then smart pointers are not an appropriate tool.
 
RAII factory have fixed objects lifetime, smartptr can be destroyed anytime and lifetime can be increased.
 
Again, a crucial discrepancy. It's the difference between deterministic and non-deterministic resource management.
 
I think RAII factory like a container of smart-pointer with constrains. Resolving any of this constrains will be step back to smart-pointers.
 
Confused | :confused:
 
RAII factory have much unmotivated restrictions for object manipulation.
 
The only restriction is that the RAII factory and the created objects use 'scope based' resource management. IMO, that's a feature, not a liability.
 
example - sometimes i create chain of 2-3 smart-pointers
lowest level is creates\destroys real object
top level prevents MT-access.
i don't think this possible for RAII-factory

 
I don't see why not. Actually, real pointers created by a RAII factory are much more flexible than 'smart pointers'. You can just use them everywhere a pointer is required (sounds strange, but real pointers can be uses as pointers Smile | :) ).


GeneralSmart Pointersmemberpeterchen18 Apr '05 - 12:45 
Very good article (in a way, you have closed a missing point on CP). However, I just have to disagree on Smart Pointers, and partially GC.
 
In a way, Smart Pointers provide deterministic destruction* where classic RAII fails due to C++ scoping rules: RAII is such a wonderful "fire and forget" mechanim, because you can bind the lifetime of an object X to either a C++ scope, or to one other object.
This mechanism fails, however, if you need binding across multiple objects or scopes. Smart Pointers cover probably 80% of these scenarios naturally.
This also explains why they have to have pointer semantics: You need to access one object X from different scopes, for which you normally need pointers. So they recycle a known concept (dereferencing), to provide the same feature (access to a shared object from multiple locations)
 

Smart Pointers in C++ have a kind of neglected history, I see two reasons for that:
 
First, stl included auto_ptr only, the most hideous, complex, and least applicable of resource managing smart pointers.
 
Second, Pointers are an almost atomic concept (in the sense that native pointers are very small, and most operations on them take a single clock cycle). Smart pointers can model this only partially, therefore they have to make various tradeoffs, so there is no single "perfect" implementation possible.
 


*)I fully agree that this is the core benefit of "C++ - RAII", even though I think Stroustrup did intend it in a different way.
 

Pandoras Gift #44: Hope. The one that keeps you on suffering.
aber.. "Wie gesagt, der Scheiss is' Therapie"
boost your code || Fold With Us! || sighist | doxygen

GeneralRe: Smart PointersmemberRoland Pibinger18 Apr '05 - 14:20 
peterchen wrote:
In a way, Smart Pointers provide deterministic destruction* where classic RAII fails due to C++ scoping rules: RAII is such a wonderful "fire and forget" mechanim, because you can bind the lifetime of an object X to either a C++ scope, or to one other object.
 
If you return a resource from a function by smart pointer the release of the resource is not deterministic any more. The function has ended but the resource release is pending. Yes, the resource release is smoehow assured by the smart pointer, but non-deterministic.
 
This mechanism fails, however, if you need binding across multiple objects or scopes. Smart Pointers cover probably 80% of these scenarios naturally.
This also explains why they have to have pointer semantics: You need to access one object X from different scopes, for which you normally need pointers. So they recycle a known concept (dereferencing), to provide the same feature (access to a shared object from multiple locations)

 
If you use an object in many scopes you create dependencies to that object in these scopes anyway. You can create the object on the stack in the 'highest' scope and pass it to 'lower' functions without the need for a smart pointer.
 

Smart Pointers in C++ have a kind of neglected history, I see two reasons for that:
First, stl included auto_ptr only, the most hideous, complex, and least applicable of resource managing smart pointers.

 
IMO, auto_ptr is the best of the obnoxious resource managing smart pointers because it does not allocate a mostly superfluous counter object.
 
BTW, following are some cornerstones of the 'smart pointer waves' in the last 15 years (from my point of view):
- Daniel R. Edelson published "Smart Pointers: They're Smart, but They're Not Pointers", http://www-sor.inria.fr/publi/SPC++_usenixC++92.html[^]
- Scott Meyers analyzed smart pointers in his book and in several articles, http://www.aristeia.com/publications_frames.html[^]
- auto_ptr was introduced into the C++ Standard and acclaimed, http://www.gotw.ca/publications/using_auto_ptr_effectively.htm[^]
- smart pointers were boosted to new dimensions by boost::smart_ptr without solving the old problems, http://www.boost.org/libs/smart_ptr/smart_ptr.htm[^]
 


GeneralRe: Smart Pointersmemberpeterchen18 Apr '05 - 20:37 

Roland Pibinger wrote:
If you return a resource from a function by smart pointer the release of the resource is not deterministic any more. The function has ended but the resource release is pending. Yes, the resource release is smoehow assured by the smart pointer, but non-deterministic.
 
First, what means "deterministic" to you?
To me, the important point is: the moment ofdestrucion depends only on the use of the very object itself, not on other factors.
 
Second, how do you return a managed resource from a function, if it does not yield a copy constructor?
 
Roland Pibinger wrote:
You can create the object on the stack in the 'highest' scope and pass it to 'lower' functions without the need for a smart pointer.
 
Umm... wouldn't this mean pushing the data to the outermost scope, i.e. making it global? This is at least impractical for scarce resurces, and hinders isolation of concerns.
 
Smart pointers are not panacea. But neither is scope-based RAII. Nor GC. I expect a good C++ developer to use RAII automatically, use smart pointers where they make sense, and be hesitant of GC in a C-based environment.
 

 
What are your problems with reference counting smart pointers?

 

Pandoras Gift #44: Hope. The one that keeps you on suffering.
aber.. "Wie gesagt, der Scheiss is' Therapie"
boost your code || Fold With Us! || sighist | doxygen

GeneralRe: Smart PointersmemberRoland Pibinger18 Apr '05 - 21:30 
peterchen wrote:
First, what means "deterministic" to you?
To me, the important point is: the moment of destrucion depends only on the use of the very object itself, not on other factors.

 
'Deterministic' refers to the lifetime of a resurce in a unit of code, typically a function. Example:
auto_ptr<MyClass> foo();
In this case the lifetime of the returned MyClass object is not determined by foo(). By looking at foo() you don't know when the returned object is destroyed. But in
void foo2();
all resources are deterministically released at the end of foo2 (disregarding global variables and programmer errors). This concept is akin to the commit/rollback semantics known from databases.
 
Second, how do you return a managed resource from a function, if it does not yield a copy constructor?
 
I avoid it. I see functions as 'services' that do something for me and report success or error afterwards but don't bother me with resources.
 
Roland Pibinger wrote:
You can create the object on the stack in the 'highest' scope and pass it to 'lower' functions without the need for a smart pointer.

 
Umm... wouldn't this mean pushing the data to the outermost scope, i.e. making it global? This is at least impractical for scarce resurces, and hinders isolation of concerns.
 
... the outermost scope in which they are actually used.
 
What are your problems with reference counting smart pointers?
 
None, because I don't use them. Smile | :) (in general, the same as for auto_ptr plus the unnecessary dynamically allocated counter object in each r.c.s.p.)
 

 

GeneralRe: Smart Pointersmemberemilio_grv3 May '05 - 21:05 
Roland Pibinger wrote:
  • What are your problems with reference counting smart pointers?
None, because I don't use them. (in general, the same as for auto_ptr plus the unnecessary dynamically allocated counter object in each r.c.s.p.)

 
Well, I think there's too much religion and very few science in this kind of answers:
 
I don't pretend to offend anyone, but is a matter of fact that –even if all catholic Popes still disagree about the use of condoms and of sex outside marriage- the most of self-saying "catholic people" use them and have sex before marriage.
 
The metaphor is to say only one concept: whatever "right" can be a thing you would like to be, that "thing" will always go its own way, with a "best compromise" logic, when applied on a wide population. You can "influence it", not change it in its nature.
But programming should be a science, not a religion.
 
Smart pointers everywhere is wrong as RAII everywhere is wrong.
The good programmer choose the –case by case- the pattern that best fits please note the program needs (not his own needs). Object lifetime is not always something you can decide aprioristically. And "determinism" is not the concept you mention (well … not in the official mathematical sense). Destruction by reference counting is deterministic as destruction in scope. (Smart pointers are destroyed by scope, after all…) GC isn't because the destruction action is not taken as direct consequence of a program action.
 
To say "I don't have problem because I don't use it" describing another pattern as a replacement for that, doesn't make a good impression. There's nothing scientifically meaningful in that.
 
I use reference counting widely without any particular problem. As I use RAII. I'm diffident of GC in C++ program, not because I'm diffident on GC, but because I don't see (unlike for RAII and smart pointer) any binding with any C++ native scoping mechanism.

 

2 bugs found.
> recompile ...
65534 bugs found.
D'Oh! | :doh:

GeneralRe: Smart PointersmemberRoland Pibinger4 May '05 - 11:03 
emilio_grv wrote:
Roland Pibinger wrote:
 
What are your problems with reference counting smart pointers?
 
None, because I don't use them. (in general, the same as for auto_ptr plus the unnecessary dynamically allocated counter object in each r.c.s.p.)
 
Well, I think there's too much religion and very few science in this kind of answers ..
Smart pointers everywhere is wrong as RAII everywhere is wrong.

As I said before, RAII can hardly be overused (at least I don't see how).
 
The good programmer choose the –case by case- the pattern that best fits please note the program needs (not his own needs). Object lifetime is not always something you can decide aprioristically.
 
You start case by case and gradually develop towards styles, idioms, patterns. A library, e.g., must conform to a certain 'philosophy' to be usable. The little sister of KISS is KIU (Keep It Uniform Smile | :) ).
 
And "determinism" is not the concept you mention (well … not in the official mathematical sense). Destruction by reference counting is deterministic as destruction in scope. (Smart pointers are destroyed by scope, after all…)
 
If you return a smart pointer to a resource that may be returned again then you can hardly call this 'deterministic'. The usage of 'deterministic' here is close to the ACID properties of database transactions (see also link to Herb Sutters article above).
 
To say "I don't have problem because I don't use it" describing another pattern as a replacement for that, doesn't make a good impression. There's nothing scientifically meaningful in that.
 
I don't use resource-owning smart pointers because they mix two unrelated concepts: (de-)referencing and resource-handling. Besides that, 'smart pointers' are not pointers, i.e. they cannot provide the full syntax of pointers.
 
I use reference counting widely without any particular problem.
 
IMO, reference-counting works well when it's an implementation detail, invisible to the user (when r.c. is encapsulted).
 

 


 

 

GeneralRe: Smart Pointersmemberemilio_grv4 May '05 - 23:52 
You're still climbing glasses, my friend!
Many acronym and citation... and no samples by you!
Let me do a counter example: consider an application that lets a user editing a document by placing, moving and removing a variety of objects (in human-language common sense). Think to MS PowerPoint, for example.
 
The fact that the user has a "delete" command in a menu, doesn’t make you able to "destroy by scope". The scope in which the objects live is the document. If you destroy the document you destroy the objects. Right: RAII factory works.
But what about a "delete" command? You can remove the objects –oops! The object pointers- from the objects collection that represent the document [1], but the objects will be still there until the document will be closed.
Now, think a user inserting 10 thousand object, "deleting" them, inserting other 10 thousand ... three four five ... one hundred times. When do you'll ever eliminate the "deleted" 100thousand objects?
Are you going to fill-up the entire memory with things the users will no more access anyway?
 
Now, consider a reference counting pointer with casting capability inside a collection, and all object sharing a same common base. The user choose "delete", and you remove the "pointer" from the collection representing the document. Full stop. The object will continue to exist only if it is also referred from inside another collection (for example an "undo" list) and will be deleted when no more needed[2].
 
You can think this is ugly, you can find as many people you want that agree. Burt you cannot say this doesn't work, or that it "has problems"! That fact that many people agree on something doesn't make that something "true". Fore a science things are "true" when replicate coherently, independently on "opinions". "Good" and "Bad" .. it is another story.
 
If this "have problems" tell me "what are the problems". I don't see any. May be I'm wrong, but you did nothing to explain me. You simple say "I feel this's wrong".
 
But saying "I don't use so I don't have problem ..." is like saying by definitiomn "true = good / false = bad". That's not a definition. It's a prejudice.
 

[1] Please note that such a collection must have a polymorphic content: hence forget about the STL "value semantic": pointers and virtual function, in these cases, are a must. Inheritace of template parameter (that is: policy design of the objects) doesn't help a lot.
 
[2] This is still "determinism" since "when no more needed" is a well defined and predictable event. The fact that someone use this name in more strict definition, doesn't change the nature of things. "Deterministic" is a legitimate Englis dictionary term. And the fact that someone use acronyms to give a "hidden name" to this misinterpretation of words, doesn't change the physics, nor the language. It is not "when someone will be interested in looking if no more needed", like in GC. That's non-determinism.
Again: you can think this is "hugly", but you cannot say "it's wrong".
 

 

2 bugs found.
> recompile ...
65534 bugs found.
D'Oh! | :doh:

GeneralRe: Smart PointersmemberRoland Pibinger5 May '05 - 2:00 
emilio_grv wrote:
You're still climbing glasses, my friend!
Many acronym and citation... and no samples by you!
Let me do a counter example: consider an application that lets a user editing a document by placing, moving and removing a variety of objects ... Are you going to fill-up the entire memory with things the users will no more access anyway?

 
Maybe my emamples are somewhat misleading (I consider updating them). The article states the "Minimal Scoping Rule" and has a chapter 'Disposing Objects'.
 
Now, consider a reference counting pointer with casting capability inside a collection, and all object sharing a same common base. The user choose "delete", and you remove the "pointer" from the collection representing the document. Full stop. The object will continue to exist only if it is also referred from inside another collection (for example an "undo" list) and will be deleted when no more needed[2].
 
Your document example is very interesting. I'd say that the document is a RAII-factory that owns all created objects. Two 'views' work on that document: one consists of the visible objects and the other of the objects that are currently invisible but still part of the document. Objects without further usability are disposed.
The article already is too long. I've considerd to include a longer, more realistic, example, e.g. an XML document where elements are viewed as (a hierarchy of) RAIIFactories that create and own child-elements and attributes.
 
You can think this is ugly, you can find as many people you want that agree. Burt you cannot say this doesn't work, or that it "has problems"! That fact that many people agree on something doesn't make that something "true". Fore a science things are "true" when replicate coherently, independently on "opinions". "Good" and "Bad" .. it is another story.
 
Well, this is not an article about the (dis-)advantages of 'smart pointers'. I almost regret to have mentioned them in the article since they seem to distract people from the actual contents.
 
[1] Please note that such a collection must have a polymorphic content: hence forget about the STL "value semantic": pointers and virtual function, in these cases, are a must. Inheritace of template parameter (that is: policy design of the objects) doesn't help a lot.
 
You may want to have a look at my other CP article: ptr_vector[^] which could be used/combined/merged with a RAIIFactory.
 
[2] This is still "determinism" since "when no more needed" is a well defined and predictable event. The fact that someone use this name in more strict definition, doesn't change the nature of things. "Deterministic" is a legitimate Englis dictionary term. And the fact that someone use acronyms to give a "hidden name" to this misinterpretation of words, doesn't change the physics, nor the language. It is not "when someone will be interested in looking if no more needed", like in GC. That's non-determinism. Again: you can think this is "hugly", but you cannot say "it's wrong".
 
I think it is unfruitful to stick to one word: If you prefer call it: 'resource management bound to one function scope or one block scope'. That's what it is.
 
Thank you for your elaborate comment!
 


GeneralRe: Smart Pointersmemberemilio_grv5 May '05 - 2:56 
Nice anwer, but there's still one point I don't get:
 
I'd say that the document is a RAII-factory that owns all created objects. Two 'views' work on that document: one consists of the visible objects and the other of the objects that are currently invisible but still part of the document. Objects without further usability are disposed
 
How do you know they have no "further usability"? I don't see anything keeping track of this. The RAII factory says "You exist until I exist". The concept of "usable" is not there. You must count who's using. But this is –back again- reference counting. That doesn't mean by itself "smart pointers", but you still have to count! (see back "rm82" message ...)
Or you can "migrate" a user "deleted" object to another factory... that will destroy sooner; violating the pattern.
 
You may want to have a look at my other CP article: ptr_vector which could be used/combined/merged with a RAIIFactory.
 
Sure: it works fine. But the point is not the "pointer", but what it points: must be a (same) interface that each different object "reinterpret". You call "paint". But "paint" paints differently depending on object type. But this is something that does not relate to refocounting or RAII, but with polymorphism. That's another story.
 

2 bugs found.
> recompile ...
65534 bugs found.
D'Oh! | :doh:

GeneralRe: Smart PointersmemberRoland Pibinger5 May '05 - 3:44 
emilio_grv wrote:
Nice anwer, but there's still one point I don't get:
 
I'd say that the document is a RAII-factory that owns all created objects. Two 'views' work on that document: one consists of the visible objects and the other of the objects that are currently invisible but still part of the document. Objects without further usability are disposed
 
How do you know they have no "further usability"? I don't see anything keeping track of this. The RAII factory says "You exist until I exist". The concept of "usable" is not there.

 
You are right, it's not there, because it is application logic. The RAIIFactory only encapsulates resource handling via RAII so that "allocation and deallocation disappear from the surface level of your code."
 
You must count who's using. But this is –back again- reference counting. That doesn't mean by itself "smart pointers", but you still have to count! (see back "rm82" message ...)
 
You probably mean a situation, where many 'subscribers' reference the same 'published' resource. In this case you probably find an easier solution with (internal or external) refernce-counting (but that makes it harder to track down the lifetime of a resource). RAII, scope bound resource management to be more precise, is not a panacea but it works very well in many cases. Not all though. Smile | :)
 

 

 

GeneralRe: Smart PointerssussMattyT9 May '05 - 14:12 
I have trouble with your smart pointer definitions too.
 
To me at least, they are totally deterministic. When the last smart pointer assigned to a pointer is deleted, the pointed-to object will be deleted. Just because it may not happen in a function or trivial scope doesn't mean it's non-deterministic.
 
I also think your advice to avoid returning resources from functions (and presumably acting as sinks too) is misguided. It's a common, well-known and useful C++ idiom. (See Sutter's books or even his treatise online)
 
The rest of your article was reasonable and you should be applauded for discouraging the use of new/delete. Although I have to say I would avoid using your RAII factories in favour of smart pointers and standard containers. IMO they are more robust, readable and, well, standard.
GeneralRe: Smart PointersmemberRoland Pibinger10 May '05 - 9:55 
MattyT wrote:
I have trouble with your smart pointer definitions too.
To me at least, they are totally deterministic. When the last smart pointer assigned to a pointer is deleted, the pointed-to object will be deleted. Just because it may not happen in a function or trivial scope doesn't mean it's non-deterministic.

 
You may call it 'resource management bound to one function scope or one block scope' instead of 'deterministic resource management'. Ref-counted smart pointers are not bound to one scope.
 
I also think your advice to avoid returning resources from functions (and presumably acting as sinks too) is misguided. It's a common, well-known and useful C++ idiom. (See Sutter's books or even his treatise online)
 
Hmm,
- "Make a habit of using smart pointers like auto_ptr in your daily work" (Herb Sutter, October 1999)
- "Avoid using auto_ptr" (Herb Sutter, August 2004) Wink | ;)
 
Ok, to be fair, the full quotation of the last sentence is: "Avoid using auto_ptr, instead use shared_ptr which is widely available and being added to the standard library." And to avoid misunderstanding: I recommend of course his books (I have the two 'Exceptional C++') and all his articles, Gotw, ...
 
It seems to me that many 'smart pointers' (like auto_ptr) are so smart that they outsmart their users. Smile | :)
 



QuestionIs RAII a cure for all (panacea)?memberMartin Holzherr17 Apr '05 - 23:05 
Hi,
good article.
But is RAII really so good,
that GC is not necessary anymore?
Furthermore, is it true, that
"Exception handling gets complicated in GC languages ".
In Java and .Net Exception handling is the standard way
of error handling and both have GC.
I beleive that you are a bit overoptimistic about RAII.
Best Regards
Martin
AnswerRe: Is RAII a cure for all (panacea)?memberNemanja Trifunovic18 Apr '05 - 3:06 
GC is not a replacement for RAII. It can handle only memory, while leaving all other resources (db connections, files, GDI handles, sockets...) to programmer to handle manually. One solution is to have them both, like in C++/CLI, but I strongly prefer to have GC only as an option on a per-object basis. As for .NET and Java, I have seen so many programmers (heck, even book writers) write exception non-safe code, that I would argue these environments are seriously flawed in this regard. See this article by Reymond Chen[^], for instance.
 
Anyway, I voted this article 5, although I don't quite agree with author's criticisms for smart pointers. I use Boost smart pointers (especially scoped_ptr) all the time, and practically never call delete manually any more. As for RAII factory, I used this idiom once (although I had no idea it was called RAII factory Smile | :) ) when I didn't have a clear owner of my objects and wanted to avoid the overhead of reference counting. However, I exactly new the point in my program where it was safe to destruct the objects - it is not always the case.
 
Finally, I recommend this article[^] as a nice introduction to RAII.
 


My programming blahblahblah blog. If you ever find anything useful here, please let me know to remove it.
GeneralRe: Is RAII a cure for all (panacea)?memberRoland Pibinger18 Apr '05 - 9:27 
Nemanja Trifunovic wrote:
GC is not a replacement for RAII. It can handle only memory, while leaving all other resources (db connections, files, GDI handles, sockets...) to programmer to handle manually.[...] As for .NET and Java, I have seen so many programmers (heck, even book writers) write exception non-safe code, that I would argue these environments are seriously flawed in this regard. See this article by Reymond Chen[^], for instance.
 
That's the point. Many programmers in GC languages seem to be unaware of the problematic of releasing resources and the right resource-handling idioms (e.g. the 'Null' object).
 
Anyway, I voted this article 5, although I don't quite agree with author's criticisms for smart pointers. I use Boost smart pointers (especially scoped_ptr) all the time, and practically never call delete manually any more.
 
Yes, real C++ programmers don't call delete manually. Seriously!
I also use scoped resource handlers for just one object (but not 'smart pointers') in some cases when it's not possible to create the object on the stack.
 
Finally, I recommend this article[^] as a nice introduction to RAII.
 
Good article. I've known it. Unfortunately it does not define RAII, it assumes that you already know RAII.

 

 

GeneralRe: Is RAII a cure for all (panacea)?memberRompa23 Apr '05 - 4:01 
Roland Pibinger wrote:
Yes, real C++ programmers don't call delete manually. Seriously!
 
Yep, real programmers don't need to dynamically allocate everything on the planet like 99% of supposed "programmers" out there. Please ignore this - just a game programmer's view of the trends of programming in general... bloat all the way! Wink | ;)

GeneralRe: Is RAII a cure for all (panacea)?memberRoland Pibinger24 Apr '05 - 1:50 
Rompa wrote:
Yep, real programmers don't need to dynamically allocate everything on the planet like 99% of supposed "programmers" out there.
 
Well, students nowadays learn Java as 'base language' in their CS courses ... Unsure | :~
AnswerRe: Is RAII a cure for all (panacea)?memberRoland Pibinger18 Apr '05 - 9:08 
Martin Holzherr wrote:
Hi,good article.
 
Thank you!
 
But is RAII really so good,that GC is not necessary anymore?
 
IMO, yes for C++, maybe no for other languages.
 
Furthermore, is it true, that
"Exception handling gets complicated in GC languages ".
In Java and .Net Exception handling is the standard way
of error handling and both have GC.

 
In Java (the language I have worked with) the user has to write code over and over again that in C++ can be written in the destructor once and forever.
 
I believe that you are a bit overoptimistic about RAII.
 
Maybe. The RAII idiom is underestimated in C++. Partly because of the bad name, partly because RAII is not so "smart" as some "policy-based" designs.
RAII is not a panacea but a cure for most resource management problems. And it can hardly be overused. Smile | :)
 

 

GeneralRe: Is RAII a cure for all (panacea)?memberbrajiv21 Apr '05 - 20:23 
An even gentler introduction is at: http://www.relisoft.com/resource/index.htm[^]. I remember that this info has been on their site for many, many years.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130516.1 | Last Updated 4 May 2005
Article Copyright 2005 by Roland Pibinger
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid