我的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中同时设置相同的指针而不迭代它?
答案 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;
}