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

Detailed Description

Outline

Purpose

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

Classes

See also
bslma_sharedptr, bslma_sharedptrrep, bslma_sharedptrinplacerep

Description

This component provides 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.

Thread Safety

bslma::SharedPtrOutofplaceRep 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. bslma::SharedPtrOutofplaceRep 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:

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

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

class MyFactory {
// . . .
// MANIPULATORS
MyType *createObject(bslma::Allocator *basicAllocator = 0);
// Create a 'MyType' object. Optionally specify a
// 'basicAllocator' used to supply memory. If 'basicAllocator' is
// 0, the currently installed default allocator is used.
void deleteObject(MyType *object);
// Delete the specified '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 bslma::SharedPtrOutofplaceRep 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 bslma::SharedPtrOutofplaceRep:

class MySharedDatetimePtr {
// This class provide a reference counted smart pointer to support
// shared ownership of a 'bdlt::Datetime' object.
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
MySharedDatetimePtr(bdlt::Datetime *ptr,
bslma::Allocator *basicAllocator = 0);
// 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(const MySharedDatetimePtr& original);
// Create a shared datetime that refers to the same object managed
// by the specified 'original'
~MySharedDatetimePtr();
// 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.
// MANIPULATORS
bdlt::Datetime& operator*() const;
// 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 *ptr() const;
// Return the address of the modifiable 'bdlt::Datetime' to which
// this object refers.
};
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;
d_rep_p =
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;
}
static SharedPtrOutofplaceRep< TYPE, DELETER > * makeOutofplaceRep(TYPE *ptr, const DELETER &deleter, Allocator *basicAllocator=0)
Definition bslma_sharedptroutofplacerep.h:656