从指针向量中删除对象

时间:2014-03-21 01:24:39

标签: c++ pointers vector

我已经看过很多非常相似的问题,但我仍然无法解决这个问题。

考虑简单的类:

class Obj
{
public:
    Obj(int moose);
    ~Obj();

private:
    int* val;
};


Obj::Obj(int num)
{
    val = new int;

    *val = num;
}


Obj::~Obj()
{
    printf("Cleanup");
    delete val;
}

现在我想要一个指向objs的指针向量。该来源详细说明了问题:

int main(int argc, const char * argv[])
{
    std::vector<Obj*> objs;

    Obj* o = new Obj(10);

    objs.push_back(o);

    objs.erase(objs.begin() + 0);

    // should have been deleted by now - I want the destructor to have been called
    // I have tried delete objs[0], casting to it and then deleting it.

    return 0;
}

Obj中的析构函数仅在程序完成时调用。我希望在从矢量中删除对象时调用它。

澄清:我试图使用向量中的引用删除对象。我无法做到这一点。我知道向量不会释放内存。它只是从向量中删除引用。任何人都可以提供删除对象的代码,并使用向量中的引用调用析构函数。

编辑:

即使添加:

auto it = objs.begin() + 0;
delete *it;
objs.erase(it);

如建议的那样,Obj的析构函数不会触发。

3 个答案:

答案 0 :(得分:3)

正如许多评论所指出的,vector.erase仅从向量中删除元素。它不会尝试删除任何相关的内存 要明确删除关联的内存,您需要:

int main(int argc, const char * argv[])
{
    ...

    auto it = objs.begin() + i;
    delete *it;
    objs.erase(it);

}

实际上,在您的情况下:

int main(int argc, const char * argv[])
{
    std::vector<Obj*> objs;

    Obj* o = new Obj(10);
    objs.push_back(o);    

    auto it = objs.begin();
    delete *it;
    objs.erase(it);

}

您的代码还存在许多其他不一致之处,并为您尝试执行的操作提供了更好的解决方案,例如:

  • 使用vector<Obj>

    int main(int argc, const char * argv[])
    {
        std::vector<Obj> objs;
        objs.emplace_back(10);    
    
        auto it = objs.begin();
        objs.erase(it);
    }
    
  • 如果您需要动态分配对象,但出于某种原因不希望向量处理该对象,您可以使用shared_ptrunique_ptr来处理释放为你:

    int main(int argc, const char * argv[])
    {
        std::vector<std::unique_ptr<Obj>> objs;
    
        objs.emplace_back(new Obj(10));    
    
        auto it = objs.begin();
        objs.erase(it);
    }
    

答案 1 :(得分:1)

从向量中删除元素(指针)时,只需将其从容器向量中删除即可。但是指针所指向的位置仍然是堆上的有效内存。如果要释放该内存,则应使用delete,并明确释放内存。如果您不想自己管理内存,请使用智能指针。

答案 2 :(得分:0)

从向量中删除项目时,将调用项目的析构函数。但在这种情况下,项目是一个指针,指针不会拥有析构函数。指针指向的对象 not 将调用其析构函数,直到在指针上使用delete为止。如果指针被删除而您没有其他副本,则您将永远无法删除它并且您将发生内存泄漏。

尽可能优先将对象本身放在向量而不是指针中。这将减轻你对内存管理的苦差事。