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
Derivedobjects and theirnum2members 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 aDerivedat all, so this is the safe way.If the
Basetype were polymorphic, you could usedynamic_castto 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
Baserather than using lots ofif(dynamic_cast)checks.