I have a data structure : pool of values. (not pool of pointers)
When I called create(), it will return Handle.
Here is a draft. Everything is good so far.
template<class T> class Pool{
std::vector<T> v; //store by value
Handle<T> create(){ .... }
}
template<class T> class Handle{
Pool<T>* pool_;
int pool_index_;
T* operator->() {
return pool_->v.at(pool_index_);
}
void destroy(){
pool_-> ... destroy() .... mark "pool_index_" as unused, etc ....
}
}
Now I want Handle<> to support polymorphism.
Many experts have kindly advised me to use weak_ptr, but I am left in blank, don't know how to do it.
The major part that I am stuck is :-
- Should create() return weak_ptr, not Handle?
.... or should Handle encapsulate weak_ptr?
- If it return weak_ptr for user's program, ...
how weak_ptr would know pool_index_? It doesn't have such field.
- If the user cast weak_ptr/Handle to a parent class pointer as this example, there are many issues as followed.
class B{}
class C : public B {
}
....
{
Pool<C> cs;
Handle<C> cPtr=cs.create();
Handle<A> aPtr=cPtr; // casting // expected to be valid, but don't know ... how?
aPtr->destroy() ; // aPtr will invoke Pool<A>::destroy which is wrong!
// Pool<C> is the correct one, not Pool<A>
aPtr.operator->() ; // face the same problem
}
I know, I am noob, yeah.
Edit:
I found a solution, so I think I should share here.
The solution (suggested by 1litre ) is to let every Pool<T> derived from Pool_interface.
Pool_interface have get/set, everything manipulate in term of void*
Instead of caching
Pool<T>* pool_;
I must caching :-
Pool_interface* pool_;
The get/set have to be encapsult again, e.g.
return static_cast<T*>(pool_.get(index));