std :: map,polymorphism和delete

时间:2011-06-22 14:52:28

标签: c++ dictionary polymorphism rtti delete-operator

我在使用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 DTOR\n";
   }
};

class Derived: public Base
{
private:
    struct bar *_additional_structure;
public:
    Derived() { _additional_structure = new struct bar; }
   ~Derived()
   {
        delete _additional_structure;
        std::cout << "Derived DTOR\n";
   }
};


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 类;所以调用的析构函数是Base类之一,而不是Derived类。 Valgrind确认我每次都丢失16个字节。

另外,我不能使用Boost的 shared_ptr I saw some mentions of it here),我使用的嵌入式架构不支持C ++异常和RTTI (在我的例子中,导致一些未对齐的访问和其他不良内容)编辑:不相关)。

你知道我怎么能解决这个问题吗?

2 个答案:

答案 0 :(得分:13)

你的虚拟析构函数在哪里??? !!!

Read this 永远不会 忘记。真的,你刚刚破坏了10条C ++诫命之一...... :))

答案 1 :(得分:6)

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

否则,在通过指向其基类的指针引用子类的情况下,在运行时无法确定应该实际调用哪些析构函数。