【问题标题】:Is this a good way to store, iterate and delete pointers in an std::vector?这是在 std::vector 中存储、迭代和删除指针的好方法吗?
【发布时间】:2012-09-10 11:01:24
【问题描述】:
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <vector>
using namespace std;

struct delete_ptr
{
    template<typename T>
    void operator()(T*& t)
    {
        delete t;
        t = 0;
    }
};

struct is_null_ptr
{
    template<typename T>
    bool operator()(T*& t)
    {
        return t == 0;
    }
};

struct A
{
    static void removeDead(A*& a)
    {
        if(a and a->dead)
            delete_ptr()(a);
    }

    static void killSome(A* a)
    {
        if(a and a->isDead() == false and rand()%100 == 0)
        {
            static int counter = 0;
            cout << "Kill___" << ++counter << endl;
            a->kill();
        }
    }

    static void reviveSome(A* a)
    {

        if(a and a->isDead() and rand()%3 == 0)
        {
            static int counter = 0;
            cout << "Revive___" << ++counter << endl;
            a->revive();
        }
    }

    A():dead(false)
    {

    }

    virtual ~A()
    {
        static int counter = 0;
        cout << "Dtor___" << ++counter << endl;
    }

    bool isDead(){return dead;}
    void kill(){dead = true;}
    void revive(){dead = false;}

    bool dead;
};

int main()
{
    srand(time(0));
    vector<A*> as;
    for(int i = 0; i < 200; ++i)
    {
        A* a = new A;
        as.push_back(a);
    }


    for_each(as.begin(),as.end(),A::killSome);
    for_each(as.begin(),as.end(),A::reviveSome);

    for_each(as.begin(),as.end(),A::removeDead);
    as.erase( std::remove_if(as.begin(),as.end(),is_null_ptr()),as.end());
    cout << as.size() << endl;

    for_each(as.begin(),as.end(),delete_ptr());
    as.clear();

    return 0;
}

它分配它们,并打印正确的输出,但我不确定这是我正在做的正确事情。我只是想在向量中使用指针并在发生某种情况时删除它们,而不使用 boost 或 c++11。 那你怎么看呢?

【问题讨论】:

  • 使用std::vector&lt;std::unique_ptr&lt;A&gt;&gt;
  • 我正在尝试在没有 c++11 功能的情况下实现这一目标。
  • 不,这通常不是一个好方法。为什么首先将指针存储在向量中,而不是具体对象?
  • @user1659900:即使没有 C++11,您仍然可以使用 Boost.Move 编写(大部分)unique_ptr
  • "不使用 boost 或 c++11"

标签: c++ pointers functor stdvector erase-remove-idiom


【解决方案1】:

由于当前 STL 中存在的唯一智能指针 (auto_ptr) 不能在容器中使用,我会说在给定条件下你的方式是一个很好的方式。

不过,您可以考虑实现自己的 unique_ptr 或 shared_ptr。

PS:使用指针代替容器中的实际对象有很多原因,一个是多态性。另一个是实际对象已经存储在其他地方(想想已存储对象的索引结构)。

【讨论】:

  • 如果对象存储在其他地方并且向量应该只引用它们,那么您永远不需要delete指针。
猜你喜欢
  • 2022-12-19
  • 1970-01-01
  • 1970-01-01
  • 2010-10-27
  • 2013-06-11
  • 1970-01-01
  • 1970-01-01
  • 2017-11-13
  • 1970-01-01
相关资源
最近更新 更多