#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);
}
}
错误是“'dynamic_cast':'base'不是多态类型”。应该怎么做才能解决这个问题?一切都是在way1和way2中正确清理的吗?
答案 0 :(得分:7)
要使Base
成为多态类型,您需要至少为其提供一个虚函数。在这种情况下最简单的是析构函数:
class Base {
public:
virtual ~Base() { }
};
关于清理的问题:
从技术上讲,两种方式都存在一些未定义的行为,因为在从地图中删除指针之前,地图引用的对象将被销毁。这导致地图在被破坏时包含无效指针并导致未定义的行为
出于实际目的,这不会导致任何已知编译器出现任何问题。
否则,你正在清理所有东西
但是在方式2中,您可以进行简化。当Base
具有虚拟析构函数时,您可以执行
delete b.find("abc")->second;
没有动态演员。