Using RWTOnlyPointer
RWTOnlyPointer is useful for reclaiming dynamically allocated memory, especially when the block of code in which the memory is allocated may exit prematurely due to an exception being thrown. By wrapping a raw pointer in an
RWTOnlyPointer object, you can depend on the smart pointer’s destructor to delete the raw pointer when the exception causes the stack to unwind. This is an example of the “resource acquisition is initialization” technique described by Stroustrup in
The C++ Programming Language (see the bibliography).
This class implements strict ownership semantics, so that only one
RWTOnlyPointer can own a particular body at a given time. If the assignment operator or the copy constructor is called, then the right-hand instance is invalidated (its body pointer is set to NULL), and the left-hand instance assumes responsibility for deleting the body. Thus
RWTOnlyPointer is best for local protection of dynamic memory; it is not suitable for sharing pointers among several objects. Sharing pointers can be accomplished with
RWTCountingPointer and
RWTCountedPointer, as described in
Using RWTCountedPointer and
Using RWTCountingPointer, respectively.
To see why
RWTOnlyPointer is useful, consider
Example 61.
Example 61 – Allocating memory with a potential memory leak
Class A {
public:
A() {p_ = new int; initialize(); }
~A() {delete p_;}
private:
int * p_;
void initialize(void);
};
If
initialize() throws an exception, the allocated memory is not released. You can fix the memory leak problem by using
RWTOnlyPointer, as shown in
Example 62.
Example 62 – Using a smart pointer to reclaim memory
#include <rw/pointer/RWTOnlyPointer.h>
Class A {
public:
A() {p_ = new int; initialize(); } // 1
~A() {}
private:
RWTOnlyPointer<int> p_;
void initialize(void);
};
Keep in mind that the copy construction and assignment semantics of
RWTOnlyPointer modify the right-hand instance so that it doesn’t point to the body anymore. So, for example:
Example 63 – Mistakenly using an invalid pointer
RWTOnlyPointer<int> p1(new int(10)); //1
RWTOnlyPointer<int> p2 = p1; //2
cout << *p1; //3