|
-
April 12th, 2010, 12:24 AM
#1
Object storage & lifetime C++ Design
Hi there! I chose to post here as I'm coding in pure C++ and that has a direct impact on my implementation. I apologize if I chose the incorrect location.
I've been writing C++ professionally for about 6 years now. I've been reading books, taken classes, looked at and used other libraries in projects. In my spare time, I try out ideas and architectural concepts. This is for the purpose of learning, and this is one of those projects.
At present, I have only myself to discuss these things with as I am the only coder at work, and none of my friends are programmers. When it comes to discussing C++, coding in general, architecture, design, etc, it's left me kind of lonely! I hope that's where you can help me out as I haven't had much luck elsewhere. I don't know if it's because I'm not asking the right questions, in the wrong place, or I smell funny.
So, without further ado, here is my current adventure. After using the STL allocator, specializing it a few times, and studying other allocators (i.e in Boost), I decided I didn't like how object construction/destruction and storage were tied together. I believe they can be separated. A short while later, I came up with the following design:
Code:
// Responsible for creating/destroying an object at a certain memory location.
// Creating an object consists of calling the object's Constructor
// Destroying an object consists of calling the object's Destructor
template<typename T>
class ConstructionPolicy
{
public:
ConstructionPolicy();
ConstructionPolicy(const ConstructionPolicy<T>&);
ConstructionPolicy<T>& operator=(const ConstructionPolicy<T>&);
public:
void Construct(T* pLocation); // Construct an object at pLocation
void Construct(T* pLocation, const T& ref);
void Destruct(T* pLocation); // Destruct an object at pLocation
};
// Two construction policies are considered equal if an object can be constructed
// with one policy and destructed with the other. Comparing/assigning construction
// policies handling different types aren't supported (and I think shouldn't be?)
template<typename T>
bool operator==(const ConstructionPolicy<T>& l, const ConstructionPolicy<T>& r);
template<typename T>
bool operator!=(const ConstructionPolicy<T>& l, const ConstructionPolicy<T>& r);
// Responsible for determining which ConstructionPolicy is appropriate for destroying
// the specified object, and using it. This is useful so we don't have to pass the
// object's Construction policy all over the place.
template<typename T>
void Destruct(T* pObject);
Code:
// Responsible for allocating storage for an object and releasing that storage
template<typename T>
class AllocationPolicy
{
public:
AllocationPolicy();
AllocationPolicy(const AllocationPolicy<T>&);
template<typename U>
AllocationPolicy(const AllocationPolicy<U>&);
AllocationPolicy<T>& operator=(const AllocationPolicy<T>&);
template<typename U>
AllocationPolicy<T>& operator=(const AllocationPolicy<U>&);
public:
T* AddressOf(const T& object); // Returns the address, in memory, to the object
T* Allocate(size_t nCount); // Allocates enough storage to hold nCount objects
void Release(T* pLocation, size_t nCount); // Release allocated memory
};
// Two allocation policies are considered equal if an memory allocated with one can
// be released with the other.
template<typename T, typename U>
bool operator==(const AllocationPolicy<T>& l, const AllocationPolicy<U>& r);
template<typename T, typename U>
bool operator!=(const AllocationPolicy<T>& l, const AllocationPolicy<U>& r);
// Responsible for determining which AllocationPolicy is appropriate for destroying
// the specified object and using it. This is useful so we don't have to pass the
// object's Allocation policy all over the place.
template<typename T>
void Release(T* pObject);
Code:
// Combines a AllocationPolicy and ConstructionPolicy for a type. This basically
// provides a lot of the same functionality a STL Allocator does, or at least I
// believe it does.
template<typename T,
typename A=AllocationPolicy<T>,
typename C=ConstructionPolicy<T> >
class Factory
{
public:
typedef A alloc_t;
typedef C construct_t;
public:
Factory();
Factory(const Factory<T,A,C>&);
Factory(const alloc_t&, const construct_t&);
// I think some conversion constructors could be useful here, to handle
// constructing with compatable allocators, similar to the template constructor
// in the STL Allocator. However, things get fuzzy here and I'm not sure what
// what other constructors may be appropriate.
public:
T* Create(size_t nCount); // Allocate & Construct nCount objects
T* Create(size_t nCount, const T& ref);
void Destroy(T* pLocation); // Destruct & Release objects at pLocation
public:
alloc_t& AllocationPolicy();
construct_t& ConstructionPolicy();
private:
alloc_t m_ap;
construct_t m_cp;
};
// I'm also stuck on the operators here, for the same reasons as I am on the
// additional constructors above. At present, all I can come up with is that two
// factories are equal if the contained allocation and construction policies are
// equal. However, I feel this is too broad.
// TODO: Appropriate operators.
To keep things focused, I left out rebind, traits and value type typedefs that handle the pointers and references of T.
The above is (mostly) simple enough to code, and pretty easy to extend to handle custom construction/allocation schemes for different types based on my experimentation so far. My question is: What flaws are in this design and can it be made better?
I'm also struggling with the best way to handle the free floating Destroy and Release functions. A map of pointers to the best Destruct/Release member function seems overkill/slow, and allocating enough storage to hold the member function with the object results in hard to maintain/convoluted code (as such, this also applies to the storage of nCount for array destruction). Are there any better approaches?
At my disposal is Visual C++ 2008, Boost 1.42, and std::tr1.
Thanks and I highly appreciate any input you're willing to offer.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|