As the title,I have a odd requirement. Code examples:
class Base{
}
class Derived: Base{
}
//I want cast that.
shared_ptr<vector<Derived*>> -> shared_ptr<vector<Base*>>
Here is my way:
shared_ptr<vector<Derived*>> derived_vector_sp;
auto* base_vector_rawptr = (vector<Base*> *)derived_vector_sp.get();
shared_ptr<vector<Base*>> base_vector_sp = make_shared<<vector<Base*>>>(*base_vector_rawptr);
It works.But in this way I create anthor vector.And two shared_ptr manage two different vecotr.
So is there any way finish this case directly?such as:
//this way doesn't work.
shared_ptr<vector<Base*>> base_vector_sp = static_pointer_cast<vector<Base*>>(derived_vector_sp);
CodePudding user response:
You can't cast shared_ptr<vector<Derived*>>
to shared_ptr<vector<Base*>>
because vector<Derived*>
and vector<Base*>
are two distinct types that are not related to each other.
That Derived
and Base
are related to each other does not matter in that case. The type you create with std::vector<Derived*>
and std::vector<Base*>
are created from the class templated std::vector
, so it is only the inheritance given by the std::vector
class template that is relevant here.
But in this way I create another vector. And two
shared_ptr
manage two different vecotr.
You could think about creating a view
on your original vector<Derived*>
container.
CodePudding user response:
A cast is not possible, because even though Derived
inherits Base
, the classes vector<Derived*>
and vector<Base*>
are completely separate classes with no relationship at all.
If you want a vector<Base*>
from a vector<Derived*>
, it is possible but you need to convert the pointers yourself. And you get a separate vector of course.
std::vector<Derived*> source;
// Don't use this, use the version below
auto result = std::vector<Base*>(source.size());
for (std::size_t idx = 0; idx < source.size(); idx) {
result[idx] = source[idx];
}
return result;
Or in more idiomatic C , we would simply let the constructor do the job:
auto result = std::vector<Base*>(begin(source), end(source));
Random sidenote:
The cast:
(vector<Base*> *)derived_vector_sp.get(); // don't do this!
This is completely illegal. There is no
vector<Base*>
at that location, so attempting to use one is undefined behavior. It might look like it works, then you upgrade your compiler and it crashes.Using a
shared_ptr
in general is a code smell. It has a few good use cases, but most of the time you should be using the objects directly, orunique_ptr
.Especially when we talk about a
std::vector
which is already itself a set of pointers.