BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslstl_sharedptrallocateoutofplacerep

Detailed Description

Outline

Purpose

Provide an out-of-place implementation of bslma::SharedPtrRep.

Classes

See also
bslma_sharedptrrep, bslma_sharedptroutofplacerep, bslstl_sharedptr

Description

This component provides a class template, bslstl::SharedPtrAllocateOutofplaceRep , which is a concrete implementation of bslma::SharedPtrRep for managing objects of the parameterized TYPE that are stored outside of the representation. When all references to the out-of-place object are released using releaseRef, the deleter of the parameterized DELETER type is invoked to delete the shared object. Memory is supplied and reclaimed by an allocator of the parameterized ALLOCATOR type.

Thread Safety

bslstl::SharedPtrAllocateOutofplaceRep is thread-safe provided that disposeObject and disposeRep are not called explicitly, meaning that all non-creator operations other than disposeObject and disposeRep on a given instance can be safely invoked simultaneously from multiple threads (disposeObject and disposeRep are meant to be invoked only by releaseRef and releaseWeakRef). Note that there is no thread safety guarantees for operations on the managed object.

Deleters

When the last shared reference to a shared object is released, the object is destroyed using the "deleter" provided when the associated shared pointer representation was created. bslstl::SharedPtrAllocateOutofplaceRep supports two kinds of "deleter" objects, which vary in how they are invoked. A "function-like" deleter is any language entity that can be invoked such that the expression deleterInstance(objectPtr) is a valid expression, and a "factory" deleter is any language entity that can be invoked such that the expression deleterInstance.deleteObject(objectPtr) is a valid expression, where deleterInstance is an instance of the "deleter" object, and objectPtr is a pointer to the shared object. In summary:

Deleter Expression used to destroy `objectPtr`
- - - - - - - - - - - - - - - - - - - - - - - - - - -
"function-like" deleterInstance(objectPtr);
"factory" deleterInstance.deleteObject(objectPtr);

The following are examples of function-like deleters that delete an object of MyType:

/// Delete the specified `object`.
void deleteObject(MyType *object);
/// Release the specified `object`.
void releaseObject(MyType *object);
/// This `struct` provides an `operator()` that can be used to delete a
/// `MyType` object.
struct FunctionLikeDeleterObject {
/// Destroy the specified `object`.
void operator()(MyType *object);
};

The following on the other hand is an example of a factory deleter:

class MyFactory {
// . . .
// MANIPULATORS
/// Create a `MyType` object. Optionally specify a `basicAllocator`
/// used to supply memory. If `basicAllocator` is 0, the currently
/// installed default allocator is used.
MyType *createObject(bslma::Allocator *basicAllocator = 0);
/// Delete the specified `object`.
void deleteObject(MyType *object);
};
Definition bslma_allocator.h:457

Note that deleteObject is provided by all bslma allocators and by any object that implements the bdlma::Deleter protocol. Thus, any of these objects can be used as a factory deleter. The purpose of this design is to allow bslma allocators and factories to be used seamlessly as deleters.

The selection of which expression is used by bslstl::SharedPtrAllocateOutofplaceRep to destroy a shared object is based on how the deleter is passed to the shared pointer object: Deleters that are passed by address are assumed to be factory deleters, while those that are passed by value are assumed to be function-like. Note that if the wrong interface is used for a deleter, i.e., if a function-like deleter is passed by pointer, or a factory deleter is passed by value, and the expression used to delete the object is invalid, a compiler diagnostic will be emitted indicating the error.

Usage

The following example demonstrates how to implement a shared bdlt::Datetime object using bslstl::SharedPtrAllocateOutofplaceRep:

/// This class provide a reference counted smart pointer to support
/// shared ownership of a `bdlt::Datetime` object.
class MySharedDatetimePtr {
private:
bdlt::Datetime *d_ptr_p; // pointer to the managed object
bslma::SharedPtrRep *d_rep_p; // pointer to the representation object
private:
// NOT IMPLEMENTED
MySharedDatetimePtr& operator=(const MySharedDatetimePtr&);
public:
// CREATORS
/// Create a `MySharedDatetimePtr` object to managed the specified
/// `ptr`. Optionally specify an `basicAllocator` to allocate and
/// deallocate the internal representation and to destroy `ptr` when
/// all references have been released. The behavior is undefined
/// unless `ptr` was allocated using memory supplied by
/// `basicAllocator`.
MySharedDatetimePtr(bdlt::Datetime *ptr,
bslma::Allocator *basicAllocator = 0);
/// Create a shared datetime that refers to the same object managed
/// by the specified `original`
MySharedDatetimePtr(const MySharedDatetimePtr& original);
/// Destroy this shared datetime and release the reference to the
/// `bdlt::Datetime` object to which it might be referring. If this
/// is the last shared reference, deleted the managed object.
~MySharedDatetimePtr();
// MANIPULATORS
/// Return a reference offering modifiable access to the shared
/// datetime.
bdlt::Datetime& operator*() const;
/// Return the address of the modifiable `bdlt::Datetime` to which
/// this object refers.
bdlt::Datetime *operator->() const;
/// Return the address of the modifiable `bdlt::Datetime` to which
/// this object refers.
bdlt::Datetime *ptr() const;
};
Definition bdlt_datetime.h:331
Definition bslma_sharedptrrep.h:338

Finally, we define the implementation.

MySharedDatetimePtr::MySharedDatetimePtr(bdlt::Datetime *ptr,
bslma::Allocator *basicAllocator)
{
d_ptr_p = ptr;
makeOutofplaceRep(ptr, basicAllocator, basicAllocator);
}
MySharedDatetimePtr::MySharedDatetimePtr(
const MySharedDatetimePtr& original)
: d_ptr_p(original.d_ptr_p)
, d_rep_p(original.d_rep_p)
{
if (d_ptr_p) {
d_rep_p->acquireRef();
} else {
d_rep_p = 0;
}
}
MySharedDatetimePtr::~MySharedDatetimePtr()
{
if (d_rep_p) {
d_rep_p->releaseRef();
}
}
bdlt::Datetime& MySharedDatetimePtr::operator*() const {
return *d_ptr_p;
}
bdlt::Datetime *MySharedDatetimePtr::operator->() const {
return d_ptr_p;
}
bdlt::Datetime *MySharedDatetimePtr::ptr() const {
return d_ptr_p;
}
Definition bslstl_sharedptrallocateoutofplacerep.h:262