std::映射、多态性和删除

std::map, polymorphism and delete

本文关键字:删除 多态性 映射 std      更新时间:2023-10-16

我在使用C++映射存储指向基类和某些派生类的指针时遇到问题。

让我用一个相当长但很简单的代码来解释:

#include <map>
#include <iostream>
struct foo{ int dummy[4]; };
struct bar{ int additionnal[4]; };
class Base
{
private:
    struct foo *_internal_structure;
public:
    Base() { _internal_structure = new struct foo; }
   ~Base()
   {
        delete _internal_structure;
        std::cout << "Base DTORn";
   }
};
class Derived: public Base
{
private:
    struct bar *_additional_structure;
public:
    Derived() { _additional_structure = new struct bar; }
   ~Derived()
   {
        delete _additional_structure;
        std::cout << "Derived DTORn";
   }
};

int main(int argc, char *argv[])
{
    std::map<int, Base*> my_map;
    Base *to_add = new Base();
    Derived *derived_to_add = new Derived();
    my_map[1] = to_add;
    my_map[2] = derived_to_add; // works, derived class, but object gets sliced
    /// clear hash map ///
    std::map<int, Base*>::const_iterator iter;
    for(iter = my_map.begin(); iter != my_map.end(); ++iter)
    {
        delete (*iter).second;
    }
    return 0;
}

运行时的结果:

Base DTOR
Base DTOR

因此,当我将Derived类指针插入到映射中时,底层对象被视为Base类别;因此,调用的析构函数是基类中的一个,而不是派生类。Valgrind证实我每次都丢失16个字节。

此外,我不能使用Boost的shared_ptr(我在这里看到了一些提到它的地方),而且我使用的嵌入式架构不支持C++异常和RTTI(在我的情况下,这会导致一些未对齐的访问和其他不好的东西)编辑:不相关)。

你知道我怎样才能纠正这种行为吗?

虚拟析构函数在哪里

阅读这篇文章,永远不要忘记。真的,你刚刚违反了C++的10条戒律中的一条…:)

任何基类中的析构函数都应该是虚拟的

否则,在通过指向基类的指针引用子类的情况下,在运行时不可能确定实际应该调用什么析构函数。