I want to construct a std::vector
containing objects derived from the Base
class. I know that I can't directly push the whole object into the vector
(cause of object slicing) so I use smart pointers. However, it still doesn't work. What am I doing wrong?
My code:
struct Base{
int num1;
explicit Base(int num1){
this->num1 = num1;
}
};
struct Derived : Base{
int num2;
explicit Derived(int num1, int num2) : Base(num1){
this->num2 = num2;
}
};
int main()
{
std::vector<std::unique_ptr<Base>> someList;
someList.push_back(std::make_unique<Derived>(100, 1));
someList.push_back(std::make_unique<Derived>(100, 2));
std::cout << someList[0]->num2 << std::endl; // <---- Can't access num2 !
}
The
Derived
objects and theirnum2
members are there, but the type system doesn't know that (and in similar code, it might not be certain).The type of
someList[0]
isstd::unique_ptr<Base>
, so the->
operator allows naming members ofBase
. In general, aunique_ptr<Base>
might not point at aDerived
at all, so this is the safe way.If the
Base
type were polymorphic, you could usedynamic_cast
to check if the object really is aDerived
. To get this working, let's add a virtual destructor toBase
:Then we can do:
For real code, it's considered better design to make use of virtual functions in
Base
rather than using lots ofif(dynamic_cast)
checks.