|
BDE 4.14.0 Production release
|
Typedefs | |
| typedef bslma::NewDeleteAllocator | bslma_NewDeleteAllocator |
| This alias is defined for backward compatibility. | |
Provide singleton new/delete adaptor to bslma::Allocator protocol.
This component provides a concrete allocation mechanism, bslma::NewDeleteAllocator, that implements the bslma::Allocator protocol to provide direct access to the system-supplied (native) global operator new and operator delete functions via that pure abstract interface.
The essential purpose of this component is to facilitate the default use of global new and delete in all components that accept a user-supplied allocator derived from bslma::Allocator (see bslma_default ). Hence, the global operator new and operator delete functions are wrapped within concrete methods of a derived bslma::NewDeleteAllocator class. A static (factory) method of bslma::NewDeleteAllocator can be used to obtain a unique (singleton) bslma::NewDeleteAllocator object for the given process, and whose lifetime is guaranteed to exceed any possibility of its use. Note that the standard also requires the global operator new to return maximally-aligned memory, which is a stricter post condition than the natural-alignment requirement imposed by the base-class contract, or than is provided by many other concrete implementations.
This class is fully thread-safe, which means that all non-creator object methods can be safely accessed concurrently (from multiple treads). The singleton bslma::NewDeleteAllocator can also be safely created/accessed concurrently (from multiple threads) via either the static singleton or allocator (factory) methods. Moreover, the underlying (native) implementation of new and delete are required by the C++ standard to ensure that concurrent access to either the virtual allocate and/or deallocate are also safe (i.e., will not not result in heap corruption). Note that this allocator therefore has stronger thread-safety guarantees than is required by the base-class contract or than is provided by many other derived concrete allocators.
The most common and proper use of bslma::NewDeleteAllocator is both indirect and by default (see bslma_default ). For example, consider (along with its destructor) the default and copy constructors for, say, a simple container, such as my_ShortArray, each of which take as its final optional argument the address of a bslma::Allocator protocol:
In order to satisfy this contract, we will need a globally accessible utility (see bslma_default ), which by default returns the singleton bslma::NewDeleteAllocator, but which could be configured to return some other allocator, say a test allocator (see bslma_testallocator ):
Notice that the only part of the bslma::NewDeleteAllocator class we used directly was its static allocator method, which – in addition to safely constructing the singleton bslma::NewDeleteAllocator object on first access – also automatically replaces a 0 address value with that of singleton bslma::NewDeleteAllocator object. From now on, we will never again need to invoke the bslma_newdeleteallocator component's interface directly, but instead use it through my_Default (see bslma::Default for what is actually used in practice).
Turning back to our my_shortarray example, let's now implement the two constructors using the bslma_newdeleteallocator component indirectly via the my_default component:
When the default constructor is called, the default capacity and length are recorded in data members via the initialization list. The static function allocator (provided in my_Default) is used to assign the value of the basicAllocator address passed in, or if that is 0, the address of the currently installed default allocator, which by default is the singleton object of type bslma::NewDeleteAllocator, defined in this component. Note that since INITIAL_CAPACITY is 0, a default constructed object that is created using a bslma::NewDeleteAllocator will not invoke the operator new function, which on some platforms may needlessly acquire a lock, causing unnecessary overhead (the same potential overhead is avoided for operator delete whenever a 0 d_array_p value is deallocated in the destructor) and d_allocator_p refers to a bslma::NewDeleteAllocator. Note also that, for the copy constructor, the currently installed default allocator, and not the other array's allocator is used whenever basicAllocator is 0 or not explicitly supplied.
Finally note that this entire component is not intended for direct use by typical clients: See bslma_default for more information or proper usage.