将指针设置为null

时间:2011-07-18 17:14:16

标签: c++

我的c ++应用程序我创建了一些指向对象的指针并将它们添加到两个向量中。然后我遍历一个向量,直到找到满足所需条件的对象。如果它满意我想NULL那个指针。最重要的是我想在所有地方将其设为NULL。示例代码如下。

   #include <vector>

class Circle
{
public:
    Circle(int _iArea){iArea = _iArea;};
    ~Circle(){};
    void SetArea(int _iArea){ iArea = _iArea;};
    int GetArea(){return iArea;};

private:
    int iArea;
};

int _tmain(int argc, _TCHAR* argv[])
{
    Circle* pCircle1 = new Circle(10);
    Circle* pCircle2 = new Circle(20);
    Circle* pCircle3 = new Circle(30);
    Circle* pCircle4 = new Circle(40);


    std::vector<Circle*>vector_test1;
    vector_test1.push_back(pCircle1);
    vector_test1.push_back(pCircle2);
    vector_test1.push_back(pCircle3);
    vector_test1.push_back(pCircle4);

    std::vector<Circle*>vector_test2;
    vector_test2.push_back(pCircle1);
    vector_test2.push_back(pCircle2);
    vector_test2.push_back(pCircle3);
    vector_test2.push_back(pCircle4);

    std::vector<Circle*>::iterator itrVecTest1 = vector_test1.begin();
    std::vector<Circle*>::iterator itrVecTest1End = vector_test1.end();
    while(itrVecTest1 != itrVecTest1End)
    {
        int iType = (*itrVecTest1)->GetArea();
        if(iType ==10)
        {
            delete (*itrVecTest1);
            *itrVecTest1 = NULL;
        }
        ++itrVecTest1;
    }
    retrun 0;
}

这里pCircle1满足给定条件,我想从所有地方删除它。使用此代码,我可以将vector_test1中的指针设为null。但有没有办法在vector_test2中同时设置相同的指针而不迭代它?

4 个答案:

答案 0 :(得分:4)

是使用弱指针。

int _tmain(int argc, _TCHAR* argv[])
{
    // If you don't have the latest version then
    // std::auto_ptr (Pointer should never be held in a RAW pointer,
    // always use some form of smart pointer (unless you don't own the pointer then RAW is fine).
    //
    std::unique_ptr<Circle> pCircle1 = new Circle(10);
    std::unique_ptr<Circle> pCircle2 = new Circle(20);
    std::unique_ptr<Circle> pCircle3 = new Circle(30);
    std::unique_ptr<Circle> pCircle4 = new Circle(40);


    // If you don't have the latest version then
    // boost::shared_ptr
    std::vector<std::shared_prt<Circle> >     vector_test1;
    vector_test1.push_back(std::move(pCircle1));     // Transfer ownership to vector_test1
    vector_test1.push_back(std::move(pCircle2));
    vector_test1.push_back(std::move(pCircle3));
    vector_test1.push_back(std::move(pCircle4));

    // If you don't have the latest version then
    // boost::weak_ptr
    std::vector<std::weak_ptr<Circle> >       vector_test2;
    vector_test2.push_back(vector_test1[0]);         // register an interest in the object
    vector_test2.push_back(vector_test1[1]);         // But if test1 object is destroyed
    vector_test2.push_back(vector_test1[2]);         // Then weak pointer will return NULL
    vector_test2.push_back(vector_test1[3]);

    std::vector<Circle*>::iterator itrVecTest1 = vector_test1.begin();
    std::vector<Circle*>::iterator itrVecTest1End = vector_test1.end();
    while(itrVecTest1 != itrVecTest1End)
    {
        int iType = (*itrVecTest1)->GetArea();
        if(iType ==10)
        {
            itrVecTest1.reset(NULL); // Now the pointer in vector_test2 is also gone
        }
        ++itrVecTest1;
    }
    retrun 0;
}

答案 1 :(得分:0)

如果满足某些条件,为什么不将对象原始值设置为null?然后指针也将为空。否则可能是滥用指针。指针应该指向内存中的对象。一个不指向任何东西的指针似乎不是最好的方法。

只是我的两分钱。希望这会有所帮助...

答案 2 :(得分:0)

不,如果你使用常规指针。

您可以通过创建一个智能指针类来实现此目的,该类将在删除对象时使所有指针实例无效。这在C ++中并不难,但很难使其线程安全。

因此,通常智能指针不会以这种方式工作 - 相反,它们会检测何时不再存在指针实例,然后删除对象(有点像垃圾收集)。

您可能需要考虑重新设计代码,以便它可以使用标准的智能指针,例如std :: shared_ptr。

答案 3 :(得分:0)

我不完全确定weak_ptr在这种情况下可以安全使用。但是,您可以改为使用指针指针。

int _tmain(int argc, _TCHAR* argv[])
{
    using std::shared_ptr; // or use boost::shared_ptr
    typedef shared_ptr<Circle> CirclePtr;
    typedef shared_ptr<CirclePtr> CirclePtrPtr;
    typedef std::vector<CirclePtrPtr> CircleList;

    CirclePtr pCircle1(new Circle(10));
    CirclePtr pCircle2(new Circle(20));
    CirclePtr pCircle3(new Circle(30));
    CirclePtr pCircle4(new Circle(40));

    CirclePtrPtr ppCircle1(new CirclePtr(pCircle1));
    CirclePtrPtr ppCircle2(new CirclePtr(pCircle2));
    CirclePtrPtr ppCircle3(new CirclePtr(pCircle3));
    CirclePtrPtr ppCircle4(new CirclePtr(pCircle4));

    CircleList vector_test1;
    vector_test1.push_back(ppCircle1);
    vector_test1.push_back(ppCircle1);
    vector_test1.push_back(ppCircle1);
    vector_test1.push_back(ppCircle1);

    CircleList vector_test2;
    vector_test2.push_back(ppCircle1);
    vector_test2.push_back(ppCircle1);
    vector_test2.push_back(ppCircle1);
    vector_test2.push_back(ppCircle1);

    for(CircleList::iterator itrVecTest1 = vector_test1.begin();
        itrVecTest1 != vector_test1.end(); ++itrVecTest1)
    {
        CirclePtr circle = *(*itrVecTest1);
        int iType = circle->GetArea();
        if(iType ==10)
        {
            circle.reset();
        }
    }

    return 0;
}