Reputation: 85
I am currently working on a project that requires me to have a vector storing pointers to objects of the same class but with different template values. I want to use shared_ptrs for reasons that I won't get too deep into (mainly that if I want to share a Column between two ColumnLists).
I need to be able to return a casted pointer from a function (as seen below).
So here is a very simplified version:
template <typename ColType>
class Column {
std::vector<ColType>;
};
template <typename ...TypesOfColumns>
class ColumnList {
private:
std::vector< std::shared_ptr<void> > columnsVector;
/* Needs to have a vector storing pointers to multiple Columns
all with different template values */
public:
template <typename ReturnType> std::shared_ptr<ReturnType> GetPointer(int index)
{
return std::static_pointer_cast<ReturnType>(columnsVector.at(index));
};
};
I am wondering if I am getting to some type of undefined behavior here? Will it work as I am hoping: will returning the casted type just add one to the Strong Reference Counter of the void pointer? Can one be deleted before the other one is? Am I risking a memory leak where one gets deleted and the other does not (I doubt this one to be the case)?
As always, thanks for all of the help!!!
Upvotes: 2
Views: 164
Reputation: 114461
IMO much better would be having an abstract column as the base class for the template:
struct AbstractColumn {
virtual ~AbstractColumn() {}
...
};
template<typename Type>
struct Column : AbstractColumn {
std::vector<Type> data;
};
That would provide a place where to put generic methods (e.g. conversion to string, parsing from string etc.) and will also allow you to use pointers to the base class instead of pointers to void
.
Upvotes: 2
Reputation: 8374
static_pointer_cast follows the same rules that static_cast does. It is legal to downcast a pointer-to-base to a pointer-to-derived as long as derived
derives from base
. As long as you are sure that columnsVector.at(index)
contains a shared_ptr<ReturnType>
(that is, contains a shared_ptr<void>
that originated as a shared_ptr<ReturnType>
), what you are doing is legal. If you don't know for sure, you should use dynamic_pointer_cast.
Further, regarding memory, the output of static_pointer_cast shares the same underlying control block as the input, so it's safe that way too. Even if the input were to be deleted first, the output would remain a legal owner of the shared resource, and vice-versa.
Upvotes: 2