I have the following classes:
class base{};
class derived1:public base{};
class derived2:public base{};
I also have an implemented container pool
to which I have no editing access. In each of the 3 .h
files, I define the following pool respectively:
typedef pool<base> basesPool;
typedef pool<base> derived1Pool;
typedef pool<base> derived2Pool;
At some point in the flow, I am getting an object out of the pool, and assigning it to a general pointer of type base
with respect to a flag
:
derived1Pool d1pool;
derived1Pool d2pool;
base* element;
if(flag){
d1pool = new derived1Pool();
element = d1pool ->alloc();
}
else{
d2pool = new derived2Pool();
element = d2pool ->alloc();
}
Later on, I am trying to clean using the following code:
if(flag){
d1pool->free(element);
}
else{
d2pool->free(element);
}
I am getting an error due to a covariance problem:
error: no matching function for call to 'pool<derived1Pool>::free(base*&)'
An easy solution would be to define two pointers. I am trying to avoid this. Is there an elegant option to convert from the base pointer to the derived pointer? I have seen this post and tried all variations of dynamic_casting
I could think of to no avail.
CodePudding user response:
The issue you have is that you cannot cast (dynamically or otherwise) a non-lvalue base class pointer to a non-const reference to a pointer to a derived class, which is what is required as the argument to your free
calls.
As you have stated that you cannot change the pool
class definition (or its free
member function's argument type), you could get round this by creating local (to the if
and else
blocks) pointers of the correct type, initialize them by dynamically casting the element
pointer, and use those as the arguments to the free
calls:
if(flag){
derived1* d1p = dynamic_cast<derived1*>(element);
d1pool->free(d1p);
element = d1p; // See note below
}
else{
derived2* d2p = dynamic_cast<derived2*>(element);
d2pool->free(d2p);
element = d2p; // See note below
}
Note: The reason why I have included the assignments back to element
after each call is that it is likely that the free
function modifies its given pointer (probably setting it to nullptr
, but I can't be sure). So, we need to manually propagate that change, because we have passed local/temporary pointers and the free
function's changes will only apply to those.