|
BDE 4.39.x Production Release
|
Provide a smart-pointer-like manager for a Datum object.
Provide a smart-pointer-like manager for a Datum object.
Datum objectThis component implements a type, bdld::ManagedDatum, that provides two important services for Datum objects:
ManagedDatum provides value-semantic-like operations for Datum.ManagedDatum is a resource manager, similar to a smart pointer, for Datum.These services allow clients to use a ManagedDatum object in most contexts where an object of a value-semantic type can be used (passed by value, stored in containers, and so on), even though ManagedDatum is not strictly value-semantic. These services are explored in subsequent sections.
The Datum type maintained by a ManagedDatum provides a space-efficient discriminated union (i.e., a variant) holding the value of a scalar type (e.g., int, double, string) or an aggregate of other Datum objects. See bdld_datum for more details.
ManagedDatum, while not strictly a value-semantic type, provides the full set of value-semantic-like operations for Datum (see Value-Semantic Operations [VS.1] ):
ostream PrintingIn other words, the syntax of ManagedDatum is regular, but not all of its copy behavior is value-semantic. Specifically, for User Defined Types (i.e., those that bdld::Datum::clone does not deep-copy) ManagedDatum performs a shallow copy (copying the reference rather than the value), which is inconsistent with value-semantics. For all other types ManagedDatum copy operations (copy construction, copy assignment, and non-member swap when the allocators differ) will deep-copy the value using Datum::clone, which creates a completely independent copy, with independent lifetime, by duplicating all data, even referenced data (except for UDTs).
Additionally, move operations are supported (i.e. move constructor and move assignment). Depending on the match of the source and target allocators, ManagedDatum performs either shallow (the allocators are the same) or deep (the allocators are different) copying.
Note that a default constructed ManagedDatum, or a ManagedDatum on which release has been called, will have the null Datum value.
A Datum object's relationship to memory can be seen as analogous to a raw pointer, requiring calls to static functions Datum::create* and Datum::destroy to initialize and release resources (see the bdld_datum component documentation). A ManagedDatum, by extension, provides a resource manager for a Datum that is analogous to a smart pointer.
The adopt method of a ManagedDatum is used to take ownership of a supplied Datum object, after which point the ManagedDatum object's destructor will free the resources of the managed Datum (unless release is subsequently called). Similar to a smart pointer, a ManagedDatum provides dereference operators to access the Datum object under management.
This section illustrates intended use of this component.
This example demonstrates the basic construction and manipulation of a ManagedDatum object.
First, we create a ManagedDatum object that manages a Datum holding a double and verify that the managed object has the expected type and value:
Next, we create a ManagedDatum object that holds a string and again verify that it has the expected type and value:
Then, we assign this ManagedDatum object to another object and verify both objects have the same value:
Next, copy-construct this ManagedDatum object and verify that the copy has the same value as the original:
Then, we create a ManagedDatum object that holds an opaque pointer to a bdlt::Date object and verify that the managed Date has the expected value:
Next, we assign a boolean value to this ManagedDatum object and verify that it has the new type and value:
Then, we create a ManagedDatum object having an array and verify that it has the same array value. Note that in practice we would use bdld_datumarraybuilder , but do not do so here for dependency reasons:
Next, we create a ManagedDatum object having a map and verify that it has the same map value. Note that in practice we would use bdld_datummapbuilder , but do not do so here to for dependency reasons.
Then, we create a Datum object and assign its ownership to a ManagedDatum object and verify that the ownership was transferred:
Next, we release the Datum object managed by obj and verify that it was released:
Finally, we destroy the released Datum object: