#include <iostream>
#include <string>
#include <map>
#include <vector>
class base {};
class derived1 : public base
{
public:
unsigned short n;
derived1()
{
n = 2;
}
};
class derived2 : public base {};
void main()
{
// way 1
{
std::vector<derived1> a1;
std::vector<derived2> a2;
std::map<std::string, base*> b;
a1.push_back(derived1());
b["abc"] = &a1.at(0);
std::cout<<(dynamic_cast<derived1*>(b.find("abc")->second))->n<<std::endl;
}
// way 2
{
std::map<std::string, base*> b;
b["abc"] = new derived1();
std::cout<<dynamic_cast<derived1*>(b.find("abc")->second)->n<<std::endl;
delete dynamic_cast<derived1*>(b.find("abc")->second);
}
}
The error is "'dynamic_cast' : 'base' is not a polymorphic type". What should be done to fix this? Is everything properly cleaned up in both way1 and way2?
To make
Base
a polymorphic type, you need to give it at least one virtual function. The easiest in this case would be the destructor:Regarding your question about cleanup:
Technically, there is some undefined behaviour in both ways, because the objects that the map refers to are destroyed before the pointers are removed from the map. This has the result that the map, when it is destructed, contains invalid pointers and that causes undefined behaviour.
For practical purposes, this does not cause any problems with any known compiler.
Otherwise, you are properly cleaning up everything.
But in way2, you can make a simplification. When
Base
has a virtual destructor, you can just dowithout the dynamic cast.