BDE 4.14.0 Production release
|
Macros | |
#define | bslma_AutoRawDeleter bslma::AutoRawDeleter |
This alias is defined for backward compatibility. | |
Provide a range proctor to manage a sequence objects.
This component provides a range proctor class template, bslma::AutoRawDeleter
, to manage a sequence of (otherwise-unmanaged) objects of parameterized TYPE
supplied at construction. If not explicitly released, the sequence of managed objects are deleted automatically when the range proctor goes out of scope by iterating over each object, first calling the (managed) object's destructor, and then freeing its memory footprint by invoking the deallocate
method of an allocator (or pool) of parameterized ALLOCATOR
type also supplied at construction. Note that after a range proctor releases its sequence of managed objects, the same proctor can be reused to conditionally manage another sequence of objects (allocated from the same allocator or pool that was supplied at construction) by invoking the reset
method.
Note that this component should be used only if we are sure that the supplied pointer is not of a type that is a secondary base class – i.e., the (managed) object's address is (numerically) the same as when it was originally dispensed by ALLOCATOR
.
The parameterized ALLOCATOR
type of the bslma::AutoRawDeleter
class template must provide a (possibly virtual
) method:
to deallocate memory at the specified address
(originally supplied by the ALLOCATOR
object).
The bslma::AutoRawDeleter
proctor object can be used to preserve exception neutrality during manipulation of out-of-place arrays of user-defined-type objects. The following illustrates the insertion operation for an "out-of-place" string array. Assume that a string array initially contains the addresses of the following string objects as its elements:
To insert two string objects with values "F" and "G" at index position 2, the array is first reallocated if it is not big enough, and then the existing elements at index positions 2, 3, and 4 are shifted:
Next, two new string objects must be created and initialized with string values "F" and "G", respectively. If, during creation, an allocation fails and an exception is thrown, the array will be left in an invalid state because the addresses contained at index positions 2 and 3 may be duplicates of those at index positions 4 and 5, or, if a resize occurred, invalid altogether. We can restore exception neutrality by setting the array's length to 2 before attempting to create the string objects, but there is still a problem: the string objects "C", "D", and "E" (at index positions 3, 4, and 5) are "orphaned" and will never be deleted – a memory leak. To prevent this potential memory leak, we can additionally create a bslma::AutoRawDeleter
object to manage (temporarily) the elements at index positions 4, 5, and 6 prior to creating the new objects:
If an exception occurs, the array (now of length 2) is in a perfectly valid state, while the second proctor is responsible for deleting the orphaned elements at index positions 4, 5, and 6. If no exception is thrown, the elements at index positions 2 and 3 are set to new strings "F" and "G", the length of the first proctor is set to 7 and the second proctor's release
method is called, releasing its control over the temporarily managed elements.
The following example illustrates the use of bslma::AutoRawDeleter
in conjunction with bslma::DeallocatorProctor
to manage temporarily a templatized, "out-of-place" array of parameterized TYPE
objects during the array's insertion operation.
First we define a myArray
class that stores an array of parameterized TYPE
objects:
Note that a bslma::DeallocatorProctor
is used to manage a block of memory allocated before invoking the constructor of TYPE
. If the constructor of TYPE
throws, the (managed) memory is automatically deallocated by bslma::DeallocatorProctor
s destructor:
Now, if any allocation, either allocating memory for new elements or the constructor of the new element throws, the elements that had been moved to the end of the array will be deleted automatically by the bslma::AutoRawDeleter
.
Note that portions of the implementation are elided as it adds unnecessary complications to the usage example. The shown portion is sufficient to illustrate the use of bslma_autorawdeleter .
The above method copies the source elements (visually) from left to right. Another (functionally equivalent) implementation copies the source elements from right to left, and makes use of the operator--()
of the bslma::AutoRawDeleter
interface:
Since we have decided to copy the source elements from right to left, we set the origin of the bslma::AutoRawDeleter
to the end of the array, and decrement the (signed) length on each copy to extend the proctor range by 1.
Note that though the two implementations are functionally equivalent, they are logically different. First of all, the second implementation will be slightly slower because it is accessing memory backwards when compared to the normal forward sequential access. Secondly, in case of an exception, the first implementation will retain all the elements copied prior to the exception, whereas the second implementation will remove them.
#define bslma_AutoRawDeleter bslma::AutoRawDeleter |